mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #108947 - compiler-errors:ct-infer-no-shapeshifting, r=BoxyUwU
Don't even try to combine consts with incompatible types ~I left a more detailed explanation for why this fixes this issue in the UI test, but in general, we should not try to unify const infer vars and rigid consts if they have incompatible types. That's because we don't want something like a `ConstArgHasType` predicate to suddenly go from passing to failing, or vice versa, due to a shallow resolve.~ 1. Use the `type_of` for a parameter in `try_eval_lit_or_param`, instead of the "expected" type from a `WithOptConstParam` def id. 2. Don't combine consts that have incompatible types. Fixes #108781
This commit is contained in:
commit
145e6204bc
@ -34,7 +34,6 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::infer::canonical::OriginalQueryValues;
|
||||
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
|
||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
@ -171,9 +170,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
//
|
||||
// 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(|_| {
|
||||
let compatible_types = self.probe(|_| {
|
||||
if a.ty() == b.ty() {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
|
||||
@ -183,15 +182,24 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
(relation.param_env(), a.ty(), b.ty()),
|
||||
&mut OriginalQueryValues::default(),
|
||||
);
|
||||
|
||||
if let Err(NoSolution) = self.tcx.check_tys_might_be_eq(canonical) {
|
||||
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
|
||||
self.tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
&format!("cannot relate consts of different types (a={:?}, b={:?})", a, b,),
|
||||
);
|
||||
}
|
||||
)
|
||||
})
|
||||
});
|
||||
|
||||
// If the consts have differing types, just bail with a const error with
|
||||
// the expected const's type. Specifically, we don't want const infer vars
|
||||
// to do any type shapeshifting before and after resolution.
|
||||
if let Err(guar) = compatible_types {
|
||||
return Ok(self.tcx.const_error_with_guaranteed(
|
||||
if relation.a_is_expected() { a.ty() } else { b.ty() },
|
||||
guar,
|
||||
));
|
||||
}
|
||||
|
||||
match (a.kind(), b.kind()) {
|
||||
(
|
||||
ty::ConstKind::Infer(InferConst::Var(a_vid)),
|
||||
|
@ -135,6 +135,9 @@ impl<'tcx> Const<'tcx> {
|
||||
_,
|
||||
&hir::Path { res: Res::Def(DefKind::ConstParam, def_id), .. },
|
||||
)) => {
|
||||
// Use the type from the param's definition, since we can resolve it,
|
||||
// not the expected parameter type from WithOptConstParam.
|
||||
let param_ty = tcx.type_of(def_id).subst_identity();
|
||||
match tcx.named_bound_var(expr.hir_id) {
|
||||
Some(rbv::ResolvedArg::EarlyBound(_)) => {
|
||||
// Find the name and index of the const parameter by indexing the generics of
|
||||
@ -143,14 +146,14 @@ impl<'tcx> Const<'tcx> {
|
||||
let generics = tcx.generics_of(item_def_id);
|
||||
let index = generics.param_def_id_to_index[&def_id];
|
||||
let name = tcx.item_name(def_id);
|
||||
Some(tcx.mk_const(ty::ParamConst::new(index, name), ty))
|
||||
Some(tcx.mk_const(ty::ParamConst::new(index, name), param_ty))
|
||||
}
|
||||
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => Some(tcx.mk_const(
|
||||
ty::ConstKind::Bound(debruijn, ty::BoundVar::from_u32(index)),
|
||||
ty,
|
||||
param_ty,
|
||||
)),
|
||||
Some(rbv::ResolvedArg::Error(guar)) => {
|
||||
Some(tcx.const_error_with_guaranteed(ty, guar))
|
||||
Some(tcx.const_error_with_guaranteed(param_ty, guar))
|
||||
}
|
||||
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", expr.hir_id),
|
||||
}
|
||||
|
@ -99,10 +99,10 @@ pub fn translate_substs<'tcx>(
|
||||
}
|
||||
|
||||
fulfill_implication(infcx, param_env, source_trait_ref, target_impl).unwrap_or_else(
|
||||
|_| {
|
||||
|()| {
|
||||
bug!(
|
||||
"When translating substitutions for specialization, the expected \
|
||||
specialization failed to hold"
|
||||
"When translating substitutions from {source_impl:?} to {target_impl:?}, \
|
||||
the expected specialization failed to hold"
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -1,5 +1,6 @@
|
||||
fn foo<const N: usize>() -> [u8; N] {
|
||||
bar::<N>() //~ ERROR mismatched types
|
||||
//~^ ERROR the constant `N` is not of type `u8`
|
||||
}
|
||||
|
||||
fn bar<const N: u8>() -> [u8; N] {}
|
||||
|
@ -1,3 +1,15 @@
|
||||
error: the constant `N` is not of type `u8`
|
||||
--> $DIR/type_mismatch.rs:2:5
|
||||
|
|
||||
LL | bar::<N>()
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `bar`
|
||||
--> $DIR/type_mismatch.rs:6:8
|
||||
|
|
||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||
| ^^^^^^^^^^^ required by this bound in `bar`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_mismatch.rs:2:11
|
||||
|
|
||||
@ -5,7 +17,7 @@ LL | bar::<N>()
|
||||
| ^ expected `u8`, found `usize`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_mismatch.rs:5:26
|
||||
--> $DIR/type_mismatch.rs:6:26
|
||||
|
|
||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||
| --- ^^^^^^^ expected `[u8; N]`, found `()`
|
||||
@ -13,11 +25,11 @@ LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||
| implicitly returns `()` as its body has no tail or `return` expression
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_mismatch.rs:5:31
|
||||
--> $DIR/type_mismatch.rs:6:31
|
||||
|
|
||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||
| ^ expected `usize`, found `u8`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -6,6 +6,5 @@ impl X {
|
||||
}
|
||||
fn getn<const N: cfg_attr>() -> [u8; N] {}
|
||||
//~^ ERROR expected type, found built-in attribute `cfg_attr`
|
||||
//~| ERROR mismatched types
|
||||
|
||||
fn main() {}
|
||||
|
@ -10,15 +10,7 @@ error[E0573]: expected type, found built-in attribute `cfg_attr`
|
||||
LL | fn getn<const N: cfg_attr>() -> [u8; N] {}
|
||||
| ^^^^^^^^ not a type
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_not_in_scope.rs:7:33
|
||||
|
|
||||
LL | fn getn<const N: cfg_attr>() -> [u8; N] {}
|
||||
| ---- ^^^^^^^ expected `[u8; N]`, found `()`
|
||||
| |
|
||||
| implicitly returns `()` as its body has no tail or `return` expression
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0412, E0573.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
Some errors have detailed explanations: E0412, E0573.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
|
@ -0,0 +1,12 @@
|
||||
#![feature(min_specialization)]
|
||||
|
||||
// An impl that has an erroneous const substitution should not specialize one
|
||||
// that is well-formed.
|
||||
|
||||
struct S<const L: usize>;
|
||||
|
||||
impl<const N: i32> Copy for S<N> {}
|
||||
impl<const M: usize> Copy for S<M> {}
|
||||
//~^ ERROR conflicting implementations of trait `Copy` for type `S<_>`
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,11 @@
|
||||
error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
|
||||
--> $DIR/bad-const-wf-doesnt-specialize.rs:9:1
|
||||
|
|
||||
LL | impl<const N: i32> Copy for S<N> {}
|
||||
| -------------------------------- first implementation here
|
||||
LL | impl<const M: usize> Copy for S<M> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
@ -6,7 +6,7 @@ mod assert {
|
||||
pub fn is_transmutable<Src, Context, const ASSUME_ALIGNMENT: bool>()
|
||||
where
|
||||
Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope
|
||||
//~^ ERROR mismatched types
|
||||
//~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume`
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,15 @@ error[E0412]: cannot find type `Dst` in this scope
|
||||
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-101739-1.rs:8:50
|
||||
error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
|
||||
--> $DIR/issue-101739-1.rs:8:14
|
||||
|
|
||||
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
|
||||
| ^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `BikeshedIntrinsicFrom`
|
||||
--> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0412.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
For more information about this error, try `rustc --explain E0412`.
|
||||
|
Loading…
Reference in New Issue
Block a user