diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 567f660a59383..0f4f729555649 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -217,7 +217,8 @@ where fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result, Self::Error> { let infcx = self.at.infcx; debug_assert_eq!(ct, infcx.shallow_resolve_const(ct)); - if !ct.has_aliases() { + // FIXME: `generic_const_exprs` causes query cycle problem. Same as the old solver. + if !ct.has_aliases() || infcx.tcx.features().generic_const_exprs() { return Ok(ct); } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 308d533e68991..322cfc9073b4b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -257,6 +257,7 @@ fn do_normalize_predicates<'tcx>( predicates: Vec>, ) -> Result>, ErrorGuaranteed> { let span = cause.span; + let original_predicates = predicates.clone(); // FIXME. We should really... do something with these region // obligations. But this call just continues the older @@ -283,6 +284,38 @@ fn do_normalize_predicates<'tcx>( debug!("do_normalize_predicates: normalized predicates = {:?}", predicates); + // The next solver returns nothing for values that contains type error. + // And type error should cause failure later. So we skip the consistency check. + if !tcx.next_trait_solver_globally() && !predicates.references_error() { + let infcx = tcx + .infer_ctxt() + .with_next_trait_solver(true) + .ignoring_regions() + .build(TypingMode::non_body_analysis()); + for (orig_pred, pred_by_old) in original_predicates.into_iter().zip(&predicates) { + let inconsistent_pred_by_next = + match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>( + infcx.at(&cause, elaborated_env), + orig_pred, + ) { + Ok(pred_by_next) => { + if pred_by_next == *pred_by_old { + continue; + } + Some(pred_by_next) + } + Err(_) => None, + }; + tcx.dcx().span_err( + span, + format!( + "inconsistency during normalizing env `{:#?}`, old={:#?}, next={:#?}", + orig_pred, pred_by_old, inconsistent_pred_by_next + ), + ); + } + } + // We can use the `elaborated_env` here; the region code only // cares about declarations like `'a: 'b`. // FIXME: It's very weird that we ignore region obligations but apparently diff --git a/tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs b/tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs index 77998c7ec0a14..e649598658f3d 100644 --- a/tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs +++ b/tests/ui/const-generics/generic_const_exprs/cross-crate-2.rs @@ -1,6 +1,8 @@ -//@ check-pass //@ aux-build: cross-crate-2.rs +//~? ERROR: inconsistency during normalizing env +//~? ERROR: inconsistency during normalizing env + extern crate cross_crate_2; use cross_crate_2::Foo; diff --git a/tests/ui/const-generics/generic_const_exprs/cross-crate-2.stderr b/tests/ui/const-generics/generic_const_exprs/cross-crate-2.stderr new file mode 100644 index 0000000000000..f5f12ca10437e --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/cross-crate-2.stderr @@ -0,0 +1,18 @@ +error: inconsistency during normalizing env `Binder { value: ConstEvaluatable(UnevaluatedConst { def: DefId(20:8 ~ cross_crate_2[bdab]::{impl#0}::{constant#0}), args: [N/#0] }), bound_vars: [] }`, old=Binder { value: ConstEvaluatable(UnevaluatedConst { def: DefId(20:8 ~ cross_crate_2[bdab]::{impl#0}::{constant#0}), args: [N/#0] }), bound_vars: [] }, next=Some( + Binder { value: ConstEvaluatable({const error}), bound_vars: [] }, + ) + --> $DIR/auxiliary/cross-crate-2.rs:10:5 + | +LL | pub fn new() -> Self { + | ^^^^^^^^^^^^^^^^^^^^ + +error: inconsistency during normalizing env `Binder { value: TraitPredicate(<[u8; cross_crate_2::::{impl#0}::{constant#0}] as std::marker::Sized>, polarity:Positive), bound_vars: [] }`, old=Binder { value: TraitPredicate(<[u8; cross_crate_2::::{impl#0}::{constant#0}] as std::marker::Sized>, polarity:Positive), bound_vars: [] }, next=Some( + Binder { value: TraitPredicate(<[u8; {const error}] as std::marker::Sized>, polarity:Positive), bound_vars: [] }, + ) + --> $DIR/auxiliary/cross-crate-2.rs:10:5 + | +LL | pub fn new() -> Self { + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs index 81ac9979bd8c7..2432d0e416f2d 100644 --- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs +++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs @@ -10,5 +10,6 @@ trait Trait {} impl Trait for A {} impl Trait for A {} +//~^ ERROR: conflicting implementations of trait pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr index e29c49ff0422c..80ac96d487000 100644 --- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr @@ -4,6 +4,16 @@ error[E0423]: expected value, found builtin type `u8` LL | struct A; | ^^ not a value -error: aborting due to 1 previous error +error[E0119]: conflicting implementations of trait `Trait` for type `A<_>` + --> $DIR/unknown-alias-defkind-anonconst-ice-116710.rs:12:1 + | +LL | impl Trait for A {} + | --------------------------------- first implementation here +LL | +LL | impl Trait for A {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A<_>` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0423`. +Some errors have detailed explanations: E0119, E0423. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr index 1a2bc6c2c5f59..92728f6e9bfdf 100644 --- a/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr +++ b/tests/ui/traits/const-traits/unsatisfied-const-trait-bound.stderr @@ -6,94 +6,34 @@ LL | #![feature(const_trait_impl, generic_const_exprs)] | = help: remove one of these features -error[E0391]: cycle detected when evaluating type-level constant - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 +error[E0277]: the trait bound `T: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:28:37 | LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ - | -note: ...which requires const-evaluating + checking `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 - | -LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires checking if `accept0::{constant#0}` is a trivial const... - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 - | -LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires building MIR for `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 - | -LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires building an abstract representation for `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 - | -LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires building THIR for `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 - | -LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires type-checking `accept0::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 - | -LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ - = note: ...which again requires evaluating type-level constant, completing the cycle -note: cycle used when checking that `accept0` is well-formed - --> $DIR/unsatisfied-const-trait-bound.rs:28:35 - | -LL | fn accept0(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + | ^ -error[E0391]: cycle detected when checking if `accept1::{constant#0}` is a trivial const - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 - | -LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ - | -note: ...which requires building MIR for `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 +error[E0277]: the trait bound `T: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:32:51 | LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires building an abstract representation for `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 - | -LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires building THIR for `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 - | -LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires type-checking `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 + | ^ + +error[E0277]: the trait bound `Ty: const Trait` is not satisfied + --> $DIR/unsatisfied-const-trait-bound.rs:21:15 | -LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires evaluating type-level constant... - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 +LL | require::(); + | ^^ | -LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `accept1::{constant#0}`... - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 +note: required by a bound in `require` + --> $DIR/unsatisfied-const-trait-bound.rs:8:15 | -LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ - = note: ...which again requires checking if `accept1::{constant#0}` is a trivial const, completing the cycle -note: cycle used when const-evaluating + checking `accept1::{constant#0}` - --> $DIR/unsatisfied-const-trait-bound.rs:32:49 +LL | fn require() {} + | ^^^^^^^^^^^ required by this bound in `require` +help: make the `impl` of trait `Trait` `const` | -LL | const fn accept1(_: Container<{ T::make() }>) {} - | ^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +LL | impl const Trait for Ty { + | +++++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0391`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.current.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.current.stderr new file mode 100644 index 0000000000000..7408a1642c150 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.current.stderr @@ -0,0 +1,22 @@ +error: inconsistency during normalizing env `Binder { value: TraitPredicate(<::Assoc as Trait>, polarity:Positive), bound_vars: [] }`, old=Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }, next=None + --> $DIR/normalize-param-env-4.rs:16:1 + | +LL | / fn foo() +LL | | +LL | | +LL | | where +LL | | ::Assoc: Trait, + | |_______________________________^ + +error: inconsistency during normalizing env `Binder { value: TraitPredicate(<::Assoc as std::marker::MetaSized>, polarity:Positive), bound_vars: [] }`, old=Binder { value: TraitPredicate(, polarity:Positive), bound_vars: [] }, next=None + --> $DIR/normalize-param-env-4.rs:16:1 + | +LL | / fn foo() +LL | | +LL | | +LL | | where +LL | | ::Assoc: Trait, + | |_______________________________^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index f5fd9ce9864ce..d76a9b9726953 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr @@ -1,5 +1,5 @@ error[E0275]: overflow evaluating the requirement `::Assoc: Trait` - --> $DIR/normalize-param-env-4.rs:19:26 + --> $DIR/normalize-param-env-4.rs:20:26 | LL | ::Assoc: Trait, | ^^^^^ diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs index ed7f6899bdee6..ca9c365da37c9 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.rs @@ -2,7 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver //@[next] known-bug: #92505 -//@[current] check-pass trait Trait { type Assoc; @@ -15,6 +14,8 @@ impl Trait for T { fn impls_trait() {} fn foo() + //[current]~^ ERROR: inconsistency during normalizing env + //[current]~| ERROR: inconsistency during normalizing env where ::Assoc: Trait, {