From 338a27174a0bd900e573b2ee0e7383244a8b0bf9 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 8 Jul 2020 22:16:18 +0200 Subject: [PATCH 1/8] forbid generic params in the type of const params --- src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0671.md | 2 +- src/librustc_error_codes/error_codes/E0770.md | 15 +++++++++ src/librustc_resolve/diagnostics.rs | 10 ++++++ src/librustc_resolve/late.rs | 14 +++++++-- src/librustc_resolve/lib.rs | 28 ++++++++++++++++- ...const-param-type-depends-on-const-param.rs | 13 ++++++++ ...t-param-type-depends-on-const-param.stderr | 31 +++++++++++++++++++ ...aram-type-depends-on-type-param-ungated.rs | 2 +- ...-type-depends-on-type-param-ungated.stderr | 17 +++++----- .../const-param-type-depends-on-type-param.rs | 11 ++++--- ...st-param-type-depends-on-type-param.stderr | 18 +++++++---- .../ui/const-generics/issues/issue-71381.rs | 2 ++ .../const-generics/issues/issue-71381.stderr | 16 ++++++++-- .../ui/const-generics/issues/issue-71611.rs | 1 + .../const-generics/issues/issue-71611.stderr | 8 ++++- 16 files changed, 160 insertions(+), 29 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0770.md create mode 100644 src/test/ui/const-generics/const-param-type-depends-on-const-param.rs create mode 100644 src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 60aa12b0511c7..6160450d76676 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -452,6 +452,7 @@ E0766: include_str!("./error_codes/E0766.md"), E0767: include_str!("./error_codes/E0767.md"), E0768: include_str!("./error_codes/E0768.md"), E0769: include_str!("./error_codes/E0769.md"), +E0770: include_str!("./error_codes/E0770.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0671.md b/src/librustc_error_codes/error_codes/E0671.md index 449fb8ffc8945..a993ce826a737 100644 --- a/src/librustc_error_codes/error_codes/E0671.md +++ b/src/librustc_error_codes/error_codes/E0671.md @@ -3,7 +3,7 @@ Const parameters cannot depend on type parameters. The following is therefore invalid: -```compile_fail,E0741 +```compile_fail,E0770 #![feature(const_generics)] fn const_id() -> T { // error diff --git a/src/librustc_error_codes/error_codes/E0770.md b/src/librustc_error_codes/error_codes/E0770.md new file mode 100644 index 0000000000000..278bf9b907b24 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0770.md @@ -0,0 +1,15 @@ +The type of a const parameter references other generic parameters. + +Erroneous code example: + +```compile_fail,E0770 +#![feature(const_generics)] +fn foo() {} // error! +``` + +To fix this error, use a concrete type for the const parameter: + +``` +#![feature(const_generics)] +fn foo() {} +``` diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 4f25b948eb66e..c5ac7f7413ad4 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -442,6 +442,16 @@ impl<'a> Resolver<'a> { ); err } + ResolutionError::ParamInTyOfConstArg => { + let mut err = struct_span_err!( + self.session, + span, + E0770, + "the type of const parameters must not depend on other generic parameters" + ); + err.span_label(span, "const parameters must have a concrete type"); + err + } ResolutionError::SelfInTyParamDefault => { let mut err = struct_span_err!( self.session, diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index c165a601408fd..b252e5f29a3e5 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -123,6 +123,10 @@ crate enum RibKind<'a> { /// from the default of a type parameter because they're not declared /// before said type parameter. Also see the `visit_generics` override. ForwardTyParamBanRibKind, + + /// We are inside of the type of a const parameter. Can't refer to any + /// parameters. + ConstParamTyRibKind, } impl RibKind<'_> { @@ -135,7 +139,8 @@ impl RibKind<'_> { | FnItemRibKind | ConstantItemRibKind | ModuleRibKind(_) - | MacroDefinition(_) => false, + | MacroDefinition(_) + | ConstParamTyRibKind => false, AssocItemRibKind | ItemRibKind(_) | ForwardTyParamBanRibKind => true, } } @@ -562,7 +567,11 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { for bound in ¶m.bounds { self.visit_param_bound(bound); } + self.ribs[TypeNS].push(Rib::new(ConstParamTyRibKind)); + self.ribs[ValueNS].push(Rib::new(ConstParamTyRibKind)); self.visit_ty(ty); + self.ribs[TypeNS].pop().unwrap(); + self.ribs[ValueNS].pop().unwrap(); } } } @@ -798,7 +807,8 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { | ItemRibKind(..) | ConstantItemRibKind | ModuleRibKind(..) - | ForwardTyParamBanRibKind => { + | ForwardTyParamBanRibKind + | ConstParamTyRibKind => { return false; } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a265c15c18bc9..ba365e8f8418c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -214,6 +214,8 @@ enum ResolutionError<'a> { BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>), /// Error E0128: type parameters with a default cannot use forward-declared identifiers. ForwardDeclaredTyParam, // FIXME(const_generics:defaults) + /// ERROR E0770: the type of const parameters must not depend on other generic parameters. + ParamInTyOfConstArg, /// Error E0735: type parameters with a default cannot use `Self` SelfInTyParamDefault, /// Error E0767: use of unreachable label @@ -2480,6 +2482,12 @@ impl<'a> Resolver<'a> { } return Res::Err; } + ConstParamTyRibKind => { + if record_used { + self.report_error(span, ParamInTyOfConstArg); + } + return Res::Err; + } } } if let Some(res_err) = res_err { @@ -2503,6 +2511,12 @@ impl<'a> Resolver<'a> { // This was an attempt to use a type parameter outside its scope. ItemRibKind(has_generic_params) => has_generic_params, FnItemRibKind => HasGenericParams::Yes, + ConstParamTyRibKind => { + if record_used { + self.report_error(span, ResolutionError::ParamInTyOfConstArg); + } + return Res::Err; + } }; if record_used { @@ -2527,9 +2541,21 @@ impl<'a> Resolver<'a> { } for rib in ribs { let has_generic_params = match rib.kind { + NormalRibKind + | ClosureOrAsyncRibKind + | AssocItemRibKind + | ModuleRibKind(..) + | MacroDefinition(..) + | ForwardTyParamBanRibKind + | ConstantItemRibKind => continue, ItemRibKind(has_generic_params) => has_generic_params, FnItemRibKind => HasGenericParams::Yes, - _ => continue, + ConstParamTyRibKind => { + if record_used { + self.report_error(span, ResolutionError::ParamInTyOfConstArg); + } + return Res::Err; + } }; // This was an attempt to use a const parameter outside its scope. diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs new file mode 100644 index 0000000000000..6eb13c38e021c --- /dev/null +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -0,0 +1,13 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete + +// Currently, const parameters cannot depend on other generic parameters, +// as our current implementation can't really support this. +// +// We may want to lift this restriction in the future. + +pub struct Dependent([(); N]); +//~^ ERROR: the type of const parameters must not depend on other generic parameters +//~| ERROR: cycle detected when computing type of `Dependent::X` + +fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr new file mode 100644 index 0000000000000..63416732bf4ce --- /dev/null +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr @@ -0,0 +1,31 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/const-param-type-depends-on-const-param.rs:9:52 + | +LL | pub struct Dependent([(); N]); + | ^ const parameters must have a concrete type + +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/const-param-type-depends-on-const-param.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +error[E0391]: cycle detected when computing type of `Dependent::X` + --> $DIR/const-param-type-depends-on-const-param.rs:9:44 + | +LL | pub struct Dependent([(); N]); + | ^ + | + = note: ...which again requires computing type of `Dependent::X`, completing the cycle +note: cycle used when computing type of `Dependent` + --> $DIR/const-param-type-depends-on-const-param.rs:9:1 + | +LL | pub struct Dependent([(); N]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs index 86ab8075896aa..db15ececfa436 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; struct B(PhantomData<[T; N]>); //~ ERROR const generics are unstable -//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]` +//~^ ERROR the type of const parameters must not depend on other generic parameters fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 92a7edf96bccb..a2182d9edaf3d 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -1,3 +1,9 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 + | +LL | struct B(PhantomData<[T; N]>); + | ^ const parameters must have a concrete type + error[E0658]: const generics are unstable --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19 | @@ -7,15 +13,6 @@ LL | struct B(PhantomData<[T; N]>); = note: see issue #44580 for more information = help: add `#![feature(const_generics)]` to the crate attributes to enable -error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter - --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 - | -LL | struct B(PhantomData<[T; N]>); - | ^ `T` may not derive both `PartialEq` and `Eq` - | - = note: it is not currently possible to use a type parameter as the type of a const parameter - error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0741. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs index 654e36df37e98..7fe04a43412a1 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.rs @@ -1,12 +1,13 @@ #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete -// Currently, const parameters cannot depend on type parameters, because there is no way to -// enforce the structural-match property on an arbitrary type parameter. This restriction -// may be relaxed in the future. See https://github.com/rust-lang/rfcs/pull/2000 for more -// details. +// Currently, const parameters cannot depend on other generic parameters, +// as our current implementation can't really support this. +// +// We may want to lift this restriction in the future. pub struct Dependent([(); X]); -//~^ ERROR `T` is not guaranteed to `#[derive(PartialEq, Eq)]` +//~^ ERROR: the type of const parameters must not depend on other generic parameters +//~| ERROR: parameter `T` is never used fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index ed05264161e53..606bb4f4fe7e0 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -1,3 +1,9 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/const-param-type-depends-on-type-param.rs:9:34 + | +LL | pub struct Dependent([(); X]); + | ^ const parameters must have a concrete type + warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/const-param-type-depends-on-type-param.rs:1:12 | @@ -7,14 +13,14 @@ LL | #![feature(const_generics)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information -error[E0741]: `T` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be used as the type of a const parameter - --> $DIR/const-param-type-depends-on-type-param.rs:9:34 +error[E0392]: parameter `T` is never used + --> $DIR/const-param-type-depends-on-type-param.rs:9:22 | LL | pub struct Dependent([(); X]); - | ^ `T` may not derive both `PartialEq` and `Eq` + | ^ unused parameter | - = note: it is not currently possible to use a type parameter as the type of a const parameter + = help: consider removing `T`, referring to it in a field, or using a marker such as `std::marker::PhantomData` -error: aborting due to previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0741`. +For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/const-generics/issues/issue-71381.rs b/src/test/ui/const-generics/issues/issue-71381.rs index c32bd2847f837..08f9482394218 100644 --- a/src/test/ui/const-generics/issues/issue-71381.rs +++ b/src/test/ui/const-generics/issues/issue-71381.rs @@ -12,6 +12,7 @@ unsafe extern "C" fn pass(args: PassArg) { impl Test { pub fn call_me(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden + //~| ERROR: the type of const parameters must not depend on other generic parameters self.0 = Self::trampiline:: as _ } @@ -20,6 +21,7 @@ impl Test { const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden + //~| ERROR: the type of const parameters must not depend on other generic parameters >( args: Args, ) { diff --git a/src/test/ui/const-generics/issues/issue-71381.stderr b/src/test/ui/const-generics/issues/issue-71381.stderr index 6bb776fcfc017..177a2cdf14c32 100644 --- a/src/test/ui/const-generics/issues/issue-71381.stderr +++ b/src/test/ui/const-generics/issues/issue-71381.stderr @@ -1,3 +1,15 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71381.rs:13:82 + | +LL | pub fn call_me(&self) { + | ^^^^ const parameters must have a concrete type + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71381.rs:22:40 + | +LL | const FN: unsafe extern "C" fn(Args), + | ^^^^ const parameters must have a concrete type + error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71381.rs:13:61 | @@ -5,10 +17,10 @@ LL | pub fn call_me $DIR/issue-71381.rs:21:19 + --> $DIR/issue-71381.rs:22:19 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/const-generics/issues/issue-71611.rs b/src/test/ui/const-generics/issues/issue-71611.rs index 64a049e743faf..06ff38dec66c7 100644 --- a/src/test/ui/const-generics/issues/issue-71611.rs +++ b/src/test/ui/const-generics/issues/issue-71611.rs @@ -3,6 +3,7 @@ fn func(outer: A) { //~^ ERROR: using function pointers as const generic parameters is forbidden + //~| ERROR: the type of const parameters must not depend on other generic parameters F(outer); } diff --git a/src/test/ui/const-generics/issues/issue-71611.stderr b/src/test/ui/const-generics/issues/issue-71611.stderr index 9a7bf1c0a8841..fe8978b42988e 100644 --- a/src/test/ui/const-generics/issues/issue-71611.stderr +++ b/src/test/ui/const-generics/issues/issue-71611.stderr @@ -1,8 +1,14 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71611.rs:4:31 + | +LL | fn func(outer: A) { + | ^ const parameters must have a concrete type + error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71611.rs:4:21 | LL | fn func(outer: A) { | ^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors From 14a1031ec6cc4c8a0475e92a4c6ddcd75108e0ee Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 8 Jul 2020 22:25:22 +0200 Subject: [PATCH 2/8] add self dependent const param test --- ...const-param-type-depends-on-const-param.rs | 4 ++++ ...t-param-type-depends-on-const-param.stderr | 21 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs index 6eb13c38e021c..9aae73ca4b098 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -10,4 +10,8 @@ pub struct Dependent([(); N]); //~^ ERROR: the type of const parameters must not depend on other generic parameters //~| ERROR: cycle detected when computing type of `Dependent::X` +pub struct SelfDependent; +//~^ ERROR: the type of const parameters must not depend on other generic parameters +//~| ERROR: cycle detected when computing type of `SelfDependent::N` + fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr index 63416732bf4ce..22e55975dcdd8 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr @@ -4,6 +4,12 @@ error[E0770]: the type of const parameters must not depend on other generic para LL | pub struct Dependent([(); N]); | ^ const parameters must have a concrete type +error[E0769]: the type of const parameters must not depend on other generic parameters + --> $DIR/const-param-type-depends-on-const-param.rs:13:40 + | +LL | pub struct SelfDependent; + | ^ const parameters must have a concrete type + warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/const-param-type-depends-on-const-param.rs:1:12 | @@ -26,6 +32,19 @@ note: cycle used when computing type of `Dependent` LL | pub struct Dependent([(); N]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error[E0391]: cycle detected when computing type of `SelfDependent::N` + --> $DIR/const-param-type-depends-on-const-param.rs:13:32 + | +LL | pub struct SelfDependent; + | ^ + | + = note: ...which again requires computing type of `SelfDependent::N`, completing the cycle +note: cycle used when computing type of `SelfDependent` + --> $DIR/const-param-type-depends-on-const-param.rs:13:1 + | +LL | pub struct SelfDependent; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0391`. From 3f558402431f4ce033fb472bdd9cc10bd92fa73a Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 9 Jul 2020 22:18:22 +0200 Subject: [PATCH 3/8] relax Node lt bounds --- src/librustc_hir/hir.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 07b489a756267..9204f778a24b9 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2687,7 +2687,7 @@ pub enum Node<'hir> { Crate(&'hir CrateItem<'hir>), } -impl Node<'_> { +impl<'hir> Node<'hir> { pub fn ident(&self) -> Option { match self { Node::TraitItem(TraitItem { ident, .. }) @@ -2698,7 +2698,7 @@ impl Node<'_> { } } - pub fn fn_decl(&self) -> Option<&FnDecl<'_>> { + pub fn fn_decl(&self) -> Option<&FnDecl<'hir>> { match self { Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(fn_sig, _), .. }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(fn_sig, _), .. }) @@ -2722,7 +2722,7 @@ impl Node<'_> { } } - pub fn generics(&self) -> Option<&Generics<'_>> { + pub fn generics(&self) -> Option<&'hir Generics<'hir>> { match self { Node::TraitItem(TraitItem { generics, .. }) | Node::ImplItem(ImplItem { generics, .. }) => Some(generics), From 6f5d8bf5c8ec9a62d62623e59fceb8abd0996f1b Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 9 Jul 2020 22:26:49 +0200 Subject: [PATCH 4/8] don't supply generics to AnonConsts in param lists --- src/librustc_typeck/collect.rs | 61 +++++++++++++++++-- ...const-param-type-depends-on-const-param.rs | 2 - ...t-param-type-depends-on-const-param.stderr | 33 +--------- .../ui/const-generics/issues/issue-74101.rs | 9 +++ 4 files changed, 68 insertions(+), 37 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue-74101.rs diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4354996614b2a..17212187e6a01 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -29,7 +29,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::weak_lang_items; -use rustc_hir::{GenericParamKind, Node}; +use rustc_hir::{GenericParamKind, HirId, Node}; use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::hir::map::Map; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; @@ -1155,6 +1155,35 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option Visitor<'v> for AnonConstInParamListDetector { + type Map = intravisit::ErasedMap<'v>; + + fn nested_visit_map(&mut self) -> NestedVisitorMap { + NestedVisitorMap::None + } + + fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) { + let prev = self.in_param_list; + self.in_param_list = true; + intravisit::walk_generic_param(self, p); + self.in_param_list = prev; + } + + fn visit_anon_const(&mut self, c: &'v hir::AnonConst) { + if self.in_param_list && self.ct == c.hir_id { + self.found_anon_const_in_list = true; + } else { + intravisit::walk_anon_const(self, c) + } + } +} + fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { use rustc_hir::*; @@ -1176,10 +1205,32 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { let parent_id = tcx.hir().get_parent_item(hir_id); let parent_def_id = tcx.hir().local_def_id(parent_id); - // HACK(eddyb) this provides the correct generics when - // `feature(const_generics)` is enabled, so that const expressions - // used with const generics, e.g. `Foo<{N+1}>`, can work at all. - if tcx.lazy_normalization() { + let mut in_param_list = false; + for (_parent, node) in tcx.hir().parent_iter(hir_id) { + if let Some(generics) = node.generics() { + let mut visitor = AnonConstInParamListDetector { + in_param_list: false, + found_anon_const_in_list: false, + ct: hir_id, + }; + + visitor.visit_generics(generics); + in_param_list = visitor.found_anon_const_in_list; + break; + } + } + + if in_param_list { + // We do not allow generic parameters in anon consts if we are inside + // of a param list. + // + // This affects both default type bindings, e.g. `struct()]>(T, U)`, + // and the types of const parameters, e.g. `struct V();`. + None + } else if tcx.lazy_normalization() { + // HACK(eddyb) this provides the correct generics when + // `feature(const_generics)` is enabled, so that const expressions + // used with const generics, e.g. `Foo<{N+1}>`, can work at all. Some(parent_def_id.to_def_id()) } else { let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs index 9aae73ca4b098..5aa3617d1d7e0 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -8,10 +8,8 @@ pub struct Dependent([(); N]); //~^ ERROR: the type of const parameters must not depend on other generic parameters -//~| ERROR: cycle detected when computing type of `Dependent::X` pub struct SelfDependent; //~^ ERROR: the type of const parameters must not depend on other generic parameters -//~| ERROR: cycle detected when computing type of `SelfDependent::N` fn main() {} diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr index 22e55975dcdd8..a06bdea1b3ca0 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr @@ -4,8 +4,8 @@ error[E0770]: the type of const parameters must not depend on other generic para LL | pub struct Dependent([(); N]); | ^ const parameters must have a concrete type -error[E0769]: the type of const parameters must not depend on other generic parameters - --> $DIR/const-param-type-depends-on-const-param.rs:13:40 +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/const-param-type-depends-on-const-param.rs:12:40 | LL | pub struct SelfDependent; | ^ const parameters must have a concrete type @@ -19,32 +19,5 @@ LL | #![feature(const_generics)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information -error[E0391]: cycle detected when computing type of `Dependent::X` - --> $DIR/const-param-type-depends-on-const-param.rs:9:44 - | -LL | pub struct Dependent([(); N]); - | ^ - | - = note: ...which again requires computing type of `Dependent::X`, completing the cycle -note: cycle used when computing type of `Dependent` - --> $DIR/const-param-type-depends-on-const-param.rs:9:1 - | -LL | pub struct Dependent([(); N]); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0391]: cycle detected when computing type of `SelfDependent::N` - --> $DIR/const-param-type-depends-on-const-param.rs:13:32 - | -LL | pub struct SelfDependent; - | ^ - | - = note: ...which again requires computing type of `SelfDependent::N`, completing the cycle -note: cycle used when computing type of `SelfDependent` - --> $DIR/const-param-type-depends-on-const-param.rs:13:1 - | -LL | pub struct SelfDependent; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/const-generics/issues/issue-74101.rs b/src/test/ui/const-generics/issues/issue-74101.rs new file mode 100644 index 0000000000000..2f427ef3a27dc --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-74101.rs @@ -0,0 +1,9 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +fn test() {} + +struct Foo; + +fn main() {} From 0c511ab5c7fae69635ea4f296a1ffae25a22b0f0 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 16 Jul 2020 11:10:22 +0200 Subject: [PATCH 5/8] update help message --- src/librustc_resolve/diagnostics.rs | 7 +++++-- src/librustc_resolve/lib.rs | 14 ++++++++++---- .../const-param-type-depends-on-const-param.stderr | 4 ++-- ...param-type-depends-on-type-param-ungated.stderr | 2 +- .../const-param-type-depends-on-type-param.stderr | 2 +- .../ui/const-generics/issues/issue-71381.stderr | 4 ++-- .../ui/const-generics/issues/issue-71611.stderr | 2 +- 7 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index c5ac7f7413ad4..575049c6bac2f 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -442,14 +442,17 @@ impl<'a> Resolver<'a> { ); err } - ResolutionError::ParamInTyOfConstArg => { + ResolutionError::ParamInTyOfConstArg(name) => { let mut err = struct_span_err!( self.session, span, E0770, "the type of const parameters must not depend on other generic parameters" ); - err.span_label(span, "const parameters must have a concrete type"); + err.span_label( + span, + format!("the type must not depend on the parameter `{}`", name), + ); err } ResolutionError::SelfInTyParamDefault => { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ba365e8f8418c..c3686ca4899bc 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -215,7 +215,7 @@ enum ResolutionError<'a> { /// Error E0128: type parameters with a default cannot use forward-declared identifiers. ForwardDeclaredTyParam, // FIXME(const_generics:defaults) /// ERROR E0770: the type of const parameters must not depend on other generic parameters. - ParamInTyOfConstArg, + ParamInTyOfConstArg(Symbol), /// Error E0735: type parameters with a default cannot use `Self` SelfInTyParamDefault, /// Error E0767: use of unreachable label @@ -2484,7 +2484,7 @@ impl<'a> Resolver<'a> { } ConstParamTyRibKind => { if record_used { - self.report_error(span, ParamInTyOfConstArg); + self.report_error(span, ParamInTyOfConstArg(rib_ident.name)); } return Res::Err; } @@ -2513,7 +2513,10 @@ impl<'a> Resolver<'a> { FnItemRibKind => HasGenericParams::Yes, ConstParamTyRibKind => { if record_used { - self.report_error(span, ResolutionError::ParamInTyOfConstArg); + self.report_error( + span, + ResolutionError::ParamInTyOfConstArg(rib_ident.name), + ); } return Res::Err; } @@ -2552,7 +2555,10 @@ impl<'a> Resolver<'a> { FnItemRibKind => HasGenericParams::Yes, ConstParamTyRibKind => { if record_used { - self.report_error(span, ResolutionError::ParamInTyOfConstArg); + self.report_error( + span, + ResolutionError::ParamInTyOfConstArg(rib_ident.name), + ); } return Res::Err; } diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr index a06bdea1b3ca0..ece31b5fab200 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr @@ -2,13 +2,13 @@ error[E0770]: the type of const parameters must not depend on other generic para --> $DIR/const-param-type-depends-on-const-param.rs:9:52 | LL | pub struct Dependent([(); N]); - | ^ const parameters must have a concrete type + | ^ the type must not depend on the parameter `N` error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/const-param-type-depends-on-const-param.rs:12:40 | LL | pub struct SelfDependent; - | ^ const parameters must have a concrete type + | ^ the type must not depend on the parameter `N` warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/const-param-type-depends-on-const-param.rs:1:12 diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index a2182d9edaf3d..7a2ee689c3318 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -2,7 +2,7 @@ error[E0770]: the type of const parameters must not depend on other generic para --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:22 | LL | struct B(PhantomData<[T; N]>); - | ^ const parameters must have a concrete type + | ^ the type must not depend on the parameter `T` error[E0658]: const generics are unstable --> $DIR/const-param-type-depends-on-type-param-ungated.rs:3:19 diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index 606bb4f4fe7e0..fa566b5536fee 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -2,7 +2,7 @@ error[E0770]: the type of const parameters must not depend on other generic para --> $DIR/const-param-type-depends-on-type-param.rs:9:34 | LL | pub struct Dependent([(); X]); - | ^ const parameters must have a concrete type + | ^ the type must not depend on the parameter `T` warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/const-param-type-depends-on-type-param.rs:1:12 diff --git a/src/test/ui/const-generics/issues/issue-71381.stderr b/src/test/ui/const-generics/issues/issue-71381.stderr index 177a2cdf14c32..fe6d5125223dc 100644 --- a/src/test/ui/const-generics/issues/issue-71381.stderr +++ b/src/test/ui/const-generics/issues/issue-71381.stderr @@ -2,13 +2,13 @@ error[E0770]: the type of const parameters must not depend on other generic para --> $DIR/issue-71381.rs:13:82 | LL | pub fn call_me(&self) { - | ^^^^ const parameters must have a concrete type + | ^^^^ the type must not depend on the parameter `Args` error[E0770]: the type of const parameters must not depend on other generic parameters --> $DIR/issue-71381.rs:22:40 | LL | const FN: unsafe extern "C" fn(Args), - | ^^^^ const parameters must have a concrete type + | ^^^^ the type must not depend on the parameter `Args` error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71381.rs:13:61 diff --git a/src/test/ui/const-generics/issues/issue-71611.stderr b/src/test/ui/const-generics/issues/issue-71611.stderr index fe8978b42988e..a8363cdff78d5 100644 --- a/src/test/ui/const-generics/issues/issue-71611.stderr +++ b/src/test/ui/const-generics/issues/issue-71611.stderr @@ -2,7 +2,7 @@ error[E0770]: the type of const parameters must not depend on other generic para --> $DIR/issue-71611.rs:4:31 | LL | fn func(outer: A) { - | ^ const parameters must have a concrete type + | ^ the type must not depend on the parameter `A` error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71611.rs:4:21 From 01f5dd374cb1762d722ed3537779377a74774cf1 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 16 Jul 2020 11:40:26 +0200 Subject: [PATCH 6/8] bless ui tests --- .../const-param-type-depends-on-const-param.stderr | 1 + .../const-param-type-depends-on-type-param-ungated.stderr | 3 ++- .../const-param-type-depends-on-type-param.stderr | 3 ++- src/test/ui/const-generics/issues/issue-71381.stderr | 1 + src/test/ui/const-generics/issues/issue-71611.stderr | 1 + 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr index ece31b5fab200..f6606aea726ad 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-const-param.stderr @@ -21,3 +21,4 @@ LL | #![feature(const_generics)] error: aborting due to 2 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0770`. diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 7a2ee689c3318..35996e833610d 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -15,4 +15,5 @@ LL | struct B(PhantomData<[T; N]>); error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0658, E0770. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr index fa566b5536fee..d081dcbbc7a4e 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param.stderr @@ -23,4 +23,5 @@ LL | pub struct Dependent([(); X]); error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0392`. +Some errors have detailed explanations: E0392, E0770. +For more information about an error, try `rustc --explain E0392`. diff --git a/src/test/ui/const-generics/issues/issue-71381.stderr b/src/test/ui/const-generics/issues/issue-71381.stderr index fe6d5125223dc..fd4ebe3dead81 100644 --- a/src/test/ui/const-generics/issues/issue-71381.stderr +++ b/src/test/ui/const-generics/issues/issue-71381.stderr @@ -24,3 +24,4 @@ LL | const FN: unsafe extern "C" fn(Args), error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0770`. diff --git a/src/test/ui/const-generics/issues/issue-71611.stderr b/src/test/ui/const-generics/issues/issue-71611.stderr index a8363cdff78d5..e2c9f22361ebe 100644 --- a/src/test/ui/const-generics/issues/issue-71611.stderr +++ b/src/test/ui/const-generics/issues/issue-71611.stderr @@ -12,3 +12,4 @@ LL | fn func(outer: A) { error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0770`. From f52039d5e82df9bf8cfbe7ed1ec337c3e426acee Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 16 Jul 2020 12:14:03 +0200 Subject: [PATCH 7/8] add regression test for #71169 --- .../ui/const-generics/issues/issue-71169.rs | 10 ++++++++++ .../ui/const-generics/issues/issue-71169.stderr | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-71169.rs create mode 100644 src/test/ui/const-generics/issues/issue-71169.stderr diff --git a/src/test/ui/const-generics/issues/issue-71169.rs b/src/test/ui/const-generics/issues/issue-71169.rs new file mode 100644 index 0000000000000..943a16cfcd6a7 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-71169.rs @@ -0,0 +1,10 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +fn foo() {} +//~^ ERROR the type of const parameters must not +fn main() { + const DATA: [u8; 4] = *b"ABCD"; + foo::<4, DATA>(); + //~^ ERROR constant expression depends on +} diff --git a/src/test/ui/const-generics/issues/issue-71169.stderr b/src/test/ui/const-generics/issues/issue-71169.stderr new file mode 100644 index 0000000000000..6d4cf4027c146 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-71169.stderr @@ -0,0 +1,17 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-71169.rs:4:43 + | +LL | fn foo() {} + | ^^^ the type must not depend on the parameter `LEN` + +error: constant expression depends on a generic parameter + --> $DIR/issue-71169.rs:8:14 + | +LL | foo::<4, DATA>(); + | ^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0770`. From 09ba0bda2caa448d381b952d2b52df1782c44966 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 16 Jul 2020 12:35:23 +0200 Subject: [PATCH 8/8] add regression test for #73491 --- src/test/ui/const-generics/issues/issue-73491.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-73491.rs diff --git a/src/test/ui/const-generics/issues/issue-73491.rs b/src/test/ui/const-generics/issues/issue-73491.rs new file mode 100644 index 0000000000000..05e1513bb75df --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-73491.rs @@ -0,0 +1,9 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +const LEN: usize = 1024; + +fn hoge() {} + +fn main() {}