diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 101598c59512d..7e7d4f43c7cca 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -22,11 +22,11 @@ use super::glb::Glb; use super::lub::Lub; use super::type_relating::TypeRelating; use super::StructurallyRelateAliases; -use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; +use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::bug; -use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::EffectVarValue; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{RelateResult, TypeRelation}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast}; @@ -159,36 +159,11 @@ impl<'tcx> InferCtxt<'tcx> { let a = self.shallow_resolve_const(a); let b = self.shallow_resolve_const(b); - // We should never have to relate the `ty` field on `Const` as it is checked elsewhere that consts have the - // correct type for the generic param they are an argument for. However there have been a number of cases - // historically where asserting that the types are equal has found bugs in the compiler so this is valuable - // to check even if it is a bit nasty impl wise :( - // - // This probe is probably not strictly necessary but it seems better to be safe and not accidentally find - // ourselves with a check to find bugs being required for code to compile because it made inference progress. - self.probe(|_| { - if a.ty() == b.ty() { - return; - } - - // We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the - // two const param's types are able to be equal has to go through a canonical query with the actual logic - // in `rustc_trait_selection`. - let canonical = self.canonicalize_query( - relation.param_env().and((a.ty(), b.ty())), - &mut OriginalQueryValues::default(), - ); - self.tcx.check_tys_might_be_eq(canonical).unwrap_or_else(|_| { - // The error will only be reported later. If we emit an ErrorGuaranteed - // here, then we will never get to the code that actually emits the error. - self.tcx.dcx().delayed_bug(format!( - "cannot relate consts of different types (a={a:?}, b={b:?})", - )); - // We treat these constants as if they were of the same type, so that any - // such constants being used in impls make these impls match barring other mismatches. - // This helps with diagnostics down the road. - }); - }); + // It is always an error if the types of two constants that are related are not equal. + let InferOk { value: (), obligations } = self + .at(&ObligationCause::dummy_with_span(relation.span()), relation.param_env()) + .eq(DefineOpaqueTypes::No, a.ty(), b.ty())?; + relation.register_obligations(obligations); match (a.kind(), b.kind()) { ( diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5a6decc4f9497..8ca7a465c2a8b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2218,15 +2218,6 @@ rustc_queries! { separate_provide_extern } - /// Used in `super_combine_consts` to ICE if the type of the two consts are definitely not going to end up being - /// equal to eachother. This might return `Ok` even if the types are not equal, but will never return `Err` if - /// the types might be equal. - query check_tys_might_be_eq( - arg: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>> - ) -> Result<(), NoSolution> { - desc { "check whether two const param are definitely not equal to eachother"} - } - /// Get all item paths that were stripped by a `#[cfg]` in a particular crate. /// Should not be called for the local crate before the resolver outputs are created, as it /// is only fed there. diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index da2b004761fc3..a1094d982768b 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -1,17 +1,14 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::regions::InferCtxtRegionExt; -use crate::traits::{self, ObligationCause, ObligationCtxt}; +use crate::traits::{self, ObligationCause}; use hir::LangItem; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; -use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; -use rustc_infer::traits::query::NoSolution; use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError}; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt}; -use rustc_span::DUMMY_SP; use super::outlives_bounds::InferCtxtExt; @@ -207,19 +204,3 @@ pub fn all_fields_implement_trait<'tcx>( if infringing.is_empty() { Ok(()) } else { Err(infringing) } } - -pub fn check_tys_might_be_eq<'tcx>( - tcx: TyCtxt<'tcx>, - canonical: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>, -) -> Result<(), NoSolution> { - let (infcx, key, _) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical); - let (param_env, (ty_a, ty_b)) = key.into_parts(); - let ocx = ObligationCtxt::new(&infcx); - - let result = ocx.eq(&ObligationCause::dummy(), param_env, ty_a, ty_b); - // use `select_where_possible` instead of `select_all_or_error` so that - // we don't get errors from obligations being ambiguous. - let errors = ocx.select_where_possible(); - - if errors.len() > 0 || result.is_err() { Err(NoSolution) } else { Ok(()) } -} diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 204bb487c8608..f6003a250281b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -551,7 +551,6 @@ pub fn provide(providers: &mut Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, instantiate_and_check_impossible_predicates, - check_tys_might_be_eq: misc::check_tys_might_be_eq, is_impossible_associated_item, ..*providers }; diff --git a/tests/crashes/119381.rs b/tests/crashes/119381.rs deleted file mode 100644 index 51d1d084ba2bc..0000000000000 --- a/tests/crashes/119381.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #119381 - -#![feature(with_negative_coherence)] -trait Trait {} -impl Trait for [(); N] {} -impl Trait for [(); N] {} diff --git a/tests/crashes/121585-1.rs b/tests/crashes/121585-1.rs deleted file mode 100644 index 2a4638efcabdd..0000000000000 --- a/tests/crashes/121585-1.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #121585 -#![feature(generic_const_exprs)] - -trait Trait {} - -struct HasCastInTraitImpl; -impl Trait for HasCastInTraitImpl {} - -pub fn use_trait_impl() { - fn assert_impl() {} - - assert_impl::>(); -} diff --git a/tests/crashes/121585-2.rs b/tests/crashes/121585-2.rs deleted file mode 100644 index 99cc8f7919559..0000000000000 --- a/tests/crashes/121585-2.rs +++ /dev/null @@ -1,30 +0,0 @@ -//@ known-bug: #121585 -//@ check-pass -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] - -trait Trait {} -pub struct EvaluatableU128; - -struct HasCastInTraitImpl; -impl Trait for HasCastInTraitImpl {} - -pub fn use_trait_impl() where EvaluatableU128<{N as u128}>:, { - fn assert_impl() {} - - assert_impl::>(); - assert_impl::>(); - assert_impl::>(); - assert_impl::>(); -} -pub fn use_trait_impl_2() where EvaluatableU128<{N as _}>:, { - fn assert_impl() {} - - assert_impl::>(); - assert_impl::>(); - assert_impl::>()const NUM: u8 = xyz(); - assert_impl::>(); -} - - -fn main() {} diff --git a/tests/crashes/121858-2.rs b/tests/crashes/121858-2.rs deleted file mode 100644 index cb80c081cffa3..0000000000000 --- a/tests/crashes/121858-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: #121858 -#![allow(named_arguments_used_positionally)] -#![feature(generic_const_exprs)] -struct Inner; -impl Inner where [(); N + M]: { - fn i() -> Self { - Self - } -} - -struct Outer(Inner) where [(); A + (B * 2)]:; -impl Outer where [(); A + (B * 2)]: { - fn o() -> Union { - Self(Inner::i()) - } -} - -fn main() { - Outer::<1, 1>::o(); -} diff --git a/tests/crashes/124151.rs b/tests/crashes/124151.rs deleted file mode 100644 index 5e55ac2aa943c..0000000000000 --- a/tests/crashes/124151.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #124151 -#![feature(generic_const_exprs)] - -use std::ops::Add; - -pub struct Dimension; - -pub struct Quantity(S); - -impl Add for Quantity {} - -pub fn add(x: Quantity) -> Quantity { - x + y -} diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs new file mode 100644 index 0000000000000..89d0b74d40303 --- /dev/null +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs @@ -0,0 +1,12 @@ +//! This test used to ICE (#119381), because relating the `u8` and `i8` generic +//! const with the array length of the `Self` type was succeeding under the +//! assumption that an error had already been reported. + +#![feature(with_negative_coherence)] +trait Trait {} +impl Trait for [(); N] {} +//~^ ERROR: mismatched types +impl Trait for [(); N] {} +//~^ ERROR: mismatched types + +fn main() {} diff --git a/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr new file mode 100644 index 0000000000000..d195025466024 --- /dev/null +++ b/tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/generic_const_type_mismatch.rs:7:34 + | +LL | impl Trait for [(); N] {} + | ^ expected `usize`, found `u8` + +error[E0308]: mismatched types + --> $DIR/generic_const_type_mismatch.rs:9:34 + | +LL | impl Trait for [(); N] {} + | ^ expected `usize`, found `i8` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs index ca5522a2ddf38..88f98a54b6e6e 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.rs +++ b/tests/ui/const-generics/bad-subst-const-kind.rs @@ -11,4 +11,4 @@ impl Q for [u8; N] { } pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } -//~^ ERROR: the constant `13` is not of type `u64` +//~^ ERROR: `[u8; 13]: Q` is not satisfied diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr index c04a05573bed0..6cf9fa743b341 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.stderr +++ b/tests/ui/const-generics/bad-subst-const-kind.stderr @@ -1,16 +1,10 @@ -error: the constant `13` is not of type `u64` +error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied --> $DIR/bad-subst-const-kind.rs:13:24 | LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() } - | ^^^^^^^^ expected `u64`, found `usize` + | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` | -note: required for `[u8; 13]` to implement `Q` - --> $DIR/bad-subst-const-kind.rs:8:20 - | -LL | impl Q for [u8; N] { - | ------------ ^ ^^^^^^^ - | | - | unsatisfied trait bound introduced here + = help: the trait `Q` is implemented for `[u8; N]` error[E0308]: mismatched types --> $DIR/bad-subst-const-kind.rs:8:31 @@ -20,4 +14,5 @@ LL | impl Q for [u8; N] { error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs index 6b0d9e047dbc3..285f9dee6c27f 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs @@ -10,7 +10,7 @@ impl Q for [u8; N] {} //~| ERROR mismatched types pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} -//~^ ERROR the constant `13` is not of type `u64` +//~^ ERROR `[u8; 13]: Q` is not satisfied //~| ERROR mismatched types pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr index bb6d650b7ab27..a63a56dd67531 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr @@ -7,19 +7,13 @@ LL | const ASSOC: usize; LL | impl Q for [u8; N] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation -error: the constant `13` is not of type `u64` +error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied --> $DIR/type_mismatch.rs:12:26 | LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {} - | ^^^^^^^^ expected `u64`, found `usize` + | ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]` | -note: required for `[u8; 13]` to implement `Q` - --> $DIR/type_mismatch.rs:8:20 - | -LL | impl Q for [u8; N] {} - | ------------ ^ ^^^^^^^ - | | - | unsatisfied trait bound introduced here + = help: the trait `Q` is implemented for `[u8; N]` error[E0308]: mismatched types --> $DIR/type_mismatch.rs:12:20 @@ -37,5 +31,5 @@ LL | impl Q for [u8; N] {} error: aborting due to 4 previous errors -Some errors have detailed explanations: E0046, E0308. +Some errors have detailed explanations: E0046, E0277, E0308. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/const-generics/issues/issue-105821.rs b/tests/ui/const-generics/issues/issue-105821.rs index a0a98103b2cd2..282cbe9249d96 100644 --- a/tests/ui/const-generics/issues/issue-105821.rs +++ b/tests/ui/const-generics/issues/issue-105821.rs @@ -1,4 +1,10 @@ -//@ check-pass +//@ failure-status: 101 +//@ known-bug: unknown +//@ normalize-stderr-test "note: .*\n\n" -> "" +//@ normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> "" +//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr-test "delayed at .*" -> "" +//@ rustc-env:RUST_BACKTRACE=0 #![allow(incomplete_features)] #![feature(adt_const_params, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-105821.stderr b/tests/ui/const-generics/issues/issue-105821.stderr new file mode 100644 index 0000000000000..1f0fc0f33ce4f --- /dev/null +++ b/tests/ui/const-generics/issues/issue-105821.stderr @@ -0,0 +1,8 @@ +error: internal compiler error: compiler/rustc_borrowck/src/universal_regions.rs:LL:CC: cannot convert `'{erased}` to a region vid + +query stack during panic: +#0 [mir_borrowck] borrow-checking `::R` +#1 [analysis] running analysis passes on this crate +end of query stack +error: aborting due to 1 previous error + diff --git a/tests/crashes/121858.rs b/tests/ui/consts/eval_type_mismatch.rs similarity index 53% rename from tests/crashes/121858.rs rename to tests/ui/consts/eval_type_mismatch.rs index 7d5bae37f846b..3d821ab538ec8 100644 --- a/tests/crashes/121858.rs +++ b/tests/ui/consts/eval_type_mismatch.rs @@ -1,14 +1,17 @@ -//@ known-bug: #121858 #![feature(generic_const_exprs)] +#![allow(incomplete_features)] struct Outer(); impl Outer +//~^ ERROR: `A` is not of type `i64` +//~| ERROR: mismatched types where [(); A + (B * 2)]:, { - fn o() -> Union {} + fn o() {} } fn main() { Outer::<1, 1>::o(); + //~^ ERROR: no function or associated item named `o` found } diff --git a/tests/ui/consts/eval_type_mismatch.stderr b/tests/ui/consts/eval_type_mismatch.stderr new file mode 100644 index 0000000000000..38d6e33d40675 --- /dev/null +++ b/tests/ui/consts/eval_type_mismatch.stderr @@ -0,0 +1,34 @@ +error: the constant `A` is not of type `i64` + --> $DIR/eval_type_mismatch.rs:5:38 + | +LL | impl Outer + | ^^^^^^^^^^^ expected `i64`, found `usize` + | +note: required by a bound in `Outer` + --> $DIR/eval_type_mismatch.rs:4:14 + | +LL | struct Outer(); + | ^^^^^^^^^^^^ required by this bound in `Outer` + +error[E0599]: no function or associated item named `o` found for struct `Outer<1, 1>` in the current scope + --> $DIR/eval_type_mismatch.rs:15:20 + | +LL | struct Outer(); + | ------------------------------------------ function or associated item `o` not found for this struct +... +LL | Outer::<1, 1>::o(); + | ^ function or associated item not found in `Outer<1, 1>` + | + = note: the function or associated item was found for + - `Outer` + +error[E0308]: mismatched types + --> $DIR/eval_type_mismatch.rs:5:44 + | +LL | impl Outer + | ^ expected `i64`, found `usize` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs index f89a463bc5805..4d1cd4332fee4 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs @@ -7,7 +7,8 @@ struct S; impl Copy for S {} //~^ ERROR: mismatched types +//~| ERROR: the trait bound `S: Clone` is not satisfied +//~| ERROR: the constant `N` is not of type `usize` impl Copy for S {} -//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>` fn main() {} diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr index 1dac58e1f694e..716a47879482e 100644 --- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr @@ -1,11 +1,29 @@ -error[E0119]: conflicting implementations of trait `Copy` for type `S<_>` - --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1 +error[E0277]: the trait bound `S: Clone` is not satisfied + --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 | LL | impl Copy for S {} - | -------------------------------- first implementation here -LL | -LL | impl Copy for S {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>` + | ^^^^ the trait `Clone` is not implemented for `S` + | + = help: the trait `Clone` is implemented for `S` +note: required by a bound in `Copy` + --> $SRC_DIR/core/src/marker.rs:LL:COL +help: consider annotating `S` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct S; + | + +error: the constant `N` is not of type `usize` + --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29 + | +LL | impl Copy for S {} + | ^^^^ expected `usize`, found `i32` + | +note: required by a bound in `S` + --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10 + | +LL | struct S; + | ^^^^^^^^^^^^^^ required by this bound in `S` error[E0308]: mismatched types --> $DIR/bad-const-wf-doesnt-specialize.rs:8:31 @@ -13,7 +31,7 @@ error[E0308]: mismatched types LL | impl Copy for S {} | ^ expected `usize`, found `i32` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0119, E0308. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`.