diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 43fea82608ef4..a327951b3b0dd 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1170,14 +1170,28 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { } // FIXME(#43408) enable this always when we get lazy normalization. Node::AnonConst(_) => { + 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.features().const_generics { - let parent_id = tcx.hir().get_parent_item(hir_id); - Some(tcx.hir().local_def_id(parent_id)) + Some(parent_def_id) } else { - None + let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); + match parent_node { + // HACK(eddyb) this provides the correct generics for repeat + // expressions' count (i.e. `N` in `[x; N]`), as they shouldn't + // be able to cause query cycle errors. + Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) + if constant.hir_id == hir_id => + { + Some(parent_def_id) + } + + _ => None, + } } } Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => { diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs index f1f82caf7d40b..8fe79b97d9ba2 100644 --- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs +++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs @@ -14,7 +14,7 @@ impl Foo for Def { pub fn test() { let _array = [4; ::Y]; - //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277] + //~^ ERROR constant expression depends on a generic parameter } fn main() { diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr index 946a1f1a07abd..0bc019b2dc875 100644 --- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr +++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr @@ -1,17 +1,10 @@ -error[E0277]: the trait bound `A: Foo` is not satisfied +error: constant expression depends on a generic parameter --> $DIR/associated-const-type-parameter-arrays-2.rs:16:22 | -LL | const Y: usize; - | --------------- required by `Foo::Y` -... LL | let _array = [4; ::Y]; - | ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A` + | ^^^^^^^^^^^^^ | -help: consider further restricting this bound - | -LL | pub fn test() { - | ^^^^^ + = note: this may fail depending on what value the parameter takes error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/too_generic_eval_ice.rs b/src/test/ui/consts/too_generic_eval_ice.rs index 7e4d4dbe44610..3ea5f88f07d1e 100644 --- a/src/test/ui/consts/too_generic_eval_ice.rs +++ b/src/test/ui/consts/too_generic_eval_ice.rs @@ -4,10 +4,9 @@ impl Foo { const HOST_SIZE: usize = std::mem::size_of::(); pub fn crash() -> bool { - [5; Self::HOST_SIZE] == [6; 0] //~ ERROR no associated item named `HOST_SIZE` - //~^ the size for values of type `A` cannot be known - //~| the size for values of type `B` cannot be known - //~| binary operation `==` cannot be applied to type `[{integer}; _]` + [5; Self::HOST_SIZE] == [6; 0] + //~^ ERROR constant expression depends on a generic parameter + //~| ERROR binary operation `==` cannot be applied to type `[{integer}; _]` } } diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr index 8b57d23751660..8b29c533bcc93 100644 --- a/src/test/ui/consts/too_generic_eval_ice.stderr +++ b/src/test/ui/consts/too_generic_eval_ice.stderr @@ -1,45 +1,10 @@ -error[E0599]: no associated item named `HOST_SIZE` found for struct `Foo` in the current scope - --> $DIR/too_generic_eval_ice.rs:7:19 - | -LL | pub struct Foo(A, B); - | --------------------------- associated item `HOST_SIZE` not found for this -... -LL | [5; Self::HOST_SIZE] == [6; 0] - | ^^^^^^^^^ associated item not found in `Foo` - | - = note: the method `HOST_SIZE` exists but the following trait bounds were not satisfied: - `A: std::marker::Sized` - `B: std::marker::Sized` - -error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/too_generic_eval_ice.rs:7:13 - | -LL | pub struct Foo(A, B); - | - required by this bound in `Foo` -LL | -LL | impl Foo { - | - this type parameter needs to be `std::marker::Sized` -... -LL | [5; Self::HOST_SIZE] == [6; 0] - | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `std::marker::Sized` is not implemented for `A` - = note: to learn more, visit - -error[E0277]: the size for values of type `B` cannot be known at compilation time +error: constant expression depends on a generic parameter --> $DIR/too_generic_eval_ice.rs:7:13 | -LL | pub struct Foo(A, B); - | - required by this bound in `Foo` -LL | -LL | impl Foo { - | - this type parameter needs to be `std::marker::Sized` -... LL | [5; Self::HOST_SIZE] == [6; 0] - | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^ | - = help: the trait `std::marker::Sized` is not implemented for `B` - = note: to learn more, visit + = note: this may fail depending on what value the parameter takes error[E0369]: binary operation `==` cannot be applied to type `[{integer}; _]` --> $DIR/too_generic_eval_ice.rs:7:30 @@ -49,7 +14,6 @@ LL | [5; Self::HOST_SIZE] == [6; 0] | | | [{integer}; _] -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0369, E0599. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issues/issue-39211.rs b/src/test/ui/issues/issue-39211.rs index db101ae248cb6..c7b6f1d58f33d 100644 --- a/src/test/ui/issues/issue-39211.rs +++ b/src/test/ui/issues/issue-39211.rs @@ -8,7 +8,8 @@ trait Mat { } fn m() { - let a = [3; M::Row::DIM]; //~ ERROR associated type `Row` not found for `M` + let a = [3; M::Row::DIM]; + //~^ ERROR constant expression depends on a generic parameter } fn main() { } diff --git a/src/test/ui/issues/issue-39211.stderr b/src/test/ui/issues/issue-39211.stderr index c14c663e5a1a9..c555983ea68e0 100644 --- a/src/test/ui/issues/issue-39211.stderr +++ b/src/test/ui/issues/issue-39211.stderr @@ -1,9 +1,10 @@ -error[E0220]: associated type `Row` not found for `M` - --> $DIR/issue-39211.rs:11:20 +error: constant expression depends on a generic parameter + --> $DIR/issue-39211.rs:11:17 | LL | let a = [3; M::Row::DIM]; - | ^^^ associated type `Row` not found + | ^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes error: aborting due to previous error -For more information about this error, try `rustc --explain E0220`.