From 30ba044e2460f43c5306a63beabed2625d5bbc4c Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 25 Nov 2020 21:46:11 +0000 Subject: [PATCH 1/3] Add a benchmark for exhaustive_patterns --- .../.gitignore | 2 + .../Cargo.toml | 5 + .../perf-config.json | 4 + .../src/attr.rs | 78 +++ .../src/data.rs | 84 +++ .../src/expr.rs | 560 ++++++++++++++++++ .../src/generics.rs | 82 +++ .../src/item.rs | 397 +++++++++++++ .../src/lib.rs | 192 ++++++ .../src/mac.rs | 22 + .../src/macros.rs | 61 ++ .../src/op.rs | 73 +++ .../src/ty.rs | 272 +++++++++ .../src/visit.rs | 356 +++++++++++ 14 files changed, 2188 insertions(+) create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/.gitignore create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/Cargo.toml create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/perf-config.json create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/attr.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/data.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/expr.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/generics.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/item.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/lib.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/mac.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/macros.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/op.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/ty.rs create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/src/visit.rs diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/.gitignore b/collector/benchmarks/match-stress-exhaustive_patterns/.gitignore new file mode 100644 index 000000000..a9d37c560 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/Cargo.toml b/collector/benchmarks/match-stress-exhaustive_patterns/Cargo.toml new file mode 100644 index 000000000..9cfceee29 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "syn" +version = "0.0.0" + +[workspace] diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/perf-config.json b/collector/benchmarks/match-stress-exhaustive_patterns/perf-config.json new file mode 100644 index 000000000..e96509725 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/perf-config.json @@ -0,0 +1,4 @@ +{ + "supports_stable": false, + "touch_file": "src/lib.rs" +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/attr.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/attr.rs new file mode 100644 index 000000000..14ed3455e --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/attr.rs @@ -0,0 +1,78 @@ +use super::*; +use delimited::Delimited; + +ast_enum! { + /// Distinguishes between Attributes that decorate items and Attributes that + /// are contained as statements within items. These two cases need to be + /// distinguished for pretty-printing. + pub enum AttrStyle { + /// Attribute of the form `#[...]`. + Outer, + + /// Attribute of the form `#![...]`. + Inner(tokens::Bang), + } +} + +ast_enum_of_structs! { + /// A compile-time attribute item. + /// + /// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]` + pub enum MetaItem { + /// Term meta item. + /// + /// E.g. `test` as in `#[test]` + pub Term(Ident), + + /// List meta item. + /// + /// E.g. `derive(..)` as in `#[derive(..)]` + pub List(MetaItemList { + /// Name of this attribute. + /// + /// E.g. `derive` in `#[derive(..)]` + pub ident: Ident, + + pub paren_token: tokens::Paren, + + /// Arguments to this attribute + /// + /// E.g. `..` in `#[derive(..)]` + pub nested: Delimited, + }), + + /// Name-value meta item. + /// + /// E.g. `feature = "foo"` as in `#[feature = "foo"]` + pub NameValue(MetaNameValue { + /// Name of this attribute. + /// + /// E.g. `feature` in `#[feature = "foo"]` + pub ident: Ident, + + pub eq_token: tokens::Eq, + + /// Arguments to this attribute + /// + /// E.g. `"foo"` in `#[feature = "foo"]` + pub lit: Lit, + }), + } +} + +ast_enum_of_structs! { + /// Possible values inside of compile-time attribute lists. + /// + /// E.g. the '..' in `#[name(..)]`. + pub enum NestedMetaItem { + /// A full `MetaItem`. + /// + /// E.g. `Copy` in `#[derive(Copy)]` would be a `MetaItem::Term(Ident::from("Copy"))`. + pub MetaItem(MetaItem), + + /// A Rust literal. + /// + /// E.g. `"name"` in `#[rename("name")]`. + pub Literal(Lit), + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/data.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/data.rs new file mode 100644 index 000000000..502e65858 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/data.rs @@ -0,0 +1,84 @@ +use super::*; +use delimited::Delimited; + +ast_struct! { + /// An enum variant. + pub struct Variant { + /// Name of the variant. + pub ident: Ident, + + /// Attributes tagged on the variant. + pub attrs: Vec, + + /// Type of variant. + pub data: VariantData, + + /// Explicit discriminant, e.g. `Foo = 1` + pub discriminant: Option, + + pub eq_token: Option, + } +} + +ast_enum! { + /// Data stored within an enum variant or struct. + pub enum VariantData { + /// Struct variant, e.g. `Point { x: f64, y: f64 }`. + Struct(Delimited, tokens::Brace), + + /// Tuple variant, e.g. `Some(T)`. + Tuple(Delimited, tokens::Paren), + + /// Unit variant, e.g. `None`. + Unit, + } +} + +ast_struct! { + /// A field of a struct or enum variant. + pub struct Field { + /// Name of the field, if any. + /// + /// Fields of tuple structs have no names. + pub ident: Option, + + /// Visibility of the field. + pub vis: Visibility, + + /// Attributes tagged on the field. + pub attrs: Vec, + + /// Type of the field. + pub ty: Ty, + + pub colon_token: Option, + } +} + +ast_enum_of_structs! { + /// Visibility level of an item. + pub enum Visibility { + /// Public, i.e. `pub`. + pub Public(VisPublic { + pub pub_token: tokens::Pub, + }), + + /// Crate-visible, i.e. `pub(crate)`. + pub Crate(VisCrate { + pub pub_token: tokens::Pub, + pub paren_token: tokens::Paren, + pub crate_token: tokens::Crate, + }), + + /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`. + pub Restricted(VisRestricted { + pub pub_token: tokens::Pub, + pub paren_token: tokens::Paren, + pub in_token: Option, + pub path: Box, + }), + + /// Inherited, i.e. private. + pub Inherited(VisInherited {}), + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/expr.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/expr.rs new file mode 100644 index 000000000..d0040f52a --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/expr.rs @@ -0,0 +1,560 @@ +use super::*; +use delimited::Delimited; + +ast_struct! { + /// An expression. + pub struct Expr { + /// Type of the expression. + pub node: ExprKind, + + /// Attributes tagged on the expression. + pub attrs: Vec, + } +} + +ast_enum_of_structs! { + pub enum ExprKind { + /// A `box x` expression. + pub Box(ExprBox { + pub expr: Box, + pub box_token: tokens::Box_, + }), + + /// E.g. 'place <- val' or `in place { val }`. + pub InPlace(ExprInPlace { + pub place: Box, + pub kind: InPlaceKind, + pub value: Box, + }), + + /// An array, e.g. `[a, b, c, d]`. + pub Array(ExprArray { + pub exprs: Delimited, + pub bracket_token: tokens::Bracket, + }), + + /// A function call. + pub Call(ExprCall { + pub func: Box, + pub args: Delimited, + pub paren_token: tokens::Paren, + }), + + /// A method call (`x.foo::(a, b, c, d)`) + /// + /// The `Ident` is the identifier for the method name. + /// The vector of `Ty`s are the ascripted type parameters for the method + /// (within the angle brackets). + /// + /// Thus, `x.foo::(a, b, c, d)` is represented as + /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. + pub MethodCall(ExprMethodCall { + pub expr: Box, + pub method: Ident, + pub typarams: Delimited, + pub args: Delimited, + pub paren_token: tokens::Paren, + pub dot_token: tokens::Dot, + pub lt_token: Option, + pub colon2_token: Option, + pub gt_token: Option, + }), + + /// A tuple, e.g. `(a, b, c, d)`. + pub Tup(ExprTup { + pub args: Delimited, + pub paren_token: tokens::Paren, + pub lone_comma: Option, + }), + + /// A binary operation, e.g. `a + b`, `a * b`. + pub Binary(ExprBinary { + pub op: BinOp, + pub left: Box, + pub right: Box, + }), + + /// A unary operation, e.g. `!x`, `*x`. + pub Unary(ExprUnary { + pub op: UnOp, + pub expr: Box, + }), + + /// A literal, e.g. `1`, `"foo"`. + pub Lit(Lit), + + /// A cast, e.g. `foo as f64`. + pub Cast(ExprCast { + pub expr: Box, + pub as_token: tokens::As, + pub ty: Box, + }), + + /// A type ascription, e.g. `foo: f64`. + pub Type(ExprType { + pub expr: Box, + pub colon_token: tokens::Colon, + pub ty: Box, + }), + + /// An `if` block, with an optional else block + /// + /// E.g., `if expr { block } else { expr }` + pub If(ExprIf { + pub cond: Box, + pub if_true: Block, + pub if_false: Option>, + pub if_token: tokens::If, + pub else_token: Option, + }), + + /// An `if let` expression with an optional else block + /// + /// E.g., `if let pat = expr { block } else { expr }` + /// + /// This is desugared to a `match` expression. + pub IfLet(ExprIfLet { + pub pat: Box, + pub expr: Box, + pub if_true: Block, + pub if_false: Option>, + pub if_token: tokens::If, + pub let_token: tokens::Let, + pub eq_token: tokens::Eq, + pub else_token: Option, + }), + + /// A while loop, with an optional label + /// + /// E.g., `'label: while expr { block }` + pub While(ExprWhile { + pub cond: Box, + pub body: Block, + pub label: Option, + pub colon_token: Option, + pub while_token: tokens::While, + }), + + /// A while-let loop, with an optional label. + /// + /// E.g., `'label: while let pat = expr { block }` + /// + /// This is desugared to a combination of `loop` and `match` expressions. + pub WhileLet(ExprWhileLet { + pub pat: Box, + pub expr: Box, + pub body: Block, + pub label: Option, + pub colon_token: Option, + pub while_token: tokens::While, + pub let_token: tokens::Let, + pub eq_token: tokens::Eq, + }), + + /// A for loop, with an optional label. + /// + /// E.g., `'label: for pat in expr { block }` + /// + /// This is desugared to a combination of `loop` and `match` expressions. + pub ForLoop(ExprForLoop { + pub pat: Box, + pub expr: Box, + pub body: Block, + pub label: Option, + pub for_token: tokens::For, + pub colon_token: Option, + pub in_token: tokens::In, + }), + + /// Conditionless loop with an optional label. + /// + /// E.g. `'label: loop { block }` + pub Loop(ExprLoop { + pub body: Block, + pub label: Option, + pub loop_token: tokens::Loop, + pub colon_token: Option, + }), + + /// A `match` block. + pub Match(ExprMatch { + pub match_token: tokens::Match, + pub brace_token: tokens::Brace, + pub expr: Box, + pub arms: Vec, + }), + + /// A closure (for example, `move |a, b, c| a + b + c`) + pub Closure(ExprClosure { + pub capture: CaptureBy, + pub decl: Box, + pub body: Box, + pub or1_token: tokens::Or, + pub or2_token: tokens::Or, + }), + + /// A block (`{ ... }` or `unsafe { ... }`) + pub Block(ExprBlock { + pub unsafety: Unsafety, + pub block: Block, + }), + + /// An assignment (`a = foo()`) + pub Assign(ExprAssign { + pub left: Box, + pub right: Box, + pub eq_token: tokens::Eq, + }), + + /// An assignment with an operator + /// + /// For example, `a += 1`. + pub AssignOp(ExprAssignOp { + pub op: BinOp, + pub left: Box, + pub right: Box, + }), + + /// Access of a named struct field (`obj.foo`) + pub Field(ExprField { + pub expr: Box, + pub field: Ident, + pub dot_token: tokens::Dot, + }), + + /// Access of an unnamed field of a struct or tuple-struct + /// + /// For example, `foo.0`. + pub TupField(ExprTupField { + pub expr: Box, + pub field: Lit, + pub dot_token: tokens::Dot, + }), + + /// An indexing operation (`foo[2]`) + pub Index(ExprIndex { + pub expr: Box, + pub index: Box, + pub bracket_token: tokens::Bracket, + }), + + /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`) + pub Range(ExprRange { + pub from: Option>, + pub to: Option>, + pub limits: RangeLimits, + }), + + /// Variable reference, possibly containing `::` and/or type + /// parameters, e.g. foo::bar::. + /// + /// Optionally "qualified", + /// E.g. ` as SomeTrait>::SomeType`. + pub Path(ExprPath { + pub qself: Option, + pub path: Path, + }), + + /// A referencing operation (`&a` or `&mut a`) + pub AddrOf(ExprAddrOf { + pub and_token: tokens::And, + pub mutbl: Mutability, + pub expr: Box, + }), + + /// A `break`, with an optional label to break, and an optional expression + pub Break(ExprBreak { + pub label: Option, + pub expr: Option>, + pub break_token: tokens::Break, + }), + + /// A `continue`, with an optional label + pub Continue(ExprContinue { + pub label: Option, + pub continue_token: tokens::Continue, + }), + + /// A `return`, with an optional value to be returned + pub Ret(ExprRet { + pub expr: Option>, + pub return_token: tokens::Return, + }), + + /// A macro invocation; pre-expansion + pub Mac(Mac), + + /// A struct literal expression. + /// + /// For example, `Foo {x: 1, y: 2}`, or + /// `Foo {x: 1, .. base}`, where `base` is the `Option`. + pub Struct(ExprStruct { + pub path: Path, + pub fields: Delimited, + pub rest: Option>, + pub dot2_token: Option, + pub brace_token: tokens::Brace, + }), + + /// An array literal constructed from one repeated element. + /// + /// For example, `[1; 5]`. The first expression is the element + /// to be repeated; the second is the number of times to repeat it. + pub Repeat(ExprRepeat { + pub bracket_token: tokens::Bracket, + pub semi_token: tokens::Semi, + pub expr: Box, + pub amt: Box, + }), + + /// No-op: used solely so we can pretty-print faithfully + pub Paren(ExprParen { + pub expr: Box, + pub paren_token: tokens::Paren, + }), + + /// No-op: used solely so we can pretty-print faithfully + /// + /// A `group` represents a `None`-delimited span in the input + /// `TokenStream` which affects the precidence of the resulting + /// expression. They are used for macro hygiene. + pub Group(ExprGroup { + pub expr: Box, + pub group_token: tokens::Group, + }), + + /// `expr?` + pub Try(ExprTry { + pub expr: Box, + pub question_token: tokens::Question, + }), + + /// A catch expression. + /// + /// E.g. `do catch { block }` + pub Catch(ExprCatch { + pub do_token: tokens::Do, + pub catch_token: tokens::Catch, + pub block: Block, + }), + + /// A yield expression. + /// + /// E.g. `yield expr` + pub Yield(ExprYield { + pub yield_token: tokens::Yield, + pub expr: Option>, + }), + } +} + +ast_struct! { + /// A Block (`{ .. }`). + /// + /// E.g. `{ .. }` as in `fn foo() { .. }` + pub struct Block { + pub brace_token: tokens::Brace, + /// Statements in a block + pub stmts: Vec, + } +} + +ast_enum! { + /// A statement, usually ending in a semicolon. + pub enum Stmt { + /// A local (let) binding. + Local(Box), + + /// An item definition. + Item(Box), + + /// Expr without trailing semicolon. + Expr(Box), + + /// Expression with trailing semicolon; + Semi(Box, tokens::Semi), + + /// Macro invocation. + Mac(Box), + } +} + +ast_enum! { + /// How a macro was invoked. + pub enum MacStmtStyle { + /// The macro statement had a trailing semicolon, e.g. `foo! { ... };` + /// `foo!(...);`, `foo![...];` + Semicolon(tokens::Semi), + + /// The macro statement had braces; e.g. foo! { ... } + Braces, + + /// The macro statement had parentheses or brackets and no semicolon; e.g. + /// `foo!(...)`. All of these will end up being converted into macro + /// expressions. + NoBraces, + } +} + +ast_enum_of_structs! { + // Clippy false positive + // https://github.com/Manishearth/rust-clippy/issues/1241 + #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))] + pub enum Pat { + /// Represents a wildcard pattern (`_`) + pub Wild(PatWild { + pub underscore_token: tokens::Underscore, + }), + + /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`), + /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third + /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens + /// during name resolution. + pub Ident(PatIdent { + pub mode: BindingMode, + pub ident: Ident, + pub subpat: Option>, + pub at_token: Option, + }), + + /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`. + /// The `bool` is `true` in the presence of a `..`. + pub Struct(PatStruct { + pub path: Path, + pub fields: Delimited, + pub brace_token: tokens::Brace, + pub dot2_token: Option, + }), + + /// A tuple struct/variant pattern `Variant(x, y, .., z)`. + /// If the `..` pattern fragment is present, then `Option` denotes its position. + /// 0 <= position <= subpats.len() + pub TupleStruct(PatTupleStruct { + pub path: Path, + pub pat: PatTuple, + }), + + /// A possibly qualified path pattern. + /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants + /// or associated constants. Quailfied path patterns `::B::C`/`::B::C` can + /// only legally refer to associated constants. + pub Path(PatPath { + pub qself: Option, + pub path: Path, + }), + + /// A tuple pattern `(a, b)`. + /// If the `..` pattern fragment is present, then `Option` denotes its position. + /// 0 <= position <= subpats.len() + pub Tuple(PatTuple { + pub pats: Delimited, + pub dots_pos: Option, + pub paren_token: tokens::Paren, + pub dot2_token: Option, + pub comma_token: Option, + }), + /// A `box` pattern + pub Box(PatBox { + pub pat: Box, + pub box_token: tokens::Box_, + }), + /// A reference pattern, e.g. `&mut (a, b)` + pub Ref(PatRef { + pub pat: Box, + pub mutbl: Mutability, + pub and_token: tokens::And, + }), + /// A literal + pub Lit(PatLit { + pub expr: Box, + }), + /// A range pattern, e.g. `1...2` + pub Range(PatRange { + pub lo: Box, + pub hi: Box, + pub limits: RangeLimits, + }), + /// `[a, b, i.., y, z]` is represented as: + pub Slice(PatSlice { + pub front: Delimited, + pub middle: Option>, + pub back: Delimited, + pub dot2_token: Option, + pub comma_token: Option, + pub bracket_token: tokens::Bracket, + }), + /// A macro pattern; pre-expansion + pub Mac(Mac), + } +} + +ast_struct! { + /// An arm of a 'match'. + /// + /// E.g. `0...10 => { println!("match!") }` as in + /// + /// ```rust,ignore + /// match n { + /// 0...10 => { println!("match!") }, + /// // .. + /// } + /// ``` + pub struct Arm { + pub attrs: Vec, + pub pats: Delimited, + pub if_token: Option, + pub guard: Option>, + pub rocket_token: tokens::Rocket, + pub body: Box, + pub comma: Option, + } +} + +ast_enum! { + /// A capture clause + pub enum CaptureBy { + Value(tokens::Move), + Ref, + } +} + +ast_enum! { + /// Limit types of a range (inclusive or exclusive) + pub enum RangeLimits { + /// Inclusive at the beginning, exclusive at the end + HalfOpen(tokens::Dot2), + /// Inclusive at the beginning and end + Closed(tokens::Dot3), + } +} + +ast_struct! { + /// A single field in a struct pattern + /// + /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` + /// are treated the same as `x: x, y: ref y, z: ref mut z`, + /// except `is_shorthand` is true + pub struct FieldPat { + /// The identifier for the field + pub ident: Ident, + /// The pattern the field is destructured to + pub pat: Box, + pub is_shorthand: bool, + pub colon_token: Option, + pub attrs: Vec, + } +} + +ast_enum! { + pub enum BindingMode { + ByRef(tokens::Ref, Mutability), + ByValue(Mutability), + } +} + +ast_enum! { + pub enum InPlaceKind { + Arrow(tokens::LArrow), + In(tokens::In), + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/generics.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/generics.rs new file mode 100644 index 000000000..072fabd63 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/generics.rs @@ -0,0 +1,82 @@ +use super::*; +use delimited::Delimited; + +ast_struct! { + /// Represents lifetimes and type parameters attached to a declaration + /// of a function, enum, trait, etc. + pub struct Generics { + pub lt_token: Option, + pub gt_token: Option, + pub lifetimes: Delimited, + pub ty_params: Delimited, + pub where_clause: WhereClause, + } +} + +ast_struct! { + /// A set of bound lifetimes, e.g. `for<'a, 'b, 'c>` + pub struct BoundLifetimes { + pub for_token: tokens::For, + pub lt_token: tokens::Lt, + pub lifetimes: Delimited, + pub gt_token: tokens::Gt, + } +} + +ast_enum! { + /// The AST represents all type param bounds as types. + /// `typeck::collect::compute_bounds` matches these against + /// the "special" built-in traits (see `middle::lang_items`) and + /// detects Copy, Send and Sync. + pub enum TyParamBound { + Trait(PolyTraitRef, TraitBoundModifier), + Region(Lifetime), + } +} + +ast_enum! { + /// A modifier on a bound, currently this is only used for `?Sized`, where the + /// modifier is `Maybe`. Negative bounds should also be handled here. + pub enum TraitBoundModifier { + None, + Maybe(tokens::Question), + } +} + +ast_struct! { + /// A `where` clause in a definition + pub struct WhereClause { + pub where_token: Option, + pub predicates: Delimited, + } +} + +ast_enum_of_structs! { + /// A single predicate in a `where` clause + pub enum WherePredicate { + /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c` + pub BoundPredicate(WhereBoundPredicate { + /// Any lifetimes from a `for` binding + pub bound_lifetimes: Option, + /// The type being bounded + pub bounded_ty: Ty, + pub colon_token: tokens::Colon, + /// Trait and lifetime bounds (`Clone+Send+'static`) + pub bounds: Delimited, + }), + + /// A lifetime predicate, e.g. `'a: 'b+'c` + pub RegionPredicate(WhereRegionPredicate { + pub lifetime: Lifetime, + pub colon_token: Option, + pub bounds: Delimited, + }), + + /// An equality predicate (unsupported) + pub EqPredicate(WhereEqPredicate { + pub lhs_ty: Ty, + pub eq_token: tokens::Eq, + pub rhs_ty: Ty, + }), + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/item.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/item.rs new file mode 100644 index 000000000..775372670 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/item.rs @@ -0,0 +1,397 @@ +use super::*; +use delimited::Delimited; + +ast_struct! { + /// Things that can appear directly inside of a module. + pub struct Item { + pub attrs: Vec, + pub node: ItemKind, + } +} + +ast_enum_of_structs! { + pub enum ItemKind { + /// An `extern crate` item, with optional original crate name. + /// + /// E.g. `extern crate foo` or `extern crate foo_bar as foo` + pub ExternCrate(ItemExternCrate { + pub vis: Visibility, + pub extern_token: tokens::Extern, + pub crate_token: tokens::Crate, + pub ident: Ident, + pub rename: Option<(tokens::As, Ident)>, + pub semi_token: tokens::Semi, + }), + /// A use declaration (`use` or `pub use`) item. + /// + /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;` + pub Use(ItemUse { + pub vis: Visibility, + pub use_token: tokens::Use, + pub path: Box, + pub semi_token: tokens::Semi, + }), + /// A static item (`static` or `pub static`). + /// + /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";` + pub Static(ItemStatic { + pub vis: Visibility, + pub static_token: tokens::Static, + pub mutbl: Mutability, + pub ident: Ident, + pub colon_token: tokens::Colon, + pub ty: Box, + pub eq_token: tokens::Eq, + pub expr: Box, + pub semi_token: tokens::Semi, + }), + /// A constant item (`const` or `pub const`). + /// + /// E.g. `const FOO: i32 = 42;` + pub Const(ItemConst { + pub vis: Visibility, + pub const_token: tokens::Const, + pub ident: Ident, + pub colon_token: tokens::Colon, + pub ty: Box, + pub eq_token: tokens::Eq, + pub expr: Box, + pub semi_token: tokens::Semi, + }), + /// A function declaration (`fn` or `pub fn`). + /// + /// E.g. `fn foo(bar: usize) -> usize { .. }` + pub Fn(ItemFn { + pub vis: Visibility, + pub constness: Constness, + pub unsafety: Unsafety, + pub abi: Option, + pub decl: Box, + pub ident: Ident, + pub block: Box, + }), + /// A module declaration (`mod` or `pub mod`). + /// + /// E.g. `mod foo;` or `mod foo { .. }` + pub Mod(ItemMod { + pub vis: Visibility, + pub mod_token: tokens::Mod, + pub ident: Ident, + pub content: Option<(tokens::Brace, Vec)>, + pub semi: Option, + }), + /// An external module (`extern` or `pub extern`). + /// + /// E.g. `extern {}` or `extern "C" {}` + pub ForeignMod(ItemForeignMod { + pub abi: Abi, + pub brace_token: tokens::Brace, + pub items: Vec, + }), + /// A type alias (`type` or `pub type`). + /// + /// E.g. `type Foo = Bar;` + pub Ty(ItemTy { + pub vis: Visibility, + pub type_token: tokens::Type, + pub ident: Ident, + pub generics: Generics, + pub eq_token: tokens::Eq, + pub ty: Box, + pub semi_token: tokens::Semi, + }), + /// An enum definition (`enum` or `pub enum`). + /// + /// E.g. `enum Foo { C, D }` + pub Enum(ItemEnum { + pub vis: Visibility, + pub enum_token: tokens::Enum, + pub ident: Ident, + pub generics: Generics, + pub brace_token: tokens::Brace, + pub variants: Delimited, + }), + /// A struct definition (`struct` or `pub struct`). + /// + /// E.g. `struct Foo { x: A }` + pub Struct(ItemStruct { + pub vis: Visibility, + pub struct_token: tokens::Struct, + pub ident: Ident, + pub generics: Generics, + pub data: VariantData, + pub semi_token: Option, + }), + /// A union definition (`union` or `pub union`). + /// + /// E.g. `union Foo { x: A, y: B }` + pub Union(ItemUnion { + pub vis: Visibility, + pub union_token: tokens::Union, + pub ident: Ident, + pub generics: Generics, + pub data: VariantData, + }), + /// A Trait declaration (`trait` or `pub trait`). + /// + /// E.g. `trait Foo { .. }` or `trait Foo { .. }` + pub Trait(ItemTrait { + pub vis: Visibility, + pub unsafety: Unsafety, + pub trait_token: tokens::Trait, + pub ident: Ident, + pub generics: Generics, + pub colon_token: Option, + pub supertraits: Delimited, + pub brace_token: tokens::Brace, + pub items: Vec, + }), + /// Default trait implementation. + /// + /// E.g. `impl Trait for .. {}` or `impl Trait for .. {}` + pub DefaultImpl(ItemDefaultImpl { + pub unsafety: Unsafety, + pub impl_token: tokens::Impl, + pub path: Path, + pub for_token: tokens::For, + pub dot2_token: tokens::Dot2, + pub brace_token: tokens::Brace, + }), + /// An implementation. + /// + /// E.g. `impl Foo { .. }` or `impl Trait for Foo { .. }` + pub Impl(ItemImpl { + pub defaultness: Defaultness, + pub unsafety: Unsafety, + pub impl_token: tokens::Impl, + pub generics: Generics, + /// Trait this impl implements. + pub trait_: Option<(ImplPolarity, Path, tokens::For)>, + /// The Self type of the impl. + pub self_ty: Box, + pub brace_token: tokens::Brace, + pub items: Vec, + }), + /// A macro invocation (which includes macro definition). + /// + /// E.g. `macro_rules! foo { .. }` or `foo!(..)` + pub Mac(Mac), + } +} + +ast_enum_of_structs! { + pub enum ViewPath { + /// `foo::bar::baz as quux` + /// + /// or just + /// + /// `foo::bar::baz` (with `as baz` implicitly on the right) + pub Simple(PathSimple { + pub path: Path, + pub as_token: Option, + pub rename: Option, + }), + + /// `foo::bar::*` + pub Glob(PathGlob { + pub path: Path, + pub colon2_token: Option, + pub star_token: tokens::Star, + }), + + /// `foo::bar::{a, b, c}` + pub List(PathList { + pub path: Path, + pub colon2_token: tokens::Colon2, + pub brace_token: tokens::Brace, + pub items: Delimited, + }), + } +} + +ast_struct! { + pub struct PathListItem { + pub name: Ident, + /// renamed in list, e.g. `use foo::{bar as baz};` + pub rename: Option, + pub as_token: Option, + } +} + +ast_enum! { + pub enum Constness { + Const(tokens::Const), + NotConst, + } +} + +ast_enum! { + pub enum Defaultness { + Default(tokens::Default_), + Final, + } +} + +ast_struct! { + pub struct ForeignItem { + pub ident: Ident, + pub attrs: Vec, + pub node: ForeignItemKind, + pub vis: Visibility, + pub semi_token: tokens::Semi, + } +} + +ast_enum_of_structs! { + /// An item within an `extern` block + pub enum ForeignItemKind { + /// A foreign function + pub Fn(ForeignItemFn { + pub decl: Box, + }), + /// A foreign static item (`static ext: u8`) + pub Static(ForeignItemStatic { + pub static_token: tokens::Static, + pub ty: Box, + pub colon_token: tokens::Colon, + pub mutbl: Mutability, + }), + } +} + +ast_struct! { + /// Represents an item declaration within a trait declaration, + /// possibly including a default implementation. A trait item is + /// either required (meaning it doesn't have an implementation, just a + /// signature) or provided (meaning it has a default implementation). + pub struct TraitItem { + pub attrs: Vec, + pub node: TraitItemKind, + } +} + +ast_enum_of_structs! { + pub enum TraitItemKind { + pub Const(TraitItemConst { + pub const_token: tokens::Const, + pub ident: Ident, + pub colon_token: tokens::Colon, + pub ty: Ty, + pub default: Option<(tokens::Eq, Expr)>, + pub semi_token: tokens::Semi, + }), + pub Method(TraitItemMethod { + pub sig: MethodSig, + pub default: Option, + pub semi_token: Option, + }), + pub Type(TraitItemType { + pub type_token: tokens::Type, + pub ident: Ident, + pub colon_token: Option, + pub bounds: Delimited, + pub default: Option<(tokens::Eq, Ty)>, + pub semi_token: tokens::Semi, + }), + pub Macro(Mac), + } +} + +ast_enum! { + pub enum ImplPolarity { + /// `impl Trait for Type` + Positive, + /// `impl !Trait for Type` + Negative(tokens::Bang), + } +} + +ast_struct! { + pub struct ImplItem { + pub attrs: Vec, + pub node: ImplItemKind, + } +} + +ast_enum_of_structs! { + pub enum ImplItemKind { + pub Const(ImplItemConst { + pub vis: Visibility, + pub defaultness: Defaultness, + pub const_token: tokens::Const, + pub ident: Ident, + pub colon_token: tokens::Colon, + pub ty: Ty, + pub eq_token: tokens::Eq, + pub expr: Expr, + pub semi_token: tokens::Semi, + }), + pub Method(ImplItemMethod { + pub vis: Visibility, + pub defaultness: Defaultness, + pub sig: MethodSig, + pub block: Block, + }), + pub Type(ImplItemType { + pub vis: Visibility, + pub defaultness: Defaultness, + pub type_token: tokens::Type, + pub ident: Ident, + pub eq_token: tokens::Eq, + pub ty: Ty, + pub semi_token: tokens::Semi, + }), + pub Macro(Mac), + } +} + +ast_struct! { + /// Represents a method's signature in a trait declaration, + /// or in an implementation. + pub struct MethodSig { + pub constness: Constness, + pub unsafety: Unsafety, + pub abi: Option, + pub ident: Ident, + pub decl: FnDecl, + } +} + +ast_struct! { + /// Header (not the body) of a function declaration. + /// + /// E.g. `fn foo(bar: baz)` + pub struct FnDecl { + pub fn_token: tokens::Fn_, + pub paren_token: tokens::Paren, + pub inputs: Delimited, + pub output: FunctionRetTy, + pub generics: Generics, + pub variadic: bool, + pub dot_tokens: Option, + } +} + +ast_enum_of_structs! { + /// An argument in a function header. + /// + /// E.g. `bar: usize` as in `fn foo(bar: usize)` + pub enum FnArg { + pub SelfRef(ArgSelfRef { + pub and_token: tokens::And, + pub self_token: tokens::Self_, + pub lifetime: Option, + pub mutbl: Mutability, + }), + pub SelfValue(ArgSelf { + pub mutbl: Mutability, + pub self_token: tokens::Self_, + }), + pub Captured(ArgCaptured { + pub pat: Pat, + pub colon_token: tokens::Colon, + pub ty: Ty, + }), + pub Ignored(Ty), + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/lib.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/lib.rs new file mode 100644 index 000000000..ac213e841 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/lib.rs @@ -0,0 +1,192 @@ +//! This was extracted from the `syn` benchmark to provide a realistic benchmark for match +//! checking. This mostly defines a ton of structs and enums, and the matches come from the +//! `PartialEq` derives. +#![feature(exhaustive_patterns)] + +#[macro_use] +mod macros; + +mod delimited { + #[derive(PartialEq)] + pub struct Delimited { + inner: Box, + } +} + +mod span { + pub struct Span(u32, u32); + + impl PartialEq for Span { + fn eq(&self, _other: &Span) -> bool { + true + } + } +} + +mod tokens { + use super::span::Span; + + macro_rules! tokens { + ( $($token:ident,)*) => ( + $(token! { $token })* + ) + } + + macro_rules! token { + ($name:ident) => { + #[derive(PartialEq)] + pub struct $name(Span, Span); + }; + } + + tokens! { + Add, + AddEq, + And, + AndAnd, + AndEq, + As, + At, + Bang, + Box_, + Brace, + Bracket, + Break, + CapSelf, + Caret, + CaretEq, + Catch, + Colon, + Colon2, + Comma, + Const, + Continue, + Crate, + Default_, + Div, + DivEq, + Do, + Dot, + Dot2, + Dot3, + Else, + Enum, + Eq, + EqEq, + Extern, + Fn_, + For, + Ge, + Group, + Gt, + If, + Impl, + In, + LArrow, + Le, + Let, + Loop, + Lt, + Match, + Mod, + Move, + MulEq, + Mut, + Ne, + Or, + OrEq, + OrOr, + Paren, + Pound, + Pub, + Question, + RArrow, + Ref, + Rem, + RemEq, + Return, + Rocket, + Self_, + Semi, + Shl, + ShlEq, + Shr, + ShrEq, + Star, + Static, + Struct, + Sub, + SubEq, + Super, + Trait, + Type, + Underscore, + Union, + Unsafe, + Use, + Where, + While, + Yield, + } +} + +mod ident { + use Span; + + pub struct Ident { + pub span0: Span, + pub span1: Span, + pub span2: Span, + pub span3: Span, + pub span4: Span, + pub span5: Span, + pub span6: Span, + pub span7: Span, + } + + impl PartialEq for Ident { + fn eq(&self, _other: &Ident) -> bool { + todo!() + } + } +} + +mod lifetime { + use Ident; + + #[derive(PartialEq)] + pub struct Lifetime { + pub ident: Ident, + } +} + +mod lit { + use Ident; + + #[derive(PartialEq)] + pub struct Lit { + pub ident: Ident, + } +} + +mod attr; +mod data; +mod expr; +mod generics; +mod item; +mod mac; +mod op; +mod ty; +pub mod visit; +pub use attr::*; +pub use data::*; +pub use expr::*; +pub use generics::*; +pub use ident::*; +pub use item::*; +pub use lifetime::*; +pub use lit::*; +pub use mac::*; +pub use op::*; +pub use span::Span; +pub use ty::*; diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/mac.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/mac.rs new file mode 100644 index 000000000..bab52c6a5 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/mac.rs @@ -0,0 +1,22 @@ +use super::*; + +ast_struct! { + /// Represents a macro invocation. The Path indicates which macro + /// is being invoked, and the vector of token-trees contains the source + /// of the macro invocation. + pub struct Mac { + pub path: Path, + pub bang_token: tokens::Bang, + /// The `example` in `macro_rules! example { ... }`. + pub ident: Option, + pub tokens: Vec, + } +} + +pub struct TokenTree; + +impl PartialEq for TokenTree { + fn eq(&self, _other: &TokenTree) -> bool { + todo!() + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/macros.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/macros.rs new file mode 100644 index 000000000..f4536500e --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/macros.rs @@ -0,0 +1,61 @@ +macro_rules! ast_struct { + ( + $(#[$attr:meta])* + pub struct $name:ident $($rest:tt)* + ) => { + $(#[$attr])* + #[derive(PartialEq)] + pub struct $name $($rest)* + }; +} + +macro_rules! ast_enum { + ( + $(#[$enum_attr:meta])* + pub enum $name:ident { $($variants:tt)* } + ) => ( + $(#[$enum_attr])* + #[derive(PartialEq)] + pub enum $name { + $($variants)* + } + ) +} + +macro_rules! ast_enum_of_structs { + ( + $(#[$enum_attr:meta])* + pub enum $name:ident { + $( + $(#[$variant_attr:meta])* + pub $variant:ident($member:ident $($rest:tt)*), + )* + } + ) => ( + ast_enum! { + $(#[$enum_attr])* + pub enum $name { + $( + $(#[$variant_attr])* + $variant($member), + )* + } + } + + $( + maybe_ast_struct! { + $(#[$variant_attr])* + pub struct $member $($rest)* + } + )* + ) +} + +macro_rules! maybe_ast_struct { + ( + $(#[$attr:meta])* + pub struct $name:ident + ) => (); + + ($($rest:tt)*) => (ast_struct! { $($rest)* }); +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/op.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/op.rs new file mode 100644 index 000000000..8e3f74f70 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/op.rs @@ -0,0 +1,73 @@ +use tokens; + +ast_enum! { + pub enum BinOp { + /// The `+` operator (addition) + Add(tokens::Add), + /// The `-` operator (subtraction) + Sub(tokens::Sub), + /// The `*` operator (multiplication) + Mul(tokens::Star), + /// The `/` operator (division) + Div(tokens::Div), + /// The `%` operator (modulus) + Rem(tokens::Rem), + /// The `&&` operator (logical and) + And(tokens::AndAnd), + /// The `||` operator (logical or) + Or(tokens::OrOr), + /// The `^` operator (bitwise xor) + BitXor(tokens::Caret), + /// The `&` operator (bitwise and) + BitAnd(tokens::And), + /// The `|` operator (bitwise or) + BitOr(tokens::Or), + /// The `<<` operator (shift left) + Shl(tokens::Shl), + /// The `>>` operator (shift right) + Shr(tokens::Shr), + /// The `==` operator (equality) + Eq(tokens::EqEq), + /// The `<` operator (less than) + Lt(tokens::Lt), + /// The `<=` operator (less than or equal to) + Le(tokens::Le), + /// The `!=` operator (not equal to) + Ne(tokens::Ne), + /// The `>=` operator (greater than or equal to) + Ge(tokens::Ge), + /// The `>` operator (greater than) + Gt(tokens::Gt), + /// The `+=` operator + AddEq(tokens::AddEq), + /// The `-=` operator + SubEq(tokens::SubEq), + /// The `*=` operator + MulEq(tokens::MulEq), + /// The `/=` operator + DivEq(tokens::DivEq), + /// The `%=` operator + RemEq(tokens::RemEq), + /// The `^=` operator + BitXorEq(tokens::CaretEq), + /// The `&=` operator + BitAndEq(tokens::AndEq), + /// The `|=` operator + BitOrEq(tokens::OrEq), + /// The `<<=` operator + ShlEq(tokens::ShlEq), + /// The `>>=` operator + ShrEq(tokens::ShrEq), + } +} + +ast_enum! { + pub enum UnOp { + /// The `*` operator for dereferencing + Deref(tokens::Star), + /// The `!` operator for logical inversion + Not(tokens::Bang), + /// The `-` operator for negation + Neg(tokens::Sub), + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/ty.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/ty.rs new file mode 100644 index 000000000..f5ba8503e --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/ty.rs @@ -0,0 +1,272 @@ +use super::*; +use delimited::Delimited; + +ast_enum_of_structs! { + /// The different kinds of types recognized by the compiler + pub enum Ty { + /// A variable-length array (`[T]`) + pub Slice(TySlice { + pub ty: Box, + pub bracket_token: tokens::Bracket, + }), + /// A fixed length array (`[T; n]`) + pub Array(TyArray { + pub bracket_token: tokens::Bracket, + pub ty: Box, + pub semi_token: tokens::Semi, + pub amt0: Expr, + pub amt1: Expr, + }), + /// A raw pointer (`*const T` or `*mut T`) + pub Ptr(TyPtr { + pub star_token: tokens::Star, + pub const_token: Option, + pub ty: Box, + }), + /// A reference (`&'a T` or `&'a mut T`) + pub Rptr(TyRptr { + pub and_token: tokens::And, + pub lifetime: Option, + pub ty: Box, + }), + /// A bare function (e.g. `fn(usize) -> bool`) + pub BareFn(TyBareFn { + pub ty: Box, + }), + /// The never type (`!`) + pub Never(TyNever { + pub bang_token: tokens::Bang, + }), + /// A tuple (`(A, B, C, D, ...)`) + pub Tup(TyTup { + pub paren_token: tokens::Paren, + pub tys: Delimited, + pub lone_comma: Option, + }), + /// A path (`module::module::...::Type`), optionally + /// "qualified", e.g. ` as SomeTrait>::SomeType`. + /// + /// Type parameters are stored in the Path itself + pub Path(TyPath { + pub qself: Option, + pub path: Path, + }), + /// A trait object type `Bound1 + Bound2 + Bound3` + /// where `Bound` is a trait or a lifetime. + pub TraitObject(TyTraitObject { + pub bounds: Delimited, + }), + /// An `impl Bound1 + Bound2 + Bound3` type + /// where `Bound` is a trait or a lifetime. + pub ImplTrait(TyImplTrait { + pub impl_token: tokens::Impl, + pub bounds: Delimited, + }), + /// No-op; kept solely so that we can pretty-print faithfully + pub Paren(TyParen { + pub paren_token: tokens::Paren, + pub ty: Box, + }), + /// No-op: kept solely so that we can pretty-print faithfully + pub Group(TyGroup { + pub group_token: tokens::Group, + pub ty: Box, + }), + /// TyKind::Infer means the type should be inferred instead of it having been + /// specified. This can appear anywhere in a type. + pub Infer(TyInfer { + pub underscore_token: tokens::Underscore + }), + /// A macro in the type position. + pub Mac(Mac), + } +} + +ast_enum! { + pub enum Mutability { + Mutable(tokens::Mut), + Immutable, + } +} + +ast_struct! { + /// A "Path" is essentially Rust's notion of a name. + /// + /// It's represented as a sequence of identifiers, + /// along with a bunch of supporting information. + /// + /// E.g. `std::cmp::PartialEq` + pub struct Path { + /// A `::foo` path, is relative to the crate root rather than current + /// module (like paths in an import). + pub leading_colon: Option, + /// The segments in the path: the things separated by `::`. + pub segments: Delimited, + } +} + +ast_struct! { + /// A segment of a path: an identifier, an optional lifetime, and a set of types. + /// + /// E.g. `std`, `String` or `Box` + pub struct PathSegment { + /// The identifier portion of this path segment. + pub ident: Ident, + /// Type/lifetime parameters attached to this path. They come in + /// two flavors: `Path` and `Path(A,B) -> C`. Note that + /// this is more than just simple syntactic sugar; the use of + /// parens affects the region binding rules, so we preserve the + /// distinction. + pub parameters: PathParameters, + } +} + +ast_enum! { + /// Parameters of a path segment. + /// + /// E.g. `` as in `Foo` or `(A, B)` as in `Foo(A, B)` + pub enum PathParameters { + None, + /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>` + AngleBracketed(AngleBracketedParameterData), + /// The `(A, B)` and `C` in `Foo(A, B) -> C` + Parenthesized(ParenthesizedParameterData), + } +} + +ast_struct! { + /// A path like `Foo<'a, T>` + pub struct AngleBracketedParameterData { + pub turbofish: Option, + pub lt_token: tokens::Lt, + /// The lifetime parameters for this path segment. + pub lifetimes: Delimited, + /// The type parameters for this path segment, if present. + pub types: Delimited, + /// Bindings (equality constraints) on associated types, if present. + /// + /// E.g., `Foo`. + pub bindings: Delimited, + pub gt_token: tokens::Gt, + } +} + +ast_struct! { + /// Bind a type to an associated type: `A=Foo`. + pub struct TypeBinding { + pub ident: Ident, + pub eq_token: tokens::Eq, + pub ty: Ty, + } +} + +ast_struct! { + /// A path like `Foo(A,B) -> C` + pub struct ParenthesizedParameterData { + pub paren_token: tokens::Paren, + /// `(A, B)` + pub inputs: Delimited, + /// `C` + pub output: FunctionRetTy, + } +} + +ast_struct! { + pub struct PolyTraitRef { + /// The `for<'a>` in `for<'a> Foo<&'a T>` + pub bound_lifetimes: Option, + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` + pub trait_ref: Path, + } +} + +ast_struct! { + /// The explicit Self type in a "qualified path". The actual + /// path, including the trait and the associated item, is stored + /// separately. `position` represents the index of the associated + /// item qualified with this Self type. + /// + /// ```rust,ignore + /// as a::b::Trait>::AssociatedItem + /// ^~~~~ ~~~~~~~~~~~~~~^ + /// ty position = 3 + /// + /// >::AssociatedItem + /// ^~~~~ ^ + /// ty position = 0 + /// ``` + pub struct QSelf { + pub lt_token: tokens::Lt, + pub ty: Box, + pub position: usize, + pub as_token: Option, + pub gt_token: tokens::Gt, + } +} + +ast_struct! { + pub struct BareFnTy { + pub lifetimes: Option, + pub unsafety: Unsafety, + pub abi: Option, + pub fn_token: tokens::Fn_, + pub paren_token: tokens::Paren, + pub inputs: Delimited, + pub variadic: Option, + pub output: FunctionRetTy, + } +} + +ast_enum! { + pub enum Unsafety { + Unsafe(tokens::Unsafe), + Normal, + } +} + +ast_struct! { + pub struct Abi { + pub extern_token: tokens::Extern, + pub kind: AbiKind, + } +} + +ast_enum! { + pub enum AbiKind { + Named(Lit), + Default, + } +} + +ast_struct! { + /// An argument in a function type. + /// + /// E.g. `bar: usize` as in `fn foo(bar: usize)` + pub struct BareFnArg { + pub name: Option<(BareFnArgName, tokens::Colon)>, + pub ty: Ty, + } +} + +ast_enum! { + /// Names of arguments in the `BareFnArg` structure + pub enum BareFnArgName { + /// Argument with the provided name + Named(Ident), + /// Argument matched with `_` + Wild(tokens::Underscore), + } +} + +ast_enum! { + pub enum FunctionRetTy { + /// Return type is not specified. + /// + /// Functions default to `()` and + /// closures default to inference. Span points to where return + /// type would be inserted. + Default, + /// Everything else + Ty(Ty, tokens::RArrow), + } +} diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/src/visit.rs b/collector/benchmarks/match-stress-exhaustive_patterns/src/visit.rs new file mode 100644 index 000000000..1b79695b5 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/src/visit.rs @@ -0,0 +1,356 @@ +use *; + +pub fn visit_abi_kind(_visitor: &mut V, _i: &AbiKind) { + use AbiKind::*; + match *_i { + Named(ref _binding_0) => {} + Default => {} + } +} +pub fn visit_attr_style(_visitor: &mut V, _i: &AttrStyle) { + use AttrStyle::*; + match *_i { + Outer => {} + Inner(ref _binding_0) => {} + } +} +pub fn visit_bare_fn_arg_name(_visitor: &mut V, _i: &BareFnArgName) { + use BareFnArgName::*; + match *_i { + Named(ref _binding_0) => {} + Wild(ref _binding_0) => {} + } +} +pub fn visit_bin_op(_visitor: &mut V, _i: &BinOp) { + use BinOp::*; + match *_i { + Add(ref _binding_0) => {} + Sub(ref _binding_0) => {} + Mul(ref _binding_0) => {} + Div(ref _binding_0) => {} + Rem(ref _binding_0) => {} + And(ref _binding_0) => {} + Or(ref _binding_0) => {} + BitXor(ref _binding_0) => {} + BitAnd(ref _binding_0) => {} + BitOr(ref _binding_0) => {} + Shl(ref _binding_0) => {} + Shr(ref _binding_0) => {} + Eq(ref _binding_0) => {} + Lt(ref _binding_0) => {} + Le(ref _binding_0) => {} + Ne(ref _binding_0) => {} + Ge(ref _binding_0) => {} + Gt(ref _binding_0) => {} + AddEq(ref _binding_0) => {} + SubEq(ref _binding_0) => {} + MulEq(ref _binding_0) => {} + DivEq(ref _binding_0) => {} + RemEq(ref _binding_0) => {} + BitXorEq(ref _binding_0) => {} + BitAndEq(ref _binding_0) => {} + BitOrEq(ref _binding_0) => {} + ShlEq(ref _binding_0) => {} + ShrEq(ref _binding_0) => {} + } +} +pub fn visit_binding_mode(_visitor: &mut V, _i: &BindingMode) { + use BindingMode::*; + match *_i { + ByRef(ref _binding_0, ref _binding_1) => {} + ByValue(ref _binding_0) => {} + } +} +pub fn visit_capture_by(_visitor: &mut V, _i: &CaptureBy) { + use CaptureBy::*; + match *_i { + Value(ref _binding_0) => {} + Ref => {} + } +} +pub fn visit_constness(_visitor: &mut V, _i: &Constness) { + use Constness::*; + match *_i { + Const(ref _binding_0) => {} + NotConst => {} + } +} +pub fn visit_defaultness(_visitor: &mut V, _i: &Defaultness) { + use Defaultness::*; + match *_i { + Default(ref _binding_0) => {} + Final => {} + } +} +pub fn visit_expr_kind(_visitor: &mut V, _i: &ExprKind) { + use ExprKind::*; + match *_i { + Box(ref _binding_0) => {} + InPlace(ref _binding_0) => {} + Array(ref _binding_0) => {} + Call(ref _binding_0) => {} + MethodCall(ref _binding_0) => {} + Tup(ref _binding_0) => {} + Binary(ref _binding_0) => {} + Unary(ref _binding_0) => {} + Lit(ref _binding_0) => {} + Cast(ref _binding_0) => {} + Type(ref _binding_0) => {} + If(ref _binding_0) => {} + IfLet(ref _binding_0) => {} + While(ref _binding_0) => {} + WhileLet(ref _binding_0) => {} + ForLoop(ref _binding_0) => {} + Loop(ref _binding_0) => {} + Match(ref _binding_0) => {} + Closure(ref _binding_0) => {} + Block(ref _binding_0) => {} + Assign(ref _binding_0) => {} + AssignOp(ref _binding_0) => {} + Field(ref _binding_0) => {} + TupField(ref _binding_0) => {} + Index(ref _binding_0) => {} + Range(ref _binding_0) => {} + Path(ref _binding_0) => {} + AddrOf(ref _binding_0) => {} + Break(ref _binding_0) => {} + Continue(ref _binding_0) => {} + Ret(ref _binding_0) => {} + Mac(ref _binding_0) => {} + Struct(ref _binding_0) => {} + Repeat(ref _binding_0) => {} + Paren(ref _binding_0) => {} + Group(ref _binding_0) => {} + Try(ref _binding_0) => {} + Catch(ref _binding_0) => {} + Yield(ref _binding_0) => {} + } +} +pub fn visit_fn_arg(_visitor: &mut V, _i: &FnArg) { + use FnArg::*; + match *_i { + SelfRef(ref _binding_0) => {} + SelfValue(ref _binding_0) => {} + Captured(ref _binding_0) => {} + Ignored(ref _binding_0) => {} + } +} +pub fn visit_foreign_item_kind(_visitor: &mut V, _i: &ForeignItemKind) { + use ForeignItemKind::*; + match *_i { + Fn(ref _binding_0) => {} + Static(ref _binding_0) => {} + } +} +pub fn visit_function_ret_ty(_visitor: &mut V, _i: &FunctionRetTy) { + use FunctionRetTy::*; + match *_i { + Default => {} + Ty(ref _binding_0, ref _binding_1) => {} + } +} +pub fn visit_impl_item_kind(_visitor: &mut V, _i: &ImplItemKind) { + use ImplItemKind::*; + match *_i { + Const(ref _binding_0) => {} + Method(ref _binding_0) => {} + Type(ref _binding_0) => {} + Macro(ref _binding_0) => {} + } +} +pub fn visit_impl_polarity(_visitor: &mut V, _i: &ImplPolarity) { + use ImplPolarity::*; + match *_i { + Positive => {} + Negative(ref _binding_0) => {} + } +} +pub fn visit_in_place_kind(_visitor: &mut V, _i: &InPlaceKind) { + use InPlaceKind::*; + match *_i { + Arrow(ref _binding_0) => {} + In(ref _binding_0) => {} + } +} +pub fn visit_item_kind(_visitor: &mut V, _i: &ItemKind) { + use ItemKind::*; + match *_i { + ExternCrate(ref _binding_0) => {} + Use(ref _binding_0) => {} + Static(ref _binding_0) => {} + Const(ref _binding_0) => {} + Fn(ref _binding_0) => {} + Mod(ref _binding_0) => {} + ForeignMod(ref _binding_0) => {} + Ty(ref _binding_0) => {} + Enum(ref _binding_0) => {} + Struct(ref _binding_0) => {} + Union(ref _binding_0) => {} + Trait(ref _binding_0) => {} + DefaultImpl(ref _binding_0) => {} + Impl(ref _binding_0) => {} + Mac(ref _binding_0) => {} + } +} +pub fn visit_mac_stmt_style(_visitor: &mut V, _i: &MacStmtStyle) { + use MacStmtStyle::*; + match *_i { + Semicolon(ref _binding_0) => {} + Braces => {} + NoBraces => {} + } +} +pub fn visit_meta_item(_visitor: &mut V, _i: &MetaItem) { + use MetaItem::*; + match *_i { + Term(ref _binding_0) => {} + List(ref _binding_0) => {} + NameValue(ref _binding_0) => {} + } +} +pub fn visit_mutability(_visitor: &mut V, _i: &Mutability) { + use Mutability::*; + match *_i { + Mutable(ref _binding_0) => {} + Immutable => {} + } +} +pub fn visit_nested_meta_item(_visitor: &mut V, _i: &NestedMetaItem) { + use NestedMetaItem::*; + match *_i { + MetaItem(ref _binding_0) => {} + Literal(ref _binding_0) => {} + } +} +pub fn visit_pat(_visitor: &mut V, _i: &Pat) { + use Pat::*; + match *_i { + Wild(ref _binding_0) => {} + Ident(ref _binding_0) => {} + Struct(ref _binding_0) => {} + TupleStruct(ref _binding_0) => {} + Path(ref _binding_0) => {} + Tuple(ref _binding_0) => {} + Box(ref _binding_0) => {} + Ref(ref _binding_0) => {} + Lit(ref _binding_0) => {} + Range(ref _binding_0) => {} + Slice(ref _binding_0) => {} + Mac(ref _binding_0) => {} + } +} +pub fn visit_path_parameters(_visitor: &mut V, _i: &PathParameters) { + use PathParameters::*; + match *_i { + None => {} + AngleBracketed(ref _binding_0) => {} + Parenthesized(ref _binding_0) => {} + } +} +pub fn visit_range_limits(_visitor: &mut V, _i: &RangeLimits) { + use RangeLimits::*; + match *_i { + HalfOpen(ref _binding_0) => {} + Closed(ref _binding_0) => {} + } +} +pub fn visit_stmt(_visitor: &mut V, _i: &Stmt) { + use Stmt::*; + match *_i { + Local(ref _binding_0) => {} + Item(ref _binding_0) => {} + Expr(ref _binding_0) => {} + Semi(ref _binding_0, ref _binding_1) => {} + Mac(ref _binding_0) => {} + } +} +pub fn visit_trait_bound_modifier(_visitor: &mut V, _i: &TraitBoundModifier) { + use TraitBoundModifier::*; + match *_i { + None => {} + Maybe(ref _binding_0) => {} + } +} +pub fn visit_trait_item_kind(_visitor: &mut V, _i: &TraitItemKind) { + use TraitItemKind::*; + match *_i { + Const(ref _binding_0) => {} + Method(ref _binding_0) => {} + Type(ref _binding_0) => {} + Macro(ref _binding_0) => {} + } +} +pub fn visit_ty(_visitor: &mut V, _i: &Ty) { + use Ty::*; + match *_i { + Slice(ref _binding_0) => {} + Array(ref _binding_0) => {} + Ptr(ref _binding_0) => {} + Rptr(ref _binding_0) => {} + BareFn(ref _binding_0) => {} + Never(ref _binding_0) => {} + Tup(ref _binding_0) => {} + Path(ref _binding_0) => {} + TraitObject(ref _binding_0) => {} + ImplTrait(ref _binding_0) => {} + Paren(ref _binding_0) => {} + Group(ref _binding_0) => {} + Infer(ref _binding_0) => {} + Mac(ref _binding_0) => {} + } +} +pub fn visit_ty_param_bound(_visitor: &mut V, _i: &TyParamBound) { + use TyParamBound::*; + match *_i { + Trait(ref _binding_0, ref _binding_1) => {} + Region(ref _binding_0) => {} + } +} +pub fn visit_un_op(_visitor: &mut V, _i: &UnOp) { + use UnOp::*; + match *_i { + Deref(ref _binding_0) => {} + Not(ref _binding_0) => {} + Neg(ref _binding_0) => {} + } +} +pub fn visit_unsafety(_visitor: &mut V, _i: &Unsafety) { + use Unsafety::*; + match *_i { + Unsafe(ref _binding_0) => {} + Normal => {} + } +} +pub fn visit_variant_data(_visitor: &mut V, _i: &VariantData) { + use VariantData::*; + match *_i { + Struct(ref _binding_0, ref _binding_1) => {} + Tuple(ref _binding_0, ref _binding_1) => {} + Unit => {} + } +} +pub fn visit_view_path(_visitor: &mut V, _i: &ViewPath) { + use ViewPath::*; + match *_i { + Simple(ref _binding_0) => {} + Glob(ref _binding_0) => {} + List(ref _binding_0) => {} + } +} +pub fn visit_visibility(_visitor: &mut V, _i: &Visibility) { + use Visibility::*; + match *_i { + Public(ref _binding_0) => {} + Crate(ref _binding_0) => {} + Restricted(ref _binding_0) => {} + Inherited(ref _binding_0) => {} + } +} +pub fn visit_where_predicate(_visitor: &mut V, _i: &WherePredicate) { + use WherePredicate::*; + match *_i { + BoundPredicate(ref _binding_0) => {} + RegionPredicate(ref _binding_0) => {} + EqPredicate(ref _binding_0) => {} + } +} From d2487ef2e04394216422713bd163f557a39bd790 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 28 Nov 2020 17:05:27 +0000 Subject: [PATCH 2/3] Add Cargo.lock and update README --- collector/benchmarks/README.md | 3 +++ .../benchmarks/match-stress-exhaustive_patterns/.gitignore | 1 - .../benchmarks/match-stress-exhaustive_patterns/Cargo.lock | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/Cargo.lock diff --git a/collector/benchmarks/README.md b/collector/benchmarks/README.md index a3907f55a..db9ca863f 100644 --- a/collector/benchmarks/README.md +++ b/collector/benchmarks/README.md @@ -91,6 +91,9 @@ programs. in the past. - **match-stress-enum**: Contains a match against a huge enum, which used to have [quadratic runtime](https://github.com/rust-lang/rust/issues/7462). +- **match-stress-exhaustive_patterns**: Contains code extracted from the `syn` + crate to amplify the perf degradation caused by the `exhaustive_patterns`, as + measured [here](https://github.com/rust-lang/rust/pull/79394). - **regression-31157**: A small program that caused a [large performance regression](https://github.com/rust-lang/rust/issues/31157) from the past. - **token-stream-stress**: Constructs a long token stream much like the `quote` diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/.gitignore b/collector/benchmarks/match-stress-exhaustive_patterns/.gitignore index a9d37c560..eb5a316cb 100644 --- a/collector/benchmarks/match-stress-exhaustive_patterns/.gitignore +++ b/collector/benchmarks/match-stress-exhaustive_patterns/.gitignore @@ -1,2 +1 @@ target -Cargo.lock diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/Cargo.lock b/collector/benchmarks/match-stress-exhaustive_patterns/Cargo.lock new file mode 100644 index 000000000..17b8a4774 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "syn" +version = "0.0.0" From 290a8b902a41cc1fc0106eea33d5a5ab6f8a3efb Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 28 Nov 2020 18:12:09 +0000 Subject: [PATCH 3/3] Copy license files from `syn` --- .../LICENSE-APACHE | 201 ++++++++++++++++++ .../LICENSE-MIT | 25 +++ 2 files changed, 226 insertions(+) create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-APACHE create mode 100644 collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-MIT diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-APACHE b/collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-APACHE new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-MIT b/collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-MIT new file mode 100644 index 000000000..40b8817a4 --- /dev/null +++ b/collector/benchmarks/match-stress-exhaustive_patterns/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2016 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.