Skip to content

Commit 801463c

Browse files
committed
Use regular type equating instead of a custom query
1 parent 4278d48 commit 801463c

File tree

9 files changed

+50
-66
lines changed

9 files changed

+50
-66
lines changed

compiler/rustc_infer/src/infer/relate/combine.rs

+7-29
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ use super::glb::Glb;
2222
use super::lub::Lub;
2323
use super::type_relating::TypeRelating;
2424
use super::StructurallyRelateAliases;
25-
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
25+
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TypeTrace};
2626
use crate::traits::{Obligation, PredicateObligations};
2727
use rustc_middle::bug;
28-
use rustc_middle::infer::canonical::OriginalQueryValues;
2928
use rustc_middle::infer::unify_key::EffectVarValue;
29+
use rustc_middle::traits::ObligationCause;
3030
use rustc_middle::ty::error::{ExpectedFound, TypeError};
3131
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
3232
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
@@ -159,34 +159,12 @@ impl<'tcx> InferCtxt<'tcx> {
159159
let a = self.shallow_resolve_const(a);
160160
let b = self.shallow_resolve_const(b);
161161

162-
// We should never have to relate the `ty` field on `Const` as it is checked elsewhere that consts have the
163-
// correct type for the generic param they are an argument for. However there have been a number of cases
164-
// historically where asserting that the types are equal has found bugs in the compiler so this is valuable
165-
// to check even if it is a bit nasty impl wise :(
166-
//
167-
// This probe is probably not strictly necessary but it seems better to be safe and not accidentally find
168-
// ourselves with a check to find bugs being required for code to compile because it made inference progress.
169-
self.probe(|_| {
170-
if a.ty() == b.ty() {
171-
return Ok(());
172-
}
162+
// It is always an error if the types of two constants that are related are not equal.
163+
let InferOk { value: (), obligations } = self
164+
.at(&ObligationCause::dummy_with_span(relation.span()), relation.param_env())
165+
.eq(DefineOpaqueTypes::No, a.ty(), b.ty())?;
166+
relation.register_obligations(obligations);
173167

174-
// We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
175-
// two const param's types are able to be equal has to go through a canonical query with the actual logic
176-
// in `rustc_trait_selection`.
177-
let canonical = self.canonicalize_query(
178-
relation.param_env().and((a.ty(), b.ty())),
179-
&mut OriginalQueryValues::default(),
180-
);
181-
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
182-
// The error will only be reported later. If we emit an ErrorGuaranteed
183-
// here, then we will never get to the code that actually emits the error.
184-
self.tcx.dcx().delayed_bug(format!(
185-
"cannot relate consts of different types (a={a:?}, b={b:?})",
186-
));
187-
TypeError::Mismatch
188-
})
189-
})?;
190168
match (a.kind(), b.kind()) {
191169
(
192170
ty::ConstKind::Infer(InferConst::Var(a_vid)),

compiler/rustc_middle/src/query/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -2209,15 +2209,6 @@ rustc_queries! {
22092209
separate_provide_extern
22102210
}
22112211

2212-
/// Used in `super_combine_consts` to ICE if the type of the two consts are definitely not going to end up being
2213-
/// equal to eachother. This might return `Ok` even if the types are not equal, but will never return `Err` if
2214-
/// the types might be equal.
2215-
query check_tys_might_be_eq(
2216-
arg: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>
2217-
) -> Result<(), NoSolution> {
2218-
desc { "check whether two const param are definitely not equal to eachother"}
2219-
}
2220-
22212212
/// Get all item paths that were stripped by a `#[cfg]` in a particular crate.
22222213
/// Should not be called for the local crate before the resolver outputs are created, as it
22232214
/// is only fed there.

compiler/rustc_trait_selection/src/traits/misc.rs

+1-20
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
//! Miscellaneous type-system utilities that are too small to deserve their own modules.
22
33
use crate::regions::InferCtxtRegionExt;
4-
use crate::traits::{self, ObligationCause, ObligationCtxt};
4+
use crate::traits::{self, ObligationCause};
55

66
use hir::LangItem;
77
use rustc_data_structures::fx::FxIndexSet;
88
use rustc_hir as hir;
9-
use rustc_infer::infer::canonical::Canonical;
109
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
11-
use rustc_infer::traits::query::NoSolution;
1210
use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError};
1311
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt};
14-
use rustc_span::DUMMY_SP;
1512

1613
use super::outlives_bounds::InferCtxtExt;
1714

@@ -207,19 +204,3 @@ pub fn all_fields_implement_trait<'tcx>(
207204

208205
if infringing.is_empty() { Ok(()) } else { Err(infringing) }
209206
}
210-
211-
pub fn check_tys_might_be_eq<'tcx>(
212-
tcx: TyCtxt<'tcx>,
213-
canonical: Canonical<'tcx, ty::ParamEnvAnd<'tcx, (Ty<'tcx>, Ty<'tcx>)>>,
214-
) -> Result<(), NoSolution> {
215-
let (infcx, key, _) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical);
216-
let (param_env, (ty_a, ty_b)) = key.into_parts();
217-
let ocx = ObligationCtxt::new(&infcx);
218-
219-
let result = ocx.eq(&ObligationCause::dummy(), param_env, ty_a, ty_b);
220-
// use `select_where_possible` instead of `select_all_or_error` so that
221-
// we don't get errors from obligations being ambiguous.
222-
let errors = ocx.select_where_possible();
223-
224-
if errors.len() > 0 || result.is_err() { Err(NoSolution) } else { Ok(()) }
225-
}

compiler/rustc_trait_selection/src/traits/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,6 @@ pub fn provide(providers: &mut Providers) {
551551
specialization_graph_of: specialize::specialization_graph_provider,
552552
specializes: specialize::specializes,
553553
instantiate_and_check_impossible_predicates,
554-
check_tys_might_be_eq: misc::check_tys_might_be_eq,
555554
is_impossible_associated_item,
556555
..*providers
557556
};

tests/crashes/119381.rs

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! This test used to ICE (#119381), because relating the `u8` and `i8` generic
2+
//! const with the array length of the `Self` type was succeeding under the
3+
//! assumption that an error had already been reported.
4+
5+
#![feature(with_negative_coherence)]
6+
trait Trait {}
7+
impl<const N: u8> Trait for [(); N] {}
8+
//~^ ERROR: mismatched types
9+
impl<const N: i8> Trait for [(); N] {}
10+
//~^ ERROR: mismatched types
11+
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/generic_const_type_mismatch.rs:7:34
3+
|
4+
LL | impl<const N: u8> Trait for [(); N] {}
5+
| ^ expected `usize`, found `u8`
6+
7+
error[E0308]: mismatched types
8+
--> $DIR/generic_const_type_mismatch.rs:9:34
9+
|
10+
LL | impl<const N: i8> Trait for [(); N] {}
11+
| ^ expected `usize`, found `i8`
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0308`.

tests/ui/const-generics/issues/issue-105821.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
//@ check-pass
1+
//@ failure-status: 101
2+
//@ known-bug: unknown
3+
//@ normalize-stderr-test "note: .*\n\n" -> ""
4+
//@ normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> ""
5+
//@ normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
6+
//@ normalize-stderr-test "delayed at .*" -> ""
7+
//@ rustc-env:RUST_BACKTRACE=0
28

39
#![allow(incomplete_features)]
410
#![feature(adt_const_params, generic_const_exprs)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: internal compiler error: compiler/rustc_borrowck/src/universal_regions.rs:LL:CC: cannot convert `'{erased}` to a region vid
2+
3+
query stack during panic:
4+
#0 [mir_borrowck] borrow-checking `<impl at $DIR/issue-105821.rs:21:1: 23:24>::R`
5+
#1 [analysis] running analysis passes on this crate
6+
end of query stack
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)