diff --git a/.gitignore b/.gitignore index 6936990..4fb5d9e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target **/*.rs.bk Cargo.lock +/.vscode diff --git a/Cargo.toml b/Cargo.toml index bf0707a..27f19cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,5 +33,5 @@ name = "snapshots" path = "src/bin/snapshots.rs" [patch.'crates-io'] -gll = { git = "https://github.com/rust-lang/gll", rev = "26d42a0117b9c48538ef20c872742e05070bb55e" } -grammer = { git = "https://github.com/lykenware/grammer", rev = "6f6f1320336d84b75805907fb302a28cb6d4cfb0" } +gll = { git = "https://github.com/rust-lang/gll", rev = "4c58803c1c4df4ca8798318d63d78454cc4450f6" } +grammer = { git = "https://github.com/LykenSol/grammer", rev = "eecb1b16cd234408d066fabec63786003925452d" } diff --git a/grammar/expr.lyg b/grammar/expr.lyg index 15b1ddd..28ed079 100644 --- a/grammar/expr.lyg +++ b/grammar/expr.lyg @@ -2,6 +2,8 @@ Expr = attrs:OuterAttr* kind:ExprKind; ExprKind = | Literal:LITERAL | Paren:{ "(" attrs:InnerAttr* expr:Expr ")" } + // unstable(raw_ref_op): + | RawAddrOf:{ "&" "raw" { "const" | mutable:"mut" } expr:Expr } | Borrow:{ "&" mutable:"mut"? expr:Expr } | Box:{ "box" expr:Expr } | Unary:{ op:UnaryOp expr:Expr } @@ -125,6 +127,6 @@ ElseExpr = | If:If ; -MatchArm = attrs:OuterAttr* "|"? pats:Pat+ % "|" { "if" guard:Expr }? "=>" body:Expr ","?; +MatchArm = attrs:OuterAttr* "|"? pat:Pat { "if" guard:Expr }? "=>" body:Expr ","?; -ClosureArg = pat:Pat { ":" ty:Type }?; +ClosureArg = attrs:OuterAttr* pat:Pat { ":" ty:Type }?; diff --git a/grammar/generics.lyg b/grammar/generics.lyg index 3762e10..add7a71 100644 --- a/grammar/generics.lyg +++ b/grammar/generics.lyg @@ -3,6 +3,8 @@ GenericParam = attrs:OuterAttr* kind:GenericParamKind; GenericParamKind = | Lifetime:{ name:LIFETIME { ":" bounds:LifetimeBound* %% "+" }? } | Type:{ name:IDENT { ":" bounds:TypeBound* %% "+" }? { "=" default:Type }? } + // unstable(const_generics): + | Const:{ "const" name:IDENT ":" ty:Type } ; ForAllBinder = "for" generics:Generics; @@ -21,23 +23,31 @@ TypeBound = | Trait:TypeTraitBound | TraitParen:{ "(" bound:TypeTraitBound ")" } ; -TypeTraitBound = unbound:"?"? binder:ForAllBinder? path:Path; +TypeTraitBound = + // unstable(const_trait_bound_opt_out): + maybe_const:{ "?" "const" }? + maybe:"?"? binder:ForAllBinder? path:Path; // Generic args of a path segment. GenericArgs = - | AngleBracket:{ "<" args_and_bindings:AngleBracketGenericArgsAndBindings? ">" } + | AngleBracket:{ "<" args_and_bindings:AngleBracketGenericArgsAndConstraints? ">" } | Paren:{ "(" inputs:Type* %% "," ")" { "->" output:Type }? } ; // FIXME(eddyb) find a way to express this `A* B*` pattern better -AngleBracketGenericArgsAndBindings = +AngleBracketGenericArgsAndConstraints = | Args:GenericArg+ %% "," - | Bindings:TypeBinding+ %% "," - | ArgsAndBindings:{ args:GenericArg+ % "," "," bindings:TypeBinding+ %% "," } + | Constraints:AssocTypeConstraint+ %% "," + | ArgsAndConstraints:{ args:GenericArg+ % "," "," constraints:AssocTypeConstraint+ %% "," } ; GenericArg = | Lifetime:LIFETIME | Type:Type + // unstable(const_generics): + | Const:{ neg:"-"? lit:LITERAL | "{" expr:Expr "}" } ; -TypeBinding = name:IDENT "=" ty:Type; +AssocTypeConstraint = + | Eq:{ name:IDENT "=" ty:Type } + // unstable(associated_type_bounds): + | Bound:{ name:IDENT ":" bounds:TypeBound* %% "+" }; diff --git a/grammar/item.lyg b/grammar/item.lyg index b198a8b..4986fc5 100644 --- a/grammar/item.lyg +++ b/grammar/item.lyg @@ -21,18 +21,19 @@ ItemKind = auto:"auto"? "trait" name:IDENT generics:Generics? { ":" superbounds:TypeBound* %% "+" }? - where_clause:WhereClause? "{" trait_items:TraitItem* "}" + where_clause:WhereClause? "{" attrs:InnerAttr* trait_items:TraitItem* "}" } // unstable(trait_alias): | TraitAlias:{ - "trait" name:IDENT generics:Generics? - { ":" superbounds:TypeBound* %% "+" }? - where_clause:WhereClause? "=" bounds:TypeBound* %% "+" ";" + "trait" name:IDENT generics:Generics? "=" bounds:TypeBound* %% "+" + where_clause:WhereClause? ";" } | Impl:{ // unstable(specialization): defaultness:"default"? unsafety:"unsafe"? "impl" generics:Generics? + // unstable(const_trait_impl) + constness:"const"? { negate:"!"? trait_path:Path "for" }? ty:Type where_clause:WhereClause? "{" attrs:InnerAttr* impl_items:ImplItem* "}" } @@ -84,20 +85,23 @@ ImplItemKind = | MacroCall:ItemMacroCall ; -FnHeader = constness:"const"? unsafety:"unsafe"? asyncness:"async"? { "extern" abi:Abi }?; -FnDecl = name:IDENT generics:Generics? "(" args:FnArgs? ")" { "->" ret_ty:Type }? where_clause:WhereClause?; +FnHeader = constness:"const"? asyncness:"async"? unsafety:"unsafe"? { "extern" abi:Abi }?; +FnDecl = name:IDENT generics:Generics? "(" params:FnParams? ")" { "->" ret_ty:Type }? where_clause:WhereClause?; // FIXME(eddyb) find a way to express this `A* B?` pattern better -FnArgs = - | Regular:FnArg+ %% "," - | Variadic:"..." - | RegularAndVariadic:{ args:FnArg+ % "," "," "..." } +FnParams = + | Regular:FnParam+ %% "," + | CVariadic:FnCVariadicParam + | RegularAndCVariadic:{ args:FnParam+ % "," "," c_variadic:FnCVariadicParam } ; -FnArg = +FnParam = attrs:OuterAttr* kind:FnParamKind; +FnParamKind = | SelfValue:{ mutable:"mut"? "self" } | SelfRef:{ "&" lt:LIFETIME? mutable:"mut"? "self" } - | Regular:FnSigInput + | Regular:{ { pat:Pat ":" }? ty:Type } ; +// unstable(c_variadic): +FnCVariadicParam = attrs:OuterAttr* { pat:Pat ":" }? "..."; EnumVariant = attrs:OuterAttr* name:IDENT kind:EnumVariantKind { "=" discr:Expr }?; EnumVariantKind = diff --git a/grammar/pat.lyg b/grammar/pat.lyg index 58f72a6..83f483d 100644 --- a/grammar/pat.lyg +++ b/grammar/pat.lyg @@ -1,18 +1,30 @@ Pat = | Wild:"_" + | Rest:".." | Literal:{ minus:"-"? lit:LITERAL } // unstable(exclusive_range_pattern): - | Range:{ start:PatRangeValue ".." end:PatRangeValue } - | RangeInclusive:{ start:PatRangeValue { "..." | "..=" } end:PatRangeValue } + | Range:{ + | start:PatRangeValue ".." end:PatRangeValue + // unstable(half_open_range_patterns): + | start:PatRangeValue ".." | ".." end:PatRangeValue + } + | RangeInclusive:{ + | start:PatRangeValue { "..." | "..=" } end:PatRangeValue + // unstable(half_open_range_patterns): + | { "..." | "..=" } end:PatRangeValue + } | Binding:{ binding:Binding { "@" subpat:Pat }? } | Paren:{ "(" pat:Pat ")" } | Ref:{ "&" mutable:"mut"? pat:Pat } // unstable(box_patterns): | Box:{ "box" pat:Pat } - | Slice:{ "[" elems:SlicePatElem* %% "," "]" } - | Tuple:{ "(" fields:TuplePatField* %% "," ")" } + // unstable(or_patterns): + // FIXME(eddyb) find a way to express "2 or more" (like regex `{2,}`). + | Or:{ first_pat:Pat "|" pats:Pat+ % "|" } + | Slice:{ "[" elems:Pat* %% "," "]" } + | Tuple:{ "(" fields:Pat* %% "," ")" } | Path:QPath - | TupleStruct:{ path:Path "(" fields:TuplePatField* %% "," ")" } + | TupleStruct:{ path:Path "(" fields:Pat* %% "," ")" } | Struct:{ path:Path "{" fields:StructPatFieldsAndEllipsis "}" } | MacroCall:MacroCall ; @@ -24,16 +36,6 @@ PatRangeValue = Binding = boxed:"box"? reference:"ref"? mutable:"mut"? name:IDENT; -SlicePatElem = - | Subslice:{ subpat:Pat? ".." } - | Pat:Pat - ; - -TuplePatField = - | Ellipsis:".." - | Pat:Pat - ; - // FIXME(eddyb) find a way to express this `A* B?` pattern better StructPatFieldsAndEllipsis = | Fields:StructPatField* %% "," @@ -41,7 +43,8 @@ StructPatFieldsAndEllipsis = | FieldsAndEllipsis:{ fields:StructPatField+ % "," "," ".." } ; -StructPatField = +StructPatField = attrs:OuterAttr* kind:StructPatFieldKind; +StructPatFieldKind = | Shorthand:Binding | Explicit:{ field:FieldName ":" pat:Pat } ; diff --git a/grammar/type.lyg b/grammar/type.lyg index 509b690..18674bb 100644 --- a/grammar/type.lyg +++ b/grammar/type.lyg @@ -21,7 +21,8 @@ Type = FnSigInputs = | Regular:FnSigInput+ %% "," - | Variadic:"..." - | RegularAndVariadic:{ inputs:FnSigInput+ % "," "," "..." } + | CVariadic:FnSigCVariadicInput + | RegularAndCVariadic:{ inputs:FnSigInput+ % "," "," c_variadic:FnSigCVariadicInput } ; -FnSigInput = { pat:Pat ":" }? ty:Type; +FnSigInput = attrs:OuterAttr* { pat:Pat ":" }? ty:Type; +FnSigCVariadicInput = attrs:OuterAttr* "..."; diff --git a/src/bin/coverage.rs b/src/bin/coverage.rs index 2681fe9..023df18 100644 --- a/src/bin/coverage.rs +++ b/src/bin/coverage.rs @@ -100,6 +100,17 @@ impl From> for Error { /// using the `ModuleContents` rule, and pass the result to `f`. fn parse_file(path: &Path) -> ModuleContentsResult { let src = fs::read_to_string(path).unwrap(); + + // Strip shebang, using the same logic as `rustc_lexer`. + // FIXME(rust-lang/rust#70528) this may have to change in the future. + let src = if src.starts_with("#!") && !src.starts_with("#![") { + // Remove the first line's contents, i.e. up to the `\n`, + // but keep the `\n` so that the line numbers remain correct. + &src[src.find('\n').unwrap_or(src.len())..] + } else { + &src[..] + }; + let tts = src.parse::()?; let res = parse::ModuleContents::parse(tts)?; Ok(res) @@ -171,7 +182,7 @@ fn ambiguity_check(handle: &ModuleContentsHandle) -> Result<(), MoreThanOne> { add_children(&[child]); } } - NodeShape::Choice => add_children(&[forest.one_choice(source)?]), + NodeShape::Choice(_) => add_children(&[forest.one_choice(source)?]), NodeShape::Split(..) => { let (left, right) = forest.one_split(source)?; add_children(&[left, right]) diff --git a/src/bin/snapshots.rs b/src/bin/snapshots.rs index 10e361f..c4c7703 100644 --- a/src/bin/snapshots.rs +++ b/src/bin/snapshots.rs @@ -57,17 +57,16 @@ fn test_snapshot(file: walkdir::DirEntry) { If Cond ElseExpr MatchArm ClosureArg // generics.lyg Generics GenericParam GenericParamKind ForAllBinder WhereClause WhereBound LifetimeBound - TypeBound TypeTraitBound GenericArgs AngleBracketGenericArgsAndBindings GenericArg - TypeBinding + TypeBound TypeTraitBound GenericArgs AngleBracketGenericArgsAndConstraints GenericArg + AssocTypeConstraint // item.lyg ModuleContents Item ItemKind UseTree UseTreePrefix ForeignItem ForeignItemKind TraitItem - TraitItemKind ImplItem ImplItemKind FnHeader FnDecl FnArgs FnArg EnumVariant EnumVariantKind - StructBody TupleField RecordField + TraitItemKind ImplItem ImplItemKind FnHeader FnDecl FnParams FnParam EnumVariant + EnumVariantKind StructBody TupleField RecordField // macro.lyg MacroCall MacroInput ItemMacroCall ItemMacroInput // pat.lyg - Pat PatRangeValue Binding SlicePatElem TuplePatField StructPatFieldsAndEllipsis - StructPatField + Pat PatRangeValue Binding StructPatFieldsAndEllipsis StructPatField // path.lyg Path RelativePath PathSegment QSelf QPath // stmt.lyg