about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-05-23 16:23:41 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-05-24 09:15:43 +0000
commitd5eb7a71b3c869eb9e15f10da6eb92303b96dfb5 (patch)
tree9f0de336061fe6a306376523eb5ce1641b5db11c
parent9dc76207ffdb225c4f4615dd59bce356b25eeab8 (diff)
downloadrust-d5eb7a71b3c869eb9e15f10da6eb92303b96dfb5.tar.gz
rust-d5eb7a71b3c869eb9e15f10da6eb92303b96dfb5.zip
Use regular type equating instead of a custom query
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs36
-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
-rw-r--r--tests/crashes/119381.rs6
-rw-r--r--tests/ui/coherence/negative-coherence/generic_const_type_mismatch.rs12
-rw-r--r--tests/ui/coherence/negative-coherence/generic_const_type_mismatch.stderr15
-rw-r--r--tests/ui/const-generics/issues/issue-105821.rs8
-rw-r--r--tests/ui/const-generics/issues/issue-105821.stderr8
9 files changed, 50 insertions, 66 deletions
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index fa5b9179c88..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,34 +159,12 @@ 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 Ok(());
-            }
+        // 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);
 
-            // 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).map_err(|_| {
-                // 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:?})",
-                ));
-                TypeError::Mismatch
-            })
-        })?;
         match (a.kind(), b.kind()) {
             (
                 ty::ConstKind::Infer(InferConst::Var(a_vid)),
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
     };
diff --git a/tests/crashes/119381.rs b/tests/crashes/119381.rs
deleted file mode 100644
index 51d1d084ba2..00000000000
--- a/tests/crashes/119381.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//@ known-bug: #119381
-
-#![feature(with_negative_coherence)]
-trait Trait {}
-impl<const N: u8> Trait for [(); N] {}
-impl<const N: i8> Trait for [(); N] {}
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 00000000000..89d0b74d403
--- /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<const N: u8> Trait for [(); N] {}
+//~^ ERROR: mismatched types
+impl<const N: i8> 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 00000000000..d1950254660
--- /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<const N: u8> Trait for [(); N] {}
+   |                                  ^ expected `usize`, found `u8`
+
+error[E0308]: mismatched types
+  --> $DIR/generic_const_type_mismatch.rs:9:34
+   |
+LL | impl<const N: i8> 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/issues/issue-105821.rs b/tests/ui/const-generics/issues/issue-105821.rs
index a0a98103b2c..282cbe9249d 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 00000000000..1f0fc0f33ce
--- /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 `<impl at $DIR/issue-105821.rs:21:1: 23:24>::R`
+#1 [analysis] running analysis passes on this crate
+end of query stack
+error: aborting due to 1 previous error
+