From 9574f39c2dc6312223fe562c1e04e4344eada316 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 Mar 2023 20:49:05 +0000 Subject: [PATCH 1/2] Use param's real type in try_eval_lit_or_param --- compiler/rustc_middle/src/ty/consts.rs | 9 ++++++--- .../src/traits/specialize/mod.rs | 6 +++--- tests/ui/const-generics/type_mismatch.rs | 1 + tests/ui/const-generics/type_mismatch.stderr | 18 +++++++++++++++--- tests/ui/const-generics/type_not_in_scope.rs | 1 - .../ui/const-generics/type_not_in_scope.stderr | 14 +++----------- .../bad-const-wf-doesnt-specialize.rs | 12 ++++++++++++ .../bad-const-wf-doesnt-specialize.stderr | 11 +++++++++++ tests/ui/transmutability/issue-101739-1.rs | 2 +- tests/ui/transmutability/issue-101739-1.stderr | 12 +++++++----- 10 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs create mode 100644 tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 5d0cf23280b..42101f6b931 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -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), } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index d1d6a7a90cf..fcfb60b2603 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -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" ) }, ) diff --git a/tests/ui/const-generics/type_mismatch.rs b/tests/ui/const-generics/type_mismatch.rs index 4a7534e3713..daa13277be0 100644 --- a/tests/ui/const-generics/type_mismatch.rs +++ b/tests/ui/const-generics/type_mismatch.rs @@ -1,5 +1,6 @@ fn foo() -> [u8; N] { bar::() //~ ERROR mismatched types + //~^ ERROR the constant `N` is not of type `u8` } fn bar() -> [u8; N] {} diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr index b28ae8f7e71..6d8955e411e 100644 --- a/tests/ui/const-generics/type_mismatch.stderr +++ b/tests/ui/const-generics/type_mismatch.stderr @@ -1,3 +1,15 @@ +error: the constant `N` is not of type `u8` + --> $DIR/type_mismatch.rs:2:5 + | +LL | bar::() + | ^^^^^^^^ + | +note: required by a bound in `bar` + --> $DIR/type_mismatch.rs:6:8 + | +LL | fn bar() -> [u8; N] {} + | ^^^^^^^^^^^ required by this bound in `bar` + error[E0308]: mismatched types --> $DIR/type_mismatch.rs:2:11 | @@ -5,7 +17,7 @@ LL | bar::() | ^ expected `u8`, found `usize` error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:5:26 + --> $DIR/type_mismatch.rs:6:26 | LL | fn bar() -> [u8; N] {} | --- ^^^^^^^ expected `[u8; N]`, found `()` @@ -13,11 +25,11 @@ LL | fn bar() -> [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() -> [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`. diff --git a/tests/ui/const-generics/type_not_in_scope.rs b/tests/ui/const-generics/type_not_in_scope.rs index 5933701808b..917abaed15e 100644 --- a/tests/ui/const-generics/type_not_in_scope.rs +++ b/tests/ui/const-generics/type_not_in_scope.rs @@ -6,6 +6,5 @@ impl X { } fn getn() -> [u8; N] {} //~^ ERROR expected type, found built-in attribute `cfg_attr` -//~| ERROR mismatched types fn main() {} diff --git a/tests/ui/const-generics/type_not_in_scope.stderr b/tests/ui/const-generics/type_not_in_scope.stderr index 5f45550a627..5eb81ca0522 100644 --- a/tests/ui/const-generics/type_not_in_scope.stderr +++ b/tests/ui/const-generics/type_not_in_scope.stderr @@ -10,15 +10,7 @@ error[E0573]: expected type, found built-in attribute `cfg_attr` LL | fn getn() -> [u8; N] {} | ^^^^^^^^ not a type -error[E0308]: mismatched types - --> $DIR/type_not_in_scope.rs:7:33 - | -LL | fn getn() -> [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`. 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 new file mode 100644 index 00000000000..582b480aa25 --- /dev/null +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs @@ -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; + +impl Copy for S {} +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 new file mode 100644 index 00000000000..a3906a9a22f --- /dev/null +++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr @@ -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 Copy for S {} + | -------------------------------- first implementation here +LL | impl Copy for S {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/transmutability/issue-101739-1.rs b/tests/ui/transmutability/issue-101739-1.rs index bcb8b158edf..2b966609108 100644 --- a/tests/ui/transmutability/issue-101739-1.rs +++ b/tests/ui/transmutability/issue-101739-1.rs @@ -6,7 +6,7 @@ mod assert { pub fn is_transmutable() where Dst: BikeshedIntrinsicFrom, //~ ERROR cannot find type `Dst` in this scope - //~^ ERROR mismatched types + //~^ the constant `ASSUME_ALIGNMENT` is not of type `Assume` { } } diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index 7c6b533ef5f..f0fa93722b8 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -4,13 +4,15 @@ error[E0412]: cannot find type `Dst` in this scope LL | Dst: BikeshedIntrinsicFrom, | ^^^ 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, - | ^^^^^^^^^^^^^^^^ 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`. From f7146136d79a4fb78c482797e50724bb4483a337 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 Mar 2023 20:52:06 +0000 Subject: [PATCH 2/2] Bail in combine if consts have different types --- compiler/rustc_infer/src/infer/combine.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 33292e871b1..adbd91f436c 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -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}; @@ -161,9 +160,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 @@ -173,15 +172,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)),