From 8511cf48f93fc37c44a87f5823cce1338da1bb7e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 1 Jan 2021 15:52:08 -0800 Subject: [PATCH 1/2] Update grammar for order of parameters/arguments. Generic param order restriction was changed in https://github.com/rust-lang/rust/pull/58191. Generic argument order restriction was changed in https://github.com/rust-lang/rust/pull/70261. `for` lifetime argument restriction was changed in https://github.com/rust-lang/rust/pull/48326. Generic parameter parsing: https://github.com/rust-lang/rust/blob/206ee1eea3467fd1d7f1efdbeafe27880897bb2c/compiler/rustc_parse/src/parser/generics.rs#L83-L153 Generic argument parsing: https://github.com/rust-lang/rust/blob/17eec1433c69972844dd228b5fe801f218e118c3/compiler/rustc_parse/src/parser/path.rs#L395-L413 `for` argument parsing: https://github.com/rust-lang/rust/blob/206ee1eea3467fd1d7f1efdbeafe27880897bb2c/compiler/rustc_parse/src/parser/ty.rs#L724-L736 Fixes #785 --- src/items/generics.md | 34 ++++++++++++++++++---------------- src/paths.md | 29 ++++++----------------------- 2 files changed, 24 insertions(+), 39 deletions(-) diff --git a/src/items/generics.md b/src/items/generics.md index abb50b47f..a798d91f7 100644 --- a/src/items/generics.md +++ b/src/items/generics.md @@ -2,30 +2,27 @@ > **Syntax**\ > _Generics_ :\ ->    `<` _GenericParams_ `>` +>    `<` _GenericParams_? `>` > > _GenericParams_ :\ ->       _LifetimeParams_\ ->    | ( _LifetimeParam_ `,` )\* _TypeParams_\ ->    | ( _LifetimeParam_ `,` )\* ( _TypeParam_ `,` )\* _ConstParams_ +>    (_GenericParam_ `,`)\* _GenericParam_ `,`? > -> _LifetimeParams_ :\ ->    ( _LifetimeParam_ `,` )\* _LifetimeParam_? +> _GenericParam_ :\ +>    [_OuterAttribute_] \*\ +>    (\ +>          _LifetimeParam_\ +>       | _TypeParam_\ +>       | _ConstParam_\ +>    ) > > _LifetimeParam_ :\ ->    [_OuterAttribute_]? [LIFETIME_OR_LABEL] ( `:` [_LifetimeBounds_] )? -> -> _TypeParams_:\ ->    ( _TypeParam_ `,` )\* _TypeParam_? +>    [LIFETIME_OR_LABEL] ( `:` [_LifetimeBounds_] )? > > _TypeParam_ :\ ->    [_OuterAttribute_]? [IDENTIFIER]( `:` [_TypeParamBounds_]? )? ( `=` [_Type_] )? -> -> _ConstParams_:\ ->    ( _ConstParam_ `,` )\* _ConstParam_? +>    [IDENTIFIER]( `:` [_TypeParamBounds_]? )? ( `=` [_Type_] )? > > _ConstParam_:\ ->    [_OuterAttribute_]? `const` [IDENTIFIER] `:` [_Type_] +>    `const` [IDENTIFIER] `:` [_Type_] Functions, type aliases, structs, enumerations, unions, traits, and implementations may be *parameterized* by types, constants, and lifetimes. These @@ -91,12 +88,15 @@ referred to with path syntax. >    _ForLifetimes_? [_Type_] `:` [_TypeParamBounds_]? > > _ForLifetimes_ :\ ->    `for` `<` [_LifetimeParams_](#generic-parameters) `>` +>    `for` `<` [_GenericParams_](#generic-parameters) `>` *Where clauses* provide another way to specify bounds on type and lifetime parameters as well as a way to specify bounds on types that aren't type parameters. +The `for` keyword can be used to introduce [higher-ranked lifetimes]. It only +allows [_LifetimeParam_] parameters. + Bounds that don't use the item's parameters or higher-ranked lifetimes are checked when the item is defined. It is an error for such a bound to be false. @@ -141,6 +141,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> { [IDENTIFIER]: ../identifiers.md [LIFETIME_OR_LABEL]: ../tokens.md#lifetimes-and-loop-labels +[_LifetimeParam_]: #generic-parameters [_LifetimeBounds_]: ../trait-bounds.md [_Lifetime_]: ../trait-bounds.md [_OuterAttribute_]: ../attributes.md @@ -150,6 +151,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> { [arrays]: ../types/array.md [const contexts]: ../const_eval.md#const-context [function pointers]: ../types/function-pointer.md +[higher-ranked lifetimes]: ../trait-bounds.md#higher-ranked-trait-bounds [raw pointers]: ../types/pointer.md#raw-pointers-const-and-mut [references]: ../types/pointer.md#shared-references- [repeat expressions]: ../expressions/array-expr.md diff --git a/src/paths.md b/src/paths.md index 47a14ee91..29d2475b5 100644 --- a/src/paths.md +++ b/src/paths.md @@ -50,27 +50,10 @@ mod m { > > _GenericArgs_ :\ >       `<` `>`\ ->    | `<` _GenericArgsLifetimes_ `,`? `>`\ ->    | `<` _GenericArgsTypes_ `,`? `>`\ ->    | `<` _GenericArgsConsts_ `,`? `>`\ ->    | `<` _GenericArgsBindings_ `,`? `>`\ ->    | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,`? `>`\ ->    | `<` _GenericArgsLifetimes_ `,` _GenericArgsConsts_ `,`? `>`\ ->    | `<` _GenericArgsLifetimes_ `,` _GenericArgsBindings_ `,`? `>`\ ->    | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsConsts_ `,`? `>`\ ->    | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsBindings_ `,`? `>`\ ->    | `<` _GenericArgsLifetimes_ `,` _GenericArgsConsts_ `,` _GenericArgsBindings_ `,`? `>`\ ->    | `<` _GenericArgsTypes_ `,` _GenericArgsConsts_ `,` _GenericArgsBindings_ `,`? `>`\ ->    | `<` _GenericArgsLifetimes_ `,` _GenericArgsTypes_ `,` _GenericArgsConsts_ `,` _GenericArgsBindings_ `,`? `>` +>    | `<` ( _GenericArg_ `,` )\* _GenericArg_ `,`? `>` > -> _GenericArgsLifetimes_ :\ ->    [_Lifetime_] (`,` [_Lifetime_])\* -> -> _GenericArgsTypes_ :\ ->    [_Type_] (`,` [_Type_])\* -> -> _GenericArgsConsts_ :\ ->    _GenericArgsConst_ (`,` _GenericArgsConst_)\* +> _GenericArg_ :\ +>    [_Lifetime_] | [_Type_] | _GenericArgsConst_ | _GenericArgsBinding_ > > _GenericArgsConst_ :\ >       [_BlockExpression_]\ @@ -78,9 +61,6 @@ mod m { >    | `-` [_LiteralExpression_]\ >    | [_SimplePathSegment_] > -> _GenericArgsBindings_ :\ ->    _GenericArgsBinding_ (`,` _GenericArgsBinding_)\* -> > _GenericArgsBinding_ :\ >    [IDENTIFIER] `=` [_Type_] @@ -95,6 +75,9 @@ ambiguity with the less-than operator. This is colloquially known as "turbofish" Vec::::with_capacity(1024); ``` +The order of generic arguments is restricted to lifetime arguments, then type +arguments, then const arguments, then equality constraints. + Const arguments must be surrounded by braces unless they are a [literal] or a single segment path. From 9d0aa172932ed15ec1b13556e6809b74bc58a02b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 9 Jan 2021 07:45:46 -0800 Subject: [PATCH 2/2] Update generic params based on review. --- src/items/associated-items.md | 4 ++-- src/items/enumerations.md | 4 ++-- src/items/external-blocks.md | 4 ++-- src/items/functions.md | 4 ++-- src/items/generics.md | 15 ++++----------- src/items/implementations.md | 6 +++--- src/items/structs.md | 6 +++--- src/items/traits.md | 8 ++++---- src/items/type-aliases.md | 4 ++-- src/items/unions.md | 4 ++-- 10 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/items/associated-items.md b/src/items/associated-items.md index 5434c0495..c1ad2397e 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -80,7 +80,7 @@ let _: f64 = f64::from_i32(42); ### Methods > _Method_ :\ ->    [_FunctionQualifiers_] `fn` [IDENTIFIER] [_Generics_]?\ +>    [_FunctionQualifiers_] `fn` [IDENTIFIER] [_GenericParams_]?\ >       `(` _SelfParam_ (`,` [_FunctionParam_])\* `,`? `)`\ >       [_FunctionReturnType_]? [_WhereClause_]?\ >       [_BlockExpression_] @@ -344,7 +344,7 @@ fn main() { [_FunctionParam_]: functions.md [_FunctionQualifiers_]: functions.md [_FunctionReturnType_]: functions.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_Lifetime_]: ../trait-bounds.md [_Type_]: ../types.md#type-expressions [_WhereClause_]: generics.md#where-clauses diff --git a/src/items/enumerations.md b/src/items/enumerations.md index 7e4795508..8248a47db 100644 --- a/src/items/enumerations.md +++ b/src/items/enumerations.md @@ -4,7 +4,7 @@ > _Enumeration_ :\ >    `enum` > [IDENTIFIER]  -> [_Generics_]? +> [_GenericParams_]? > [_WhereClause_]? > `{` _EnumItems_? `}` > @@ -172,7 +172,7 @@ enum E { ``` [IDENTIFIER]: ../identifiers.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_WhereClause_]: generics.md#where-clauses [_Expression_]: ../expressions.md [_TupleFields_]: structs.md diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index b31dd17d4..6a1ada912 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -17,7 +17,7 @@ >    `static` `mut`? [IDENTIFIER] `:` [_Type_] `;` > > _ExternalFunctionItem_ :\ ->    `fn` [IDENTIFIER] [_Generics_]?\ +>    `fn` [IDENTIFIER] [_GenericParams_]?\ >    `(` ( _NamedFunctionParameters_ | _NamedFunctionParametersWithVariadics_ )? `)`\ >    [_FunctionReturnType_]? [_WhereClause_]? `;` > @@ -190,7 +190,7 @@ restrictions as [regular function parameters]. [statics]: static-items.md [_Abi_]: functions.md [_FunctionReturnType_]: functions.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_InnerAttribute_]: ../attributes.md [_MacroInvocationSemi_]: ../macros.md#macro-invocation [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax diff --git a/src/items/functions.md b/src/items/functions.md index 27dbef24b..550f6d96a 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -2,7 +2,7 @@ > **Syntax**\ > _Function_ :\ ->    _FunctionQualifiers_ `fn` [IDENTIFIER] [_Generics_]?\ +>    _FunctionQualifiers_ `fn` [IDENTIFIER] [_GenericParams_]?\ >       `(` _FunctionParameters_? `)`\ >       _FunctionReturnType_? [_WhereClause_]?\ >       [_BlockExpression_] @@ -341,7 +341,7 @@ fn foo_oof(#[some_inert_attribute] arg: u8) { [RAW_STRING_LITERAL]: ../tokens.md#raw-string-literals [STRING_LITERAL]: ../tokens.md#string-literals [_BlockExpression_]: ../expressions/block-expr.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_Pattern_]: ../patterns.md [_Type_]: ../types.md#type-expressions [_WhereClause_]: generics.md#where-clauses diff --git a/src/items/generics.md b/src/items/generics.md index a798d91f7..789563c8a 100644 --- a/src/items/generics.md +++ b/src/items/generics.md @@ -1,19 +1,12 @@ # Generic parameters > **Syntax**\ -> _Generics_ :\ ->    `<` _GenericParams_? `>` -> > _GenericParams_ :\ ->    (_GenericParam_ `,`)\* _GenericParam_ `,`? +>       `<` `>`\ +>    | `<` (_GenericParam_ `,`)\* _GenericParam_ `,`? `>` > > _GenericParam_ :\ ->    [_OuterAttribute_] \*\ ->    (\ ->          _LifetimeParam_\ ->       | _TypeParam_\ ->       | _ConstParam_\ ->    ) +>    [_OuterAttribute_]\* ( _LifetimeParam_ | _TypeParam_ | _ConstParam_ ) > > _LifetimeParam_ :\ >    [LIFETIME_OR_LABEL] ( `:` [_LifetimeBounds_] )? @@ -88,7 +81,7 @@ referred to with path syntax. >    _ForLifetimes_? [_Type_] `:` [_TypeParamBounds_]? > > _ForLifetimes_ :\ ->    `for` `<` [_GenericParams_](#generic-parameters) `>` +>    `for` [_GenericParams_](#generic-parameters) *Where clauses* provide another way to specify bounds on type and lifetime parameters as well as a way to specify bounds on types that aren't type diff --git a/src/items/implementations.md b/src/items/implementations.md index 26ba45a8e..976241481 100644 --- a/src/items/implementations.md +++ b/src/items/implementations.md @@ -5,7 +5,7 @@ >    _InherentImpl_ | _TraitImpl_ > > _InherentImpl_ :\ ->    `impl` [_Generics_]? [_Type_] [_WhereClause_]? `{`\ +>    `impl` [_GenericParams_]? [_Type_] [_WhereClause_]? `{`\ >       [_InnerAttribute_]\*\ >       _InherentImplItem_\*\ >    `}` @@ -17,7 +17,7 @@ >    ) > > _TraitImpl_ :\ ->    `unsafe`? `impl` [_Generics_]? `!`? +>    `unsafe`? `impl` [_GenericParams_]? `!`? > [_TypePath_] `for` [_Type_]\ >    [_WhereClause_]?\ >    `{`\ @@ -206,7 +206,7 @@ attributes]. [_ConstantItem_]: constant-items.md [_Function_]: functions.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_InnerAttribute_]: ../attributes.md [_MacroInvocationSemi_]: ../macros.md#macro-invocation [_Method_]: associated-items.md#methods diff --git a/src/items/structs.md b/src/items/structs.md index debd52cc7..9523e7bfb 100644 --- a/src/items/structs.md +++ b/src/items/structs.md @@ -8,14 +8,14 @@ > _StructStruct_ :\ >    `struct` > [IDENTIFIER]  -> [_Generics_]? +> [_GenericParams_]? > [_WhereClause_]? > ( `{` _StructFields_? `}` | `;` ) > > _TupleStruct_ :\ >    `struct` > [IDENTIFIER]  -> [_Generics_]? +> [_GenericParams_]? > `(` _TupleFields_? `)` > [_WhereClause_]? > `;` @@ -82,7 +82,7 @@ particular layout using the [`repr` attribute]. [_OuterAttribute_]: ../attributes.md [IDENTIFIER]: ../identifiers.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_WhereClause_]: generics.md#where-clauses [_Visibility_]: ../visibility-and-privacy.md [_Type_]: ../types.md#type-expressions diff --git a/src/items/traits.md b/src/items/traits.md index d08f45c6f..3094bb49f 100644 --- a/src/items/traits.md +++ b/src/items/traits.md @@ -3,7 +3,7 @@ > **Syntax**\ > _Trait_ :\ >    `unsafe`? `trait` [IDENTIFIER]  -> [_Generics_]? +> [_GenericParams_]? > ( `:` [_TypeParamBounds_]? )? > [_WhereClause_]? `{`\ >      [_InnerAttribute_]\*\ @@ -26,12 +26,12 @@ >       _TraitMethodDecl_ ( `;` | [_BlockExpression_] ) > > _TraitFunctionDecl_ :\ ->    [_FunctionQualifiers_] `fn` [IDENTIFIER] [_Generics_]?\ +>    [_FunctionQualifiers_] `fn` [IDENTIFIER] [_GenericParams_]?\ >       `(` _TraitFunctionParameters_? `)`\ >       [_FunctionReturnType_]? [_WhereClause_]? > > _TraitMethodDecl_ :\ ->    [_FunctionQualifiers_] `fn` [IDENTIFIER] [_Generics_]?\ +>    [_FunctionQualifiers_] `fn` [IDENTIFIER] [_GenericParams_]?\ >       `(` [_SelfParam_] (`,` _TraitFunctionParam_)\* `,`? `)`\ >       [_FunctionReturnType_]? [_WhereClause_]? > @@ -339,7 +339,7 @@ fn main() { [_Expression_]: ../expressions.md [_FunctionQualifiers_]: functions.md [_FunctionReturnType_]: functions.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_MacroInvocationSemi_]: ../macros.md#macro-invocation [_OuterAttribute_]: ../attributes.md [_InnerAttribute_]: ../attributes.md diff --git a/src/items/type-aliases.md b/src/items/type-aliases.md index 6afd7a7fa..d8fc5bf66 100644 --- a/src/items/type-aliases.md +++ b/src/items/type-aliases.md @@ -2,7 +2,7 @@ > **Syntax**\ > _TypeAlias_ :\ ->    `type` [IDENTIFIER] [_Generics_]? +>    `type` [IDENTIFIER] [_GenericParams_]? > [_WhereClause_]? `=` [_Type_] `;` A _type alias_ defines a new name for an existing [type]. Type aliases are @@ -33,6 +33,6 @@ let _ = TypeAlias(5); // Doesn't work ``` [IDENTIFIER]: ../identifiers.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_WhereClause_]: generics.md#where-clauses [_Type_]: ../types.md#type-expressions diff --git a/src/items/unions.md b/src/items/unions.md index c974a9a55..dabb6355c 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -2,7 +2,7 @@ > **Syntax**\ > _Union_ :\ ->    `union` [IDENTIFIER] [_Generics_]? [_WhereClause_]? +>    `union` [IDENTIFIER] [_GenericParams_]? [_WhereClause_]? > `{`[_StructFields_] `}` A union declaration uses the same syntax as a struct declaration, except with @@ -177,7 +177,7 @@ generics, trait implementations, inherent implementations, coherence, pattern checking, etc etc etc). [IDENTIFIER]: ../identifiers.md -[_Generics_]: generics.md +[_GenericParams_]: generics.md [_WhereClause_]: generics.md#where-clauses [_StructFields_]: structs.md [`transmute`]: ../../std/mem/fn.transmute.html