about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-05-25 12:54:34 +0200
committerGitHub <noreply@github.com>2024-05-25 12:54:34 +0200
commit7ea507e0415deedf8ba7d477ef0fba4da9c90ae2 (patch)
tree81432fdb4244c59e4093ce8baf11169d8b22910f /compiler
parentf28d36899c1e914bd8e994c8f526da70a0ed1073 (diff)
parentd5eb7a71b3c869eb9e15f10da6eb92303b96dfb5 (diff)
downloadrust-7ea507e0415deedf8ba7d477ef0fba4da9c90ae2.tar.gz
rust-7ea507e0415deedf8ba7d477ef0fba4da9c90ae2.zip
Rollup merge of #125451 - oli-obk:const_type_mismatch, r=compiler-errors
Fail relating constants of different types

fixes #121585
fixes #121858
fixes #124151

I gave this several attempts before, but we lost too many important diagnostics until I managed to make compilation never bail out early. We have reached this point, so now we can finally fix all those ICEs by bubbling up an error instead of continueing when we encounter a bug.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs39
-rw-r--r--compiler/rustc_middle/src/query/mod.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs21
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs1
4 files changed, 8 insertions, 62 deletions
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 101598c5951..7e7d4f43c7c 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 5a6decc4f94..8ca7a465c2a 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 da2b004761f..a1094d98276 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 204bb487c86..f6003a25028 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
     };