Skip to content
This repository has been archived by the owner on Apr 8, 2024. It is now read-only.

Update for new stable and unstable features, and fix a few mistakes. #68

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
**/*.rs.bk
Cargo.lock
/.vscode
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
6 changes: 4 additions & 2 deletions grammar/expr.lyg
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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 ","?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to this setup, where nested or-patterns are unstable, then match 0 { 0 | 1 => 0 } is also unstable but it isn't.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have a proper stability setup, but I can undo this change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just leave a comment instead. You might want to double check if/while let also.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we annoyingly don't allow fn foo(Ok(x) | Err(x): _); but require parens around the pattern instead.


ClosureArg = pat:Pat { ":" ty:Type }?;
ClosureArg = attrs:OuterAttr* pat:Pat { ":" ty:Type }?;
22 changes: 16 additions & 6 deletions grammar/generics.lyg
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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* %% "+" };
28 changes: 16 additions & 12 deletions grammar/item.lyg
Original file line number Diff line number Diff line change
Expand Up @@ -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* "}"
}
Expand Down Expand Up @@ -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 }
Comment on lines +94 to +95
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... is allowed in any position now syntactically with semantic restrictions in validation to enforce the order (I fixed your FIXME.)

;
FnArg =
FnParam = attrs:OuterAttr* kind:FnParamKind;
FnParamKind =
| SelfValue:{ mutable:"mut"? "self" }
| SelfRef:{ "&" lt:LIFETIME? mutable:"mut"? "self" }
Comment on lines 99 to 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The self param is only allowed in the first parameter syntactically (Also, consider lifting this out to its own rule.)

| Regular:FnSigInput
| Regular:{ { pat:Pat ":" }? ty:Type }
;
// unstable(c_variadic):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The syntax itself is stable so you can remove this.

FnCVariadicParam = attrs:OuterAttr* { pat:Pat ":" }? "...";
Copy link
Contributor

@Centril Centril Mar 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more like this:

FnParamKind =
   | SelfParam: FnSelfParam
   | Regular:{ { pat:Pat ":" }? ty:FnParamType }
   ;

FnParamType =
   | CVariadic: "..."
   | Regular: Type
   ;


EnumVariant = attrs:OuterAttr* name:IDENT kind:EnumVariantKind { "=" discr:Expr }?;
EnumVariantKind =
Expand Down
35 changes: 19 additions & 16 deletions grammar/pat.lyg
Original file line number Diff line number Diff line change
@@ -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
Centril marked this conversation as resolved.
Show resolved Hide resolved
// unstable(half_open_range_patterns):
| { "..." | "..=" } end:PatRangeValue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| { "..." | "..=" } end:PatRangeValue
| "..=" 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,}`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively you can just explain this as a binary operator rather than a list.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, it's just weird to think of it as a binary operator because it's fully commutative and associative.

| 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
;
Expand All @@ -24,24 +36,15 @@ 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* %% ","
| Ellipsis:{ ".." }
| FieldsAndEllipsis:{ fields:StructPatField+ % "," "," ".." }
;

StructPatField =
StructPatField = attrs:OuterAttr* kind:StructPatFieldKind;
StructPatFieldKind =
| Shorthand:Binding
| Explicit:{ field:FieldName ":" pat:Pat }
;
7 changes: 4 additions & 3 deletions grammar/type.lyg
Original file line number Diff line number Diff line change
Expand Up @@ -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* "...";
Comment on lines 22 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't right; the actual grammar is defined by:

    fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>) -> PResult<'a, TyKind> {
        let unsafety = self.parse_unsafety();
        let ext = self.parse_extern()?;
        self.expect_keyword(kw::Fn)?;
        let decl = self.parse_fn_decl(|_| false, AllowPlus::No)?;
        Ok(TyKind::BareFn(P(BareFnTy { ext, unsafety, generic_params, decl })))
    }

Aside from that false, which adjusts the precedence (bias towards named vs. not), its just the regular FnDecl grammar, and since we don't deal with precedence here, you can use FnDecl instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I'd rather move the full grammar here than have a separate FnDecl, but that makes sense.
So fn(self) parses, I didn't know that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I've made some changes recently in the large scale parser refactorings to simplify things.

Copy link
Contributor

@Centril Centril Mar 30, 2020

13 changes: 12 additions & 1 deletion src/bin/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ impl<A, Pat> From<gll::grammer::parser::ParseError<A, Pat>> for Error<A, Pat> {
/// 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::<proc_macro2::TokenStream>()?;
let res = parse::ModuleContents::parse(tts)?;
Ok(res)
Expand Down Expand Up @@ -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])
Expand Down
11 changes: 5 additions & 6 deletions src/bin/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down