From a8eb5b7265cc52635d47614b18a6dd4062f3865b Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Sep 2022 17:12:51 +0200 Subject: [PATCH 01/13] stop upgrading param envs to `Reveal::All` --- .../src/transform/validate.rs | 67 ++++++++++--------- .../rustc_middle/src/mir/interpret/queries.rs | 5 +- .../rustc_middle/src/mir/interpret/value.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 3 +- compiler/rustc_middle/src/query/mod.rs | 2 - compiler/rustc_middle/src/traits/mod.rs | 18 +++-- compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_middle/src/ty/consts/kind.rs | 11 +-- compiler/rustc_middle/src/ty/layout.rs | 1 - compiler/rustc_middle/src/ty/mod.rs | 21 ------ .../rustc_mir_build/src/thir/pattern/mod.rs | 7 +- compiler/rustc_passes/src/layout_test.rs | 7 +- compiler/rustc_ty_utils/src/instance.rs | 1 - compiler/rustc_ty_utils/src/ty.rs | 7 +- .../const-generics/issues/issue-83765.stderr | 8 +-- src/test/ui/consts/const-size_of-cycle.stderr | 5 -- src/test/ui/consts/issue-44415.stderr | 5 -- .../ui/pattern/non-structural-match-types.rs | 4 +- .../pattern/non-structural-match-types.stderr | 10 ++- .../issue-26548-recursion-via-normalize.rs | 8 +-- ...issue-26548-recursion-via-normalize.stderr | 18 +++-- .../transmute-specialization.rs | 3 +- .../transmute-specialization.stderr | 14 +++- .../ui/type-alias-impl-trait/issue-53092-2.rs | 2 +- .../issue-53092-2.stderr | 32 +-------- .../no_inferrable_concrete_type.stderr | 2 +- .../structural-match-no-leak.rs | 3 +- .../structural-match-no-leak.stderr | 10 ++- .../type-alias-impl-trait/structural-match.rs | 3 +- .../structural-match.stderr | 10 ++- 30 files changed, 133 insertions(+), 158 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 4aa98cb13d82b..561d352dbf568 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; +use rustc_infer::infer::DefiningAnchor; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; @@ -12,13 +13,14 @@ use rustc_middle::mir::{ ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK, }; -use rustc_middle::ty::fold::BottomUpFolder; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable}; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; use rustc_target::abi::{Size, VariantIdx}; +use rustc_trait_selection::traits::ObligationCtxt; #[derive(Copy, Clone, Debug)] enum EdgeKind { @@ -88,25 +90,36 @@ pub fn equal_up_to_regions<'tcx>( return true; } - // Normalize lifetimes away on both sides, then compare. - let normalize = |ty: Ty<'tcx>| { - tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty).fold_with( - &mut BottomUpFolder { - tcx, - // FIXME: We erase all late-bound lifetimes, but this is not fully correct. - // If you have a type like ` fn(&'a u32) as SomeTrait>::Assoc`, - // this is not necessarily equivalent to `::Assoc`, - // since one may have an `impl SomeTrait for fn(&32)` and - // `impl SomeTrait for fn(&'static u32)` at the same time which - // specify distinct values for Assoc. (See also #56105) - lt_op: |_| tcx.lifetimes.re_erased, - // Leave consts and types unchanged. - ct_op: |ct| ct, - ty_op: |ty| ty, - }, - ) - }; - tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok()) + may_subtype_ignoring_regions(tcx, param_env, src, dest) + || may_subtype_ignoring_regions(tcx, param_env, dest, src) +} + +fn may_subtype_ignoring_regions<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + src: Ty<'tcx>, + dest: Ty<'tcx>, +) -> bool { + let mut builder = + tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble); + builder.enter(|infcx| { + let ocx = ObligationCtxt::new(&infcx); + let cause = ObligationCause::dummy(); + let src = ocx.normalize(cause.clone(), param_env, src); + let dest = ocx.normalize(cause.clone(), param_env, dest); + let Ok(infer_ok) = infcx.at(&cause, param_env).eq(src, dest) else { + return false; + }; + let () = ocx.register_infer_ok_obligations(infer_ok); + let errors = ocx.select_all_or_error(); + // With `Reveal::All`, opaque types get normalized away, with `Reveal::UserFacing` + // we would get unification errors because we're unable to look into opaque types, + // even if they're constrained in our current function. + // + // It seems very unlikely that this hides any bugs. + let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + errors.is_empty() + }) } struct TypeChecker<'a, 'tcx> { @@ -189,16 +202,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // all normal lifetimes are erased, higher-ranked types with their // late-bound lifetimes are still around and can lead to type // differences. So we compare ignoring lifetimes. - - // First, try with reveal_all. This might not work in some cases, as the predicates - // can be cleared in reveal_all mode. We try the reveal first anyways as it is used - // by some other passes like inlining as well. - let param_env = self.param_env.with_reveal_all_normalized(self.tcx); - if equal_up_to_regions(self.tcx, param_env, src, dest) { - return true; - } - - // If this fails, we can try it without the reveal. equal_up_to_regions(self.tcx, self.param_env, src, dest) } } @@ -285,7 +288,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { this.fail( location, format!( - "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is {:?}", + "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is `{:?}`", parent, f, ty, f_ty ) ) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 786927e2dad70..511d35fb0091b 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -20,7 +20,7 @@ impl<'tcx> TyCtxt<'tcx> { let substs = InternalSubsts::identity_for_item(self, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; - let param_env = self.param_env(def_id).with_reveal_all_normalized(self); + let param_env = self.param_env_reveal_all_normalized(def_id); self.const_eval_global_id(param_env, cid, None) } /// Resolves and evaluates a constant. @@ -184,8 +184,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> { let substs = InternalSubsts::identity_for_item(self.tcx, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; - let param_env = - self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const(); + let param_env = self.tcx.param_env_reveal_all_normalized(def_id).with_const(); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.tcx.erase_regions(param_env.and(cid)); diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index ac5fddb7ad1eb..a9e0a28013eed 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -84,7 +84,7 @@ impl<'tcx> ConstValue<'tcx> { param_env: ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> Option { - let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; + let size = tcx.layout_of(param_env.and(ty)).ok()?.size; self.try_to_bits(size) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index af00118fcbeba..13f12a8dc7c87 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2164,8 +2164,7 @@ impl<'tcx> ConstantKind<'tcx> { Self::Ty(ct) => ct.try_eval_bits(tcx, param_env, ty), Self::Val(val, t) => { assert_eq!(*t, ty); - let size = - tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; + let size = tcx.layout_of(param_env.and(ty)).ok()?.size; val.try_to_bits(size) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 53c254119f436..5a499cccc02db 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1238,8 +1238,6 @@ rustc_queries! { } /// Like `param_env`, but returns the `ParamEnv` in `Reveal::All` mode. - /// Prefer this over `tcx.param_env(def_id).with_reveal_all_normalized(tcx)`, - /// as this method is more efficient. query param_env_reveal_all_normalized(def_id: DefId) -> ty::ParamEnv<'tcx> { desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 68a7af0b8c8d7..73e00c355b077 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -71,13 +71,17 @@ pub enum Reveal { /// Also, `impl Trait` is normalized to the concrete type, /// which has to be already collected by type-checking. /// - /// NOTE: as `impl Trait`'s concrete type should *never* - /// be observable directly by the user, `Reveal::All` - /// should not be used by checks which may expose - /// type equality or type contents to the user. - /// There are some exceptions, e.g., around auto traits and - /// transmute-checking, which expose some details, but - /// not the whole concrete type of the `impl Trait`. + /// **This should not be used at any point before borrowck** + /// + /// The concrete type of an opaque type should *never* + /// be observable directly by the user and doing so can cause + /// cycles if done before borrowck. Therefore, `Reveal::All` + /// should not be used by checks which may expose type equality + /// or type contents to the user. + /// + /// There are some places where we do observe some details about + /// the concrete type of opaque types, e.g., around auto traits and + /// transmute-checking, but these shouldn't rely on `Reveal::All`. All, } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 2eb5cffa6bc44..77f44af32ac56 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -250,7 +250,7 @@ impl<'tcx> Const<'tcx> { ty: Ty<'tcx>, ) -> Option { assert_eq!(self.ty(), ty); - let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; + let size = tcx.layout_of(param_env.and(ty)).ok()?.size; // if `ty` does not depend on generic parameters, use an empty param_env self.kind().eval(tcx, param_env).try_to_bits(size) } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 2f7352e0aff24..42ade519491d8 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -184,16 +184,7 @@ impl<'tcx> ConstKind<'tcx> { if let ConstKind::Unevaluated(unevaluated) = self { use crate::mir::interpret::ErrorHandled; - // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` - // also does later, but we want to do it before checking for - // inference variables. - // Note that we erase regions *before* calling `with_reveal_all_normalized`, - // so that we don't try to invoke this query with - // any region variables. - let param_env_and = tcx - .erase_regions(param_env) - .with_reveal_all_normalized(tcx) - .and(tcx.erase_regions(unevaluated)); + let param_env_and = tcx.erase_regions(param_env).and(tcx.erase_regions(unevaluated)); // HACK(eddyb) when the query key would contain inference variables, // attempt using identity substs and `ParamEnv` instead, that will succeed diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 042eeec3f4622..a2cf942596bf7 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -232,7 +232,6 @@ fn layout_of<'tcx>( let (param_env, ty) = query.into_parts(); debug!(?ty); - let param_env = param_env.with_reveal_all_normalized(tcx); let unnormalized_ty = ty; // FIXME: We might want to have two different versions of `layout_of`: diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e8fe37e7dab73..82551a2f9b18e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1618,27 +1618,6 @@ impl<'tcx> ParamEnv<'tcx> { *self = self.with_constness(constness.and(self.constness())) } - /// Returns a new parameter environment with the same clauses, but - /// which "reveals" the true results of projections in all cases - /// (even for associated types that are specializable). This is - /// the desired behavior during codegen and certain other special - /// contexts; normally though we want to use `Reveal::UserFacing`, - /// which is the default. - /// All opaque types in the caller_bounds of the `ParamEnv` - /// will be normalized to their underlying types. - /// See PR #65989 and issue #65918 for more details - pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self { - if self.packed.tag().reveal == traits::Reveal::All { - return self; - } - - ParamEnv::new( - tcx.normalize_opaque_types(self.caller_bounds()), - Reveal::All, - self.constness(), - ) - } - /// Returns this same environment but with no caller bounds. #[inline] pub fn without_caller_bounds(self) -> Self { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 2c131a26d3a41..f34b4b480d604 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -478,11 +478,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { _ => return pat_from_kind(self.lower_variant_or_leaf(res, id, span, ty, vec![])), }; - // Use `Reveal::All` here because patterns are always monomorphic even if their function - // isn't. - let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx); let substs = self.typeck_results.node_substs(id); - let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, substs) { + let instance = match ty::Instance::resolve(self.tcx, self.param_env, def_id, substs) { Ok(Some(i)) => i, Ok(None) => { // It should be assoc consts if there's no error but we cannot resolve it. @@ -505,7 +502,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let mir_structural_match_violation = self.tcx.mir_const_qualif(instance.def_id()).custom_eq; debug!("mir_structural_match_violation({:?}) -> {}", qpath, mir_structural_match_violation); - match self.tcx.const_eval_instance(param_env_reveal_all, instance, Some(span)) { + match self.tcx.const_eval_instance(self.param_env, instance, Some(span)) { Ok(literal) => { let const_ = mir::ConstantKind::Val(literal, ty); let pattern = self.const_to_pat(const_, id, span, mir_structural_match_violation); diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index fd03f657111d9..8221aa6995c5e 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -25,7 +25,7 @@ pub fn test_layout(tcx: TyCtxt<'_>) { fn dump_layout_of<'tcx>(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId, attr: &Attribute) { let tcx = tcx; - let param_env = tcx.param_env(item_def_id); + let param_env = tcx.param_env_reveal_all_normalized(item_def_id); let ty = tcx.type_of(item_def_id); match tcx.layout_of(param_env.and(ty)) { Ok(ty_layout) => { @@ -66,10 +66,7 @@ fn dump_layout_of<'tcx>(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId, attr: &Attri } sym::debug => { - let normalized_ty = tcx.normalize_erasing_regions( - param_env.with_reveal_all_normalized(tcx), - ty, - ); + let normalized_ty = tcx.normalize_erasing_regions(param_env, ty); tcx.sess.span_err( tcx.def_span(item_def_id.to_def_id()), &format!("layout_of({:?}) = {:#?}", normalized_ty, *ty_layout), diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 05738b6c48ae2..519dab02ad6d8 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -136,7 +136,6 @@ fn resolve_associated_item<'tcx>( }); let substs = tcx.infer_ctxt().enter(|infcx| { - let param_env = param_env.with_reveal_all_normalized(tcx); let substs = rcvr_substs.rebase_onto(tcx, trait_def_id, impl_data.substs); let substs = translate_substs( &infcx, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 9266e4e3f6efb..6ff2c7d065166 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -335,7 +335,12 @@ fn well_formed_types_in_env<'tcx>( } fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { - tcx.param_env(def_id).with_reveal_all_normalized(tcx) + let param_env = tcx.param_env(def_id); + ty::ParamEnv::new( + tcx.normalize_opaque_types(param_env.caller_bounds()), + traits::Reveal::All, + param_env.constness(), + ) } fn instance_def_size_estimate<'tcx>( diff --git a/src/test/ui/const-generics/issues/issue-83765.stderr b/src/test/ui/const-generics/issues/issue-83765.stderr index d5f914f46f873..b2464b07e65f1 100644 --- a/src/test/ui/const-generics/issues/issue-83765.stderr +++ b/src/test/ui/const-generics/issues/issue-83765.stderr @@ -10,11 +10,11 @@ note: ...which requires computing candidate for ` LL | trait TensorDimension { | ^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires resolving instance ` as TensorDimension>::DIM`, completing the cycle -note: cycle used when computing candidate for ` as TensorDimension>` - --> $DIR/issue-83765.rs:4:1 +note: cycle used when const-evaluating + checking `TensorSize::size::{constant#0}` + --> $DIR/issue-83765.rs:16:31 | -LL | trait TensorDimension { - | ^^^^^^^^^^^^^^^^^^^^^ +LL | fn size(&self) -> [usize; Self::DIM]; + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr index 46f02ce8a4533..c34f472490245 100644 --- a/src/test/ui/consts/const-size_of-cycle.stderr +++ b/src/test/ui/consts/const-size_of-cycle.stderr @@ -7,11 +7,6 @@ LL | bytes: [u8; std::mem::size_of::()] note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... --> $DIR/const-size_of-cycle.rs:4:17 | -LL | bytes: [u8; std::mem::size_of::()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... - --> $DIR/const-size_of-cycle.rs:4:17 - | LL | bytes: [u8; std::mem::size_of::()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... diff --git a/src/test/ui/consts/issue-44415.stderr b/src/test/ui/consts/issue-44415.stderr index 57f94f8c6ab52..2ee2741042507 100644 --- a/src/test/ui/consts/issue-44415.stderr +++ b/src/test/ui/consts/issue-44415.stderr @@ -7,11 +7,6 @@ LL | bytes: [u8; unsafe { intrinsics::size_of::() }], note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... --> $DIR/issue-44415.rs:6:17 | -LL | bytes: [u8; unsafe { intrinsics::size_of::() }], - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires const-evaluating + checking `Foo::bytes::{constant#0}`... - --> $DIR/issue-44415.rs:6:17 - | LL | bytes: [u8; unsafe { intrinsics::size_of::() }], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires computing layout of `Foo`... diff --git a/src/test/ui/pattern/non-structural-match-types.rs b/src/test/ui/pattern/non-structural-match-types.rs index 5c33154736650..39eadedbf4bc0 100644 --- a/src/test/ui/pattern/non-structural-match-types.rs +++ b/src/test/ui/pattern/non-structural-match-types.rs @@ -9,6 +9,8 @@ fn main() { const { || {} } => {}, //~ ERROR cannot be used in patterns } match loop {} { - const { async {} } => {}, //~ ERROR cannot be used in patterns + const { async {} } => {}, + //~^ ERROR constant pattern depends on a generic parameter + //~| ERROR constant pattern depends on a generic parameter } } diff --git a/src/test/ui/pattern/non-structural-match-types.stderr b/src/test/ui/pattern/non-structural-match-types.stderr index 45e1626497388..230543ebf241a 100644 --- a/src/test/ui/pattern/non-structural-match-types.stderr +++ b/src/test/ui/pattern/non-structural-match-types.stderr @@ -4,11 +4,17 @@ error: `[closure@$DIR/non-structural-match-types.rs:9:17: 9:19]` cannot be used LL | const { || {} } => {}, | ^^^^^^^^^^^^^^^ -error: `impl Future` cannot be used in patterns +error: constant pattern depends on a generic parameter --> $DIR/non-structural-match-types.rs:12:9 | LL | const { async {} } => {}, | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: constant pattern depends on a generic parameter + --> $DIR/non-structural-match-types.rs:12:9 + | +LL | const { async {} } => {}, + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors diff --git a/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs b/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs index 91958dffcf4df..6266ee105c95b 100644 --- a/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs +++ b/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs @@ -1,10 +1,10 @@ -//~ ERROR cycle detected when computing layout of `core::option::Option` +//~ ERROR cycle detected when computing layout of `core::option::Option<::It>` +//~| NOTE ...which requires computing layout of `core::option::Option`... //~| NOTE ...which requires computing layout of `S`... -//~| NOTE ...which requires computing layout of `core::option::Option<::It>`... -//~| NOTE ...which again requires computing layout of `core::option::Option`, completing the cycle -//~| NOTE cycle used when computing layout of `core::option::Option<::It>` +//~| NOTE ...which again requires computing layout of `core::option::Option<::It>`, completing the cycle trait Mirror { + //~^ NOTE cycle used when checking deathness of variables in top-level module type It: ?Sized; } impl Mirror for T { diff --git a/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr index a75097cdbfbda..d5ad0d640186c 100644 --- a/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr +++ b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr @@ -1,9 +1,19 @@ -error[E0391]: cycle detected when computing layout of `core::option::Option` +error[E0391]: cycle detected when computing layout of `core::option::Option<::It>` | + = note: ...which requires computing layout of `core::option::Option`... = note: ...which requires computing layout of `S`... - = note: ...which requires computing layout of `core::option::Option<::It>`... - = note: ...which again requires computing layout of `core::option::Option`, completing the cycle - = note: cycle used when computing layout of `core::option::Option<::It>` + = note: ...which again requires computing layout of `core::option::Option<::It>`, completing the cycle +note: cycle used when checking deathness of variables in top-level module + --> $DIR/issue-26548-recursion-via-normalize.rs:6:1 + | +LL | / trait Mirror { +LL | | +LL | | type It: ?Sized; +LL | | } +... | +LL | | let _s = S(None); +LL | | } + | |_^ error: aborting due to previous error diff --git a/src/test/ui/specialization/transmute-specialization.rs b/src/test/ui/specialization/transmute-specialization.rs index 499334d983b1f..3c4a0b869cb83 100644 --- a/src/test/ui/specialization/transmute-specialization.rs +++ b/src/test/ui/specialization/transmute-specialization.rs @@ -1,5 +1,3 @@ -// run-pass - #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Specializable { type Output; } @@ -11,5 +9,6 @@ impl Specializable for T { fn main() { unsafe { std::mem::transmute::::Output>(0); + //~^ ERROR cannot transmute between types of different sizes } } diff --git a/src/test/ui/specialization/transmute-specialization.stderr b/src/test/ui/specialization/transmute-specialization.stderr index a0ea72415a189..39ba33b00fa8b 100644 --- a/src/test/ui/specialization/transmute-specialization.stderr +++ b/src/test/ui/specialization/transmute-specialization.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/transmute-specialization.rs:3:12 + --> $DIR/transmute-specialization.rs:1:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -8,5 +8,15 @@ LL | #![feature(specialization)] = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete -warning: 1 warning emitted +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute-specialization.rs:11:9 + | +LL | std::mem::transmute::::Output>(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `u16` (16 bits) + = note: target type: `<() as Specializable>::Output` (this type does not have a fixed size) + +error: aborting due to previous error; 1 warning emitted +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.rs b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs index 438ac35fdea51..a3070c8e93eaa 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53092-2.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs @@ -1,7 +1,7 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -type Bug = impl Fn(T) -> U + Copy; //~ ERROR cycle detected +type Bug = impl Fn(T) -> U + Copy; const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; //~^ ERROR: cannot transmute diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr index 1b89d55711dbd..8fcf4a6d2bc48 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -1,29 +1,3 @@ -error[E0391]: cycle detected when computing type of `Bug::{opaque#0}` - --> $DIR/issue-53092-2.rs:4:18 - | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires type-checking `CONST_BUG`... - --> $DIR/issue-53092-2.rs:6:1 - | -LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires computing layout of `Bug`... - = note: ...which requires normalizing `Bug`... - = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle -note: cycle used when checking item types in top-level module - --> $DIR/issue-53092-2.rs:1:1 - | -LL | / #![feature(type_alias_impl_trait)] -LL | | #![allow(dead_code)] -LL | | -LL | | type Bug = impl Fn(T) -> U + Copy; -... | -LL | | CONST_BUG(0); -LL | | } - | |_^ - error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/issue-53092-2.rs:6:41 | @@ -31,7 +5,7 @@ LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; | ^^^^^^^^^^^^^^^^^^^ | = note: source type: `[closure@$DIR/issue-53092-2.rs:6:61: 6:68]` (0 bits) - = note: target type: `Bug` (size can vary because of [type error]) + = note: target type: `Bug` (this type does not have a fixed size) error[E0277]: the trait bound `U: From` is not satisfied --> $DIR/issue-53092-2.rs:10:5 @@ -49,7 +23,7 @@ help: consider restricting type parameter `U` LL | type Bug> = impl Fn(T) -> U + Copy; | +++++++++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0391, E0512. +Some errors have detailed explanations: E0277, E0512. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index 337708b876524..3f3d337a82d20 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -13,7 +13,7 @@ LL | let _: foo::Foo = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^ | = note: source type: `u8` (8 bits) - = note: target type: `Foo` (size can vary because of [type error]) + = note: target type: `Foo` (this type does not have a fixed size) error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs index c2ab6a9d10aa6..5117d83a4203d 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -12,7 +12,8 @@ const LEAK_FREE: Bar = leak_free(); fn leak_free_test() { match LEAK_FREE { LEAK_FREE => (), - //~^ `Bar` cannot be used in patterns + //~^ ERROR constant pattern depends on a generic parameter + //~| ERROR constant pattern depends on a generic parameter _ => (), } } diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr index dbc183f54f46b..eda1cc3ac51da 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr +++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -1,8 +1,14 @@ -error: `Bar` cannot be used in patterns +error: constant pattern depends on a generic parameter --> $DIR/structural-match-no-leak.rs:14:9 | LL | LEAK_FREE => (), | ^^^^^^^^^ -error: aborting due to previous error +error: constant pattern depends on a generic parameter + --> $DIR/structural-match-no-leak.rs:14:9 + | +LL | LEAK_FREE => (), + | ^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/type-alias-impl-trait/structural-match.rs b/src/test/ui/type-alias-impl-trait/structural-match.rs index 7cc9ccaabdca4..77a2b95adcb92 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match.rs +++ b/src/test/ui/type-alias-impl-trait/structural-match.rs @@ -13,7 +13,8 @@ const VALUE: Foo = value(); fn test() { match VALUE { VALUE => (), - //~^ `Foo` cannot be used in patterns + //~^ ERROR constant pattern depends on a generic parameter + //~| ERROR constant pattern depends on a generic parameter _ => (), } } diff --git a/src/test/ui/type-alias-impl-trait/structural-match.stderr b/src/test/ui/type-alias-impl-trait/structural-match.stderr index 61287f268066e..bec2c2318440d 100644 --- a/src/test/ui/type-alias-impl-trait/structural-match.stderr +++ b/src/test/ui/type-alias-impl-trait/structural-match.stderr @@ -1,8 +1,14 @@ -error: `Foo` cannot be used in patterns +error: constant pattern depends on a generic parameter --> $DIR/structural-match.rs:15:9 | LL | VALUE => (), | ^^^^^ -error: aborting due to previous error +error: constant pattern depends on a generic parameter + --> $DIR/structural-match.rs:15:9 + | +LL | VALUE => (), + | ^^^^^ + +error: aborting due to 2 previous errors From d1ed61be5e8b0fcdf620cf9c39c808f87212d726 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 5 Sep 2022 17:30:49 +0200 Subject: [PATCH 02/13] add (currently broken) test --- .../ui/type-alias-impl-trait/in-where-clause.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/in-where-clause.rs diff --git a/src/test/ui/type-alias-impl-trait/in-where-clause.rs b/src/test/ui/type-alias-impl-trait/in-where-clause.rs new file mode 100644 index 0000000000000..ea7e132a02638 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/in-where-clause.rs @@ -0,0 +1,15 @@ +// check-pass +// This previously caused a query cycle as we evaluated +// `1 + 2` with `Reveal::All` during typeck, causing us to +// to get the concrete type of `Bar` while computing it. +#![feature(type_alias_impl_trait)] +type Bar = impl Sized; + +fn foo() -> Bar +where + Bar: Send, +{ + [0; 1 + 2] +} + +fn main() {} From 395f3f7f840cb9f9ea1d9eab682e4e89c30fdbeb Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Sep 2022 12:51:03 +0200 Subject: [PATCH 03/13] don't use `RevealAll` in `elaborate_drops` --- .../rustc_mir_dataflow/src/elaborate_drops.rs | 2 -- .../rustc_mir_transform/src/elaborate_drops.rs | 2 +- src/test/ui/impl-trait/issues/issue-78722.rs | 1 - src/test/ui/impl-trait/issues/issue-78722.stderr | 16 +++++----------- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index c0b0cc3c591b0..bb971165131e2 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -3,7 +3,6 @@ use rustc_hir::lang_items::LangItem; use rustc_index::vec::Idx; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; -use rustc_middle::traits::Reveal; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -273,7 +272,6 @@ where let subpath = self.elaborator.field_subpath(variant_path, field); let tcx = self.tcx(); - assert_eq!(self.elaborator.param_env().reveal(), Reveal::All); let field_ty = tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)); (tcx.mk_place_field(base_place, field, field_ty), subpath) diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 65f4956d23acd..4ddce50ef6d82 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -25,7 +25,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { debug!("elaborate_drops({:?} @ {:?})", body.source, body.span); let def_id = body.source.def_id(); - let param_env = tcx.param_env_reveal_all_normalized(def_id); + let param_env = tcx.param_env(def_id); let (side_table, move_data) = match MoveData::gather_moves(body, tcx, param_env) { Ok(move_data) => move_data, Err((move_data, _)) => { diff --git a/src/test/ui/impl-trait/issues/issue-78722.rs b/src/test/ui/impl-trait/issues/issue-78722.rs index 90d1cd3798a83..b13ab6bad7fbe 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.rs +++ b/src/test/ui/impl-trait/issues/issue-78722.rs @@ -7,7 +7,6 @@ type F = impl core::future::Future; struct Bug { V1: [(); { fn concrete_use() -> F { - //~^ ERROR expected `impl Future` to be a future that resolves to `u8`, but it resolves to `()` async {} } let f: F = async { 1 }; diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr index 9a0ffbc89d92e..975c771759f9b 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.stderr +++ b/src/test/ui/impl-trait/issues/issue-78722.stderr @@ -1,5 +1,5 @@ error[E0658]: `async` blocks are not allowed in constants - --> $DIR/issue-78722.rs:13:20 + --> $DIR/issue-78722.rs:12:20 | LL | let f: F = async { 1 }; | ^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let f: F = async { 1 }; = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time - --> $DIR/issue-78722.rs:13:13 + --> $DIR/issue-78722.rs:12:13 | LL | let f: F = async { 1 }; | ^ constants cannot evaluate destructors @@ -16,13 +16,7 @@ LL | let f: F = async { 1 }; LL | }], | - value is dropped here -error[E0271]: expected `impl Future` to be a future that resolves to `u8`, but it resolves to `()` - --> $DIR/issue-78722.rs:9:30 - | -LL | fn concrete_use() -> F { - | ^ expected `()`, found `u8` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0271, E0493, E0658. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`. From d04b32576cde204692cd42dd92fa15d58ff03e14 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Sep 2022 13:32:11 +0200 Subject: [PATCH 04/13] add some new ICE --- src/test/ui/impl-trait/in-ctfe/array-len.rs | 20 ++++++++++++++++ src/test/ui/impl-trait/in-ctfe/enum-discr.rs | 24 ++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/test/ui/impl-trait/in-ctfe/array-len.rs create mode 100644 src/test/ui/impl-trait/in-ctfe/enum-discr.rs diff --git a/src/test/ui/impl-trait/in-ctfe/array-len.rs b/src/test/ui/impl-trait/in-ctfe/array-len.rs new file mode 100644 index 0000000000000..1cd7d1be57104 --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/array-len.rs @@ -0,0 +1,20 @@ +trait MyTrait: Copy { + const ASSOC: usize; +} + +impl MyTrait for u8 { + const ASSOC: usize = 32; +} + +const fn yeet() -> impl MyTrait { + 0u8 +} + +const fn output(_: T) -> usize { + ::ASSOC +} + +fn main() { + let x = [0u8; output(yeet())]; + println!("{:?}", x); +} diff --git a/src/test/ui/impl-trait/in-ctfe/enum-discr.rs b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs new file mode 100644 index 0000000000000..6c55b079ee1d2 --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs @@ -0,0 +1,24 @@ +trait MyTrait: Copy { + const ASSOC: usize; +} + +impl MyTrait for u8 { + const ASSOC: usize = 32; +} + +const fn yeet() -> impl MyTrait { + 0u8 +} + +const fn output(_: T) -> usize { + ::ASSOC +} + +#[repr(usize)] +enum Foo { + Bar = output(yeet()), +} + +fn main() { + println!("{}", Foo::Bar as usize); +} From be33d9a85b9ad319d3793d42f0367dc61ae15948 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 6 Sep 2022 14:19:19 +0200 Subject: [PATCH 05/13] add more tests --- src/test/ui/impl-trait/in-ctfe/array-len.rs | 3 +++ src/test/ui/impl-trait/in-ctfe/enum-discr.rs | 3 +++ .../in-ctfe/match-arm-exhaustive.rs | 25 +++++++++++++++++++ .../in-ctfe/match-arm-exhaustive.stderr | 14 +++++++++++ 4 files changed, 45 insertions(+) create mode 100644 src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs create mode 100644 src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr diff --git a/src/test/ui/impl-trait/in-ctfe/array-len.rs b/src/test/ui/impl-trait/in-ctfe/array-len.rs index 1cd7d1be57104..d0716ae72965c 100644 --- a/src/test/ui/impl-trait/in-ctfe/array-len.rs +++ b/src/test/ui/impl-trait/in-ctfe/array-len.rs @@ -1,3 +1,6 @@ +// This previously compiled, but broke with #101478. +// +// See that PR for more details. trait MyTrait: Copy { const ASSOC: usize; } diff --git a/src/test/ui/impl-trait/in-ctfe/enum-discr.rs b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs index 6c55b079ee1d2..8f41dcb9af963 100644 --- a/src/test/ui/impl-trait/in-ctfe/enum-discr.rs +++ b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs @@ -1,3 +1,6 @@ +// This previously compiled, but broke with #101478. +// +// See that PR for more details. trait MyTrait: Copy { const ASSOC: usize; } diff --git a/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs new file mode 100644 index 0000000000000..8d809be0d0892 --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs @@ -0,0 +1,25 @@ +// This previously compiled, but broke with #101478. +// +// See that PR for more details. +trait MyTrait: Copy { + const ASSOC: u8; +} + +impl MyTrait for () { + const ASSOC: u8 = 0; +} + +const fn yeet() -> impl MyTrait {} + +const fn output(_: T) -> u8 { + ::ASSOC +} + +const CT: u8 = output(yeet()); + +fn main() { + match 0 { + CT => (), + 1.. => (), + } +} diff --git a/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr new file mode 100644 index 0000000000000..ba210465bb07e --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr @@ -0,0 +1,14 @@ +error: constant pattern depends on a generic parameter + --> $DIR/match-arm-exhaustive.rs:19:9 + | +LL | CT => (), + | ^^ + +error: constant pattern depends on a generic parameter + --> $DIR/match-arm-exhaustive.rs:19:9 + | +LL | CT => (), + | ^^ + +error: aborting due to 2 previous errors + From 350d14874a897e521bda748f1b57b70be6416c18 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 7 Sep 2022 13:29:33 +0200 Subject: [PATCH 06/13] uwu error message --- .../rustc_const_eval/src/interpret/util.rs | 4 +-- .../src/traits/const_evaluatable.rs | 12 ++++---- .../generic_const_exprs/issue-76595.rs | 1 + .../generic_const_exprs/issue-76595.stderr | 8 ++++- .../ui/const-generics/issues/issue-86530.rs | 1 + .../const-generics/issues/issue-86530.stderr | 8 ++++- .../ui/const-generics/issues/issue-98629.rs | 3 +- .../const-generics/issues/issue-98629.stderr | 12 +++----- src/test/ui/impl-trait/in-ctfe/array-len.rs | 4 ++- .../ui/impl-trait/in-ctfe/array-len.stderr | 16 ++++++++++ src/test/ui/impl-trait/in-ctfe/enum-discr.rs | 3 +- .../ui/impl-trait/in-ctfe/enum-discr.stderr | 8 +++++ .../in-ctfe/match-arm-exhaustive.rs | 4 ++- .../in-ctfe/match-arm-exhaustive.stderr | 4 +-- src/test/ui/issues/issue-77919.rs | 1 + src/test/ui/issues/issue-77919.stderr | 14 ++++++--- .../ctfe/default-assoc-const.rs | 22 ++++++++++++++ .../ctfe/default-assoc-const.stderr | 30 +++++++++++++++++++ .../specialization/ctfe/default-assoc-type.rs | 29 ++++++++++++++++++ .../ctfe/default-assoc-type.stderr | 30 +++++++++++++++++++ 20 files changed, 187 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/impl-trait/in-ctfe/array-len.stderr create mode 100644 src/test/ui/impl-trait/in-ctfe/enum-discr.stderr create mode 100644 src/test/ui/specialization/ctfe/default-assoc-const.rs create mode 100644 src/test/ui/specialization/ctfe/default-assoc-const.stderr create mode 100644 src/test/ui/specialization/ctfe/default-assoc-type.rs create mode 100644 src/test/ui/specialization/ctfe/default-assoc-type.stderr diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 2bc521d5bbe0b..63c7c263242fe 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -13,7 +13,7 @@ where T: TypeVisitable<'tcx>, { debug!("ensure_monomorphic_enough: ty={:?}", ty); - if !ty.needs_subst() { + if !(ty.needs_subst() || ty.has_opaque_types()) { return Ok(()); } @@ -31,7 +31,7 @@ where } match *ty.kind() { - ty::Param(_) => ControlFlow::Break(FoundParam), + ty::Param(_) | ty::Opaque(..) => ControlFlow::Break(FoundParam), ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) | ty::FnDef(def_id, substs) => { diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 254bc4ab66386..372be4bac7310 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -186,9 +186,9 @@ pub fn is_const_evaluatable<'cx, 'tcx>( let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); match concrete { Err(ErrorHandled::TooGeneric) => { - Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug( + Err(NotConstEvaluatable::Error(infcx.tcx.sess.span_err( span, - format!("Missing value for constant, but no error reported?"), + format!("unable to use constant with a hidden value in the type system"), ))) } Err(ErrorHandled::Linted) => { @@ -237,11 +237,13 @@ pub fn is_const_evaluatable<'cx, 'tcx>( Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { NotConstEvaluatable::MentionsInfer - } else if uv.has_param_types_or_consts() { + } else if uv.has_param_types_or_consts() { NotConstEvaluatable::MentionsParam } else { - let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?")); - NotConstEvaluatable::Error(guar) + NotConstEvaluatable::Error(infcx.tcx.sess.span_err( + span, + format!("unable to use constant with a hidden value in the type system"), + )) }), Err(ErrorHandled::Linted) => { let reported = diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs b/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs index faa8b3d10de4f..a30740466d3aa 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs +++ b/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs @@ -14,4 +14,5 @@ fn test() where Bool<{core::mem::size_of::() > 4}>: True { fn main() { test::<2>(); //~^ ERROR this function takes 2 generic arguments + //~| ERROR unable to use constant with a hidden value in the type system } diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr index c587a7e153fe3..9d5c9fd415ff0 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr @@ -16,6 +16,12 @@ help: add missing generic argument LL | test::<2, P>(); | +++ -error: aborting due to previous error +error: unable to use constant with a hidden value in the type system + --> $DIR/issue-76595.rs:15:5 + | +LL | test::<2>(); + | ^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/const-generics/issues/issue-86530.rs b/src/test/ui/const-generics/issues/issue-86530.rs index b024decd4e11c..50d49dfe21e85 100644 --- a/src/test/ui/const-generics/issues/issue-86530.rs +++ b/src/test/ui/const-generics/issues/issue-86530.rs @@ -15,6 +15,7 @@ where fn unit_literals() { z(" "); //~^ ERROR: the trait bound `&str: X` is not satisfied + //~| ERROR: unable to use constant with a hidden value in the type system } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-86530.stderr b/src/test/ui/const-generics/issues/issue-86530.stderr index c63857b2314e9..cfd4e65ae111f 100644 --- a/src/test/ui/const-generics/issues/issue-86530.stderr +++ b/src/test/ui/const-generics/issues/issue-86530.stderr @@ -1,3 +1,9 @@ +error: unable to use constant with a hidden value in the type system + --> $DIR/issue-86530.rs:16:5 + | +LL | z(" "); + | ^ + error[E0277]: the trait bound `&str: X` is not satisfied --> $DIR/issue-86530.rs:16:7 | @@ -15,6 +21,6 @@ LL | where LL | T: X, | ^ required by this bound in `z` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issues/issue-98629.rs b/src/test/ui/const-generics/issues/issue-98629.rs index fc8666bbcdb79..94719b3bf96c6 100644 --- a/src/test/ui/const-generics/issues/issue-98629.rs +++ b/src/test/ui/const-generics/issues/issue-98629.rs @@ -4,12 +4,13 @@ trait Trait { const N: usize; } +// FIXME: We should mention that `N` is missing impl const Trait for i32 {} -//~^ ERROR not all trait items implemented, missing: `N` fn f() where [(); ::N]:, + //~^ ERROR unable to use constant with a hidden value in the type system {} fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-98629.stderr b/src/test/ui/const-generics/issues/issue-98629.stderr index 53570220882c3..da4ebb23c77d6 100644 --- a/src/test/ui/const-generics/issues/issue-98629.stderr +++ b/src/test/ui/const-generics/issues/issue-98629.stderr @@ -1,12 +1,8 @@ -error[E0046]: not all trait items implemented, missing: `N` - --> $DIR/issue-98629.rs:7:1 +error: unable to use constant with a hidden value in the type system + --> $DIR/issue-98629.rs:11:5 | -LL | const N: usize; - | -------------- `N` from trait -... -LL | impl const Trait for i32 {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `N` in implementation +LL | [(); ::N]:, + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/impl-trait/in-ctfe/array-len.rs b/src/test/ui/impl-trait/in-ctfe/array-len.rs index d0716ae72965c..4d7fac09f3e73 100644 --- a/src/test/ui/impl-trait/in-ctfe/array-len.rs +++ b/src/test/ui/impl-trait/in-ctfe/array-len.rs @@ -1,4 +1,4 @@ -// This previously compiled, but broke with #101478. +// This previously compiled, but was intentionally changed in #101478. // // See that PR for more details. trait MyTrait: Copy { @@ -19,5 +19,7 @@ const fn output(_: T) -> usize { fn main() { let x = [0u8; output(yeet())]; + //~^ ERROR unable to use constant with a hidden value in the type system println!("{:?}", x); + //~^ ERROR unable to use constant with a hidden value in the type system } diff --git a/src/test/ui/impl-trait/in-ctfe/array-len.stderr b/src/test/ui/impl-trait/in-ctfe/array-len.stderr new file mode 100644 index 0000000000000..5fe9567818fe8 --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/array-len.stderr @@ -0,0 +1,16 @@ +error: unable to use constant with a hidden value in the type system + --> $DIR/array-len.rs:21:19 + | +LL | let x = [0u8; output(yeet())]; + | ^^^^^^^^^^^^^^ + +error: unable to use constant with a hidden value in the type system + --> $DIR/array-len.rs:23:22 + | +LL | println!("{:?}", x); + | ^ + | + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-trait/in-ctfe/enum-discr.rs b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs index 8f41dcb9af963..c44411b72aa2b 100644 --- a/src/test/ui/impl-trait/in-ctfe/enum-discr.rs +++ b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs @@ -1,4 +1,4 @@ -// This previously compiled, but broke with #101478. +// This previously compiled, but was intentionally changed in #101478. // // See that PR for more details. trait MyTrait: Copy { @@ -20,6 +20,7 @@ const fn output(_: T) -> usize { #[repr(usize)] enum Foo { Bar = output(yeet()), + //~^ ERROR unable to use constant with a hidden value in the type system } fn main() { diff --git a/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr b/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr new file mode 100644 index 0000000000000..7e65766473f80 --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr @@ -0,0 +1,8 @@ +error: unable to use constant with a hidden value in the type system + --> $DIR/enum-discr.rs:22:11 + | +LL | Bar = output(yeet()), + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs index 8d809be0d0892..c60c06f75d1a5 100644 --- a/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs +++ b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.rs @@ -1,4 +1,4 @@ -// This previously compiled, but broke with #101478. +// This previously compiled, but was intentionally changed in #101478. // // See that PR for more details. trait MyTrait: Copy { @@ -20,6 +20,8 @@ const CT: u8 = output(yeet()); fn main() { match 0 { CT => (), + //~^ ERROR constant pattern depends on a generic parameter + //~| ERROR constant pattern depends on a generic parameter 1.. => (), } } diff --git a/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr index ba210465bb07e..dfdebeb0e101a 100644 --- a/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr +++ b/src/test/ui/impl-trait/in-ctfe/match-arm-exhaustive.stderr @@ -1,11 +1,11 @@ error: constant pattern depends on a generic parameter - --> $DIR/match-arm-exhaustive.rs:19:9 + --> $DIR/match-arm-exhaustive.rs:22:9 | LL | CT => (), | ^^ error: constant pattern depends on a generic parameter - --> $DIR/match-arm-exhaustive.rs:19:9 + --> $DIR/match-arm-exhaustive.rs:22:9 | LL | CT => (), | ^^ diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index 966d76d148af3..a63b246f9a519 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -1,5 +1,6 @@ fn main() { [1; >::VAL]; + //~^ ERROR unable to use constant with a hidden value in the type system } trait TypeVal { const VAL: T; diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index ca256847b1f3b..fef68f4fffd73 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `PhantomData` in this scope - --> $DIR/issue-77919.rs:9:9 + --> $DIR/issue-77919.rs:10:9 | LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> $DIR/issue-77919.rs:11:63 + --> $DIR/issue-77919.rs:12:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | - ^^^ not found in this scope @@ -18,7 +18,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | help: you might be missing a type parameter: `, VAL` error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:11:1 + --> $DIR/issue-77919.rs:12:1 | LL | const VAL: T; | ------------ `VAL` from trait @@ -26,7 +26,13 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error: aborting due to 3 previous errors +error: unable to use constant with a hidden value in the type system + --> $DIR/issue-77919.rs:2:9 + | +LL | [1; >::VAL]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0046, E0412. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/specialization/ctfe/default-assoc-const.rs b/src/test/ui/specialization/ctfe/default-assoc-const.rs new file mode 100644 index 0000000000000..896c2a3743135 --- /dev/null +++ b/src/test/ui/specialization/ctfe/default-assoc-const.rs @@ -0,0 +1,22 @@ +// ICE fixed by #101478. +// +// See that PR for more details. +#![feature(specialization)] +//~^ WARNING the feature `specialization` is incomplete and may not be safe to use + +trait Foo { + const ASSOC: usize; +} + + +impl Foo for u32 { + default const ASSOC: usize = 0; +} + +fn foo() -> [u8; 0] { + [0; ::ASSOC] + //~^ ERROR unable to use constant with a hidden value in the type system + //~| ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/specialization/ctfe/default-assoc-const.stderr b/src/test/ui/specialization/ctfe/default-assoc-const.stderr new file mode 100644 index 0000000000000..209621164f7a8 --- /dev/null +++ b/src/test/ui/specialization/ctfe/default-assoc-const.stderr @@ -0,0 +1,30 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-assoc-const.rs:4:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + +error[E0308]: mismatched types + --> $DIR/default-assoc-const.rs:17:5 + | +LL | fn foo() -> [u8; 0] { + | ------- expected `[u8; 0]` because of return type +LL | [0; ::ASSOC] + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `0`, found `::ASSOC` + | + = note: expected array `[u8; 0]` + found array `[u8; _]` + +error: unable to use constant with a hidden value in the type system + --> $DIR/default-assoc-const.rs:17:9 + | +LL | [0; ::ASSOC] + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/specialization/ctfe/default-assoc-type.rs b/src/test/ui/specialization/ctfe/default-assoc-type.rs new file mode 100644 index 0000000000000..fbaab89a2d834 --- /dev/null +++ b/src/test/ui/specialization/ctfe/default-assoc-type.rs @@ -0,0 +1,29 @@ +// ICE fixed by #101478. +// +// See that PR for more details. +#![feature(specialization)] +//~^ WARNING the feature `specialization` is incomplete and may not be safe to use + +trait Foo { + type Assoc: Trait; +} + +impl Foo for Vec { + default type Assoc = u32; +} + +trait Trait { + const ASSOC: usize; +} + +impl Trait for u32 { + const ASSOC: usize = 0; +} + +fn foo() -> [u8; 0] { + [0; < as Foo>::Assoc as Trait>::ASSOC] + //~^ ERROR unable to use constant with a hidden value in the type system + //~| ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/specialization/ctfe/default-assoc-type.stderr b/src/test/ui/specialization/ctfe/default-assoc-type.stderr new file mode 100644 index 0000000000000..879ca34ecd1f0 --- /dev/null +++ b/src/test/ui/specialization/ctfe/default-assoc-type.stderr @@ -0,0 +1,30 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-assoc-type.rs:4:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + +error[E0308]: mismatched types + --> $DIR/default-assoc-type.rs:24:5 + | +LL | fn foo() -> [u8; 0] { + | ------- expected `[u8; 0]` because of return type +LL | [0; < as Foo>::Assoc as Trait>::ASSOC] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `0`, found `< as Foo>::Assoc as Trait>::ASSOC` + | + = note: expected array `[u8; 0]` + found array `[u8; _]` + +error: unable to use constant with a hidden value in the type system + --> $DIR/default-assoc-type.rs:24:9 + | +LL | [0; < as Foo>::Assoc as Trait>::ASSOC] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. From 0fd7c3fd7df701540d23b1740311ae3dae36e503 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 7 Sep 2022 13:37:33 +0200 Subject: [PATCH 07/13] resolve_instance: ErrorReported for missing value --- compiler/rustc_const_eval/src/interpret/util.rs | 2 +- compiler/rustc_ty_utils/src/instance.rs | 6 +++++- src/test/ui/const-generics/issues/issue-98629.rs | 3 +-- src/test/ui/const-generics/issues/issue-98629.stderr | 12 ++++++++---- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 63c7c263242fe..4bb5b4a54afe7 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -13,7 +13,7 @@ where T: TypeVisitable<'tcx>, { debug!("ensure_monomorphic_enough: ty={:?}", ty); - if !(ty.needs_subst() || ty.has_opaque_types()) { + if !(ty.needs_subst() || ty.has_opaque_types()) { return Ok(()); } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 519dab02ad6d8..6cffa797beb14 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -172,7 +172,11 @@ fn resolve_associated_item<'tcx>( // If the item does not have a value, then we cannot return an instance. if !leaf_def.item.defaultness(tcx).has_value() { - return Ok(None); + let guard = tcx.sess.delay_span_bug( + tcx.def_span(leaf_def.item.def_id), + "missing value for assoc item in impl", + ); + return Err(guard); } let substs = tcx.erase_regions(substs); diff --git a/src/test/ui/const-generics/issues/issue-98629.rs b/src/test/ui/const-generics/issues/issue-98629.rs index 94719b3bf96c6..fc8666bbcdb79 100644 --- a/src/test/ui/const-generics/issues/issue-98629.rs +++ b/src/test/ui/const-generics/issues/issue-98629.rs @@ -4,13 +4,12 @@ trait Trait { const N: usize; } -// FIXME: We should mention that `N` is missing impl const Trait for i32 {} +//~^ ERROR not all trait items implemented, missing: `N` fn f() where [(); ::N]:, - //~^ ERROR unable to use constant with a hidden value in the type system {} fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-98629.stderr b/src/test/ui/const-generics/issues/issue-98629.stderr index da4ebb23c77d6..53570220882c3 100644 --- a/src/test/ui/const-generics/issues/issue-98629.stderr +++ b/src/test/ui/const-generics/issues/issue-98629.stderr @@ -1,8 +1,12 @@ -error: unable to use constant with a hidden value in the type system - --> $DIR/issue-98629.rs:11:5 +error[E0046]: not all trait items implemented, missing: `N` + --> $DIR/issue-98629.rs:7:1 | -LL | [(); ::N]:, - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | const N: usize; + | -------------- `N` from trait +... +LL | impl const Trait for i32 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `N` in implementation error: aborting due to previous error +For more information about this error, try `rustc --explain E0046`. From bf787f83a8fa1af214fed07efc5224d02cb2ebe0 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 7 Sep 2022 13:54:33 +0200 Subject: [PATCH 08/13] mir opt tests + comment --- .../rustc_middle/src/mir/interpret/queries.rs | 4 ++ .../inline/inline_generator.main.Inline.diff | 56 +++++++++++++------ .../inline/issue_78442.bar.Inline.diff | 51 ++++++++++------- .../inline/issue_78442.bar.RevealAll.diff | 24 +++++--- 4 files changed, 90 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 511d35fb0091b..4122aeef8af5b 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -20,6 +20,8 @@ impl<'tcx> TyCtxt<'tcx> { let substs = InternalSubsts::identity_for_item(self, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; + // This function isn't used in the type system, so we're free to use + // `param_env_reveal_all_normalized` here. let param_env = self.param_env_reveal_all_normalized(def_id); self.const_eval_global_id(param_env, cid, None) } @@ -184,6 +186,8 @@ impl<'tcx> TyCtxtEnsure<'tcx> { let substs = InternalSubsts::identity_for_item(self.tcx, def_id); let instance = ty::Instance::new(def_id, substs); let cid = GlobalId { instance, promoted: None }; + // This function isn't used in the type system, so we're free to use + // `param_env_reveal_all_normalized` here. let param_env = self.tcx.param_env_reveal_all_normalized(def_id).with_const(); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff index 0b992e3c32ad1..7ad57a3944f61 100644 --- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff @@ -50,7 +50,7 @@ + Deinit(_4); // scope 2 at $DIR/inline-generator.rs:15:5: 15:41 + discriminant(_4) = 0; // scope 2 at $DIR/inline-generator.rs:15:5: 15:41 _3 = &mut _4; // scope 0 at $DIR/inline-generator.rs:+1:23: +1:31 -- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 +- _2 = Pin::<&mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>::new(move _3) -> [return: bb2, unwind: bb7]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:32 - // mir::Constant - // + span: $DIR/inline-generator.rs:9:14: 9:22 - // + user_ty: UserType(0) @@ -67,7 +67,7 @@ + StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL + StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL StorageDead(_3); // scope 0 at $DIR/inline-generator.rs:+1:31: +1:32 -- _1 = <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 +- _1 = <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::resume(move _2, const false) -> [return: bb3, unwind: bb7]; // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 - // mir::Constant - // + span: $DIR/inline-generator.rs:9:33: 9:39 - // + literal: Const { ty: for<'r> fn(Pin<&'r mut [generator@$DIR/inline-generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::Yield, <[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::Return> {<[generator@$DIR/inline-generator.rs:15:5: 15:8] as Generator>::resume}, val: Value() } @@ -77,7 +77,7 @@ + StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 + _13 = deref_copy (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ switchInt(move _12) -> [0_u32: bb7, 1_u32: bb12, 3_u32: bb11, otherwise: bb13]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 } - bb3: { @@ -86,36 +86,60 @@ + StorageDead(_10); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 + StorageDead(_7); // scope 0 at $DIR/inline-generator.rs:+1:14: +1:46 StorageDead(_2); // scope 0 at $DIR/inline-generator.rs:+1:45: +1:46 +- drop(_4) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47 ++ drop(_4) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47 + } + +- bb4: { ++ bb2: { StorageDead(_4); // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47 _0 = const (); // scope 0 at $DIR/inline-generator.rs:+0:11: +2:2 +- drop(_1) -> [return: bb5, unwind: bb8]; // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2 ++ drop(_1) -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2 + } + +- bb5: { ++ bb3: { StorageDead(_1); // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2 return; // scope 0 at $DIR/inline-generator.rs:+2:2: +2:2 } -- bb4 (cleanup): { -+ bb2 (cleanup): { +- bb6 (cleanup): { +- drop(_1) -> bb8; // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2 ++ bb4 (cleanup): { ++ drop(_1) -> bb6; // scope 0 at $DIR/inline-generator.rs:+2:1: +2:2 + } + +- bb7 (cleanup): { +- drop(_4) -> bb8; // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47 ++ bb5 (cleanup): { ++ drop(_4) -> bb6; // scope 0 at $DIR/inline-generator.rs:+1:46: +1:47 + } + +- bb8 (cleanup): { ++ bb6 (cleanup): { resume; // scope 0 at $DIR/inline-generator.rs:+0:1: +2:2 + } + -+ bb3: { ++ bb7: { + _11 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 + StorageLive(_9); // scope 6 at $DIR/inline-generator.rs:15:20: 15:21 + _9 = _11; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21 -+ switchInt(move _9) -> [false: bb5, otherwise: bb4]; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21 ++ switchInt(move _9) -> [false: bb9, otherwise: bb8]; // scope 6 at $DIR/inline-generator.rs:15:20: 15:21 + } + -+ bb4: { ++ bb8: { + _8 = const 7_i32; // scope 6 at $DIR/inline-generator.rs:15:24: 15:25 -+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 ++ goto -> bb10; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 + } + -+ bb5: { ++ bb9: { + _8 = const 13_i32; // scope 6 at $DIR/inline-generator.rs:15:35: 15:37 -+ goto -> bb6; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 ++ goto -> bb10; // scope 6 at $DIR/inline-generator.rs:15:17: 15:39 + } + -+ bb6: { ++ bb10: { + StorageDead(_9); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39 + Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 @@ -125,7 +149,7 @@ + goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:11: 15:39 + } + -+ bb7: { ++ bb11: { + StorageLive(_8); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + _10 = move _7; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + StorageDead(_8); // scope 6 at $DIR/inline-generator.rs:15:38: 15:39 @@ -137,11 +161,11 @@ + goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:41: 15:41 + } + -+ bb8: { -+ assert(const false, "generator resumed after completion") -> [success: bb8, unwind: bb2]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ bb12: { ++ assert(const false, "generator resumed after completion") -> [success: bb12, unwind: bb5]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + } + -+ bb9: { ++ bb13: { + unreachable; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 } } diff --git a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff index c16dfdf395ecc..c2cfc5735934e 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff @@ -15,8 +15,8 @@ StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 -- _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 -+ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 +- _4 = hide_foo() -> [return: bb1, unwind: bb6]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 ++ _4 = hide_foo() -> [return: bb1, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value() } @@ -26,43 +26,52 @@ _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 - // mir::Constant - // + span: $DIR/issue-78442.rs:11:5: 11:15 - // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r fn() {foo}, ()) -> >::Output {>::call}, val: Value() } -+ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL ++ _2 = move (*_3)() -> [return: bb7, unwind: bb4]; // scope 1 at $SRC_DIR/core/src/ops/function.rs:LL:COL } bb2: { - StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 - StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 -- StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -- StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -- _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 -- drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 -+ return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 +- drop(_4) -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 +- } +- +- bb3: { + StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 + StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 + _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 +- drop(_1) -> [return: bb4, unwind: bb7]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 ++ drop(_1) -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 } -- bb3: { -- return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 -+ bb3 (cleanup): { -+ drop(_1) -> bb4; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 +- bb4: { ++ bb3: { + return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 + } + ++ bb4 (cleanup): { ++ drop(_4) -> bb5; // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 ++ } ++ + bb5 (cleanup): { +- drop(_4) -> bb6; // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 ++ drop(_1) -> bb6; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 } - bb4 (cleanup): { -- drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + bb6 (cleanup): { +- drop(_1) -> bb7; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 } -- bb5 (cleanup): { +- bb7 (cleanup): { - resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 -+ bb5: { ++ bb7: { + StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 + StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 -+ StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -+ StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 -+ _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 -+ drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 ++ drop(_4) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 } } diff --git a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff index 0faa522cbaa9c..61a9f383d0f41 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff @@ -15,7 +15,7 @@ StorageLive(_2); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 StorageLive(_3); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 StorageLive(_4); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 - _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 + _4 = hide_foo() -> [return: bb1, unwind: bb6]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value() } @@ -25,8 +25,8 @@ _3 = &_4; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:15 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 Deinit(_5); // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 -+ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 ++ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+4:5: +4:17 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:15 - // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> >::Output {>::call}, val: Value() } @@ -36,21 +36,29 @@ bb2: { StorageDead(_5); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 StorageDead(_3); // scope 0 at $DIR/issue-78442.rs:+4:16: +4:17 + drop(_4) -> [return: bb3, unwind: bb6]; // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 + } + + bb3: { StorageDead(_4); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 StorageDead(_2); // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 _0 = const (); // scope 0 at $DIR/issue-78442.rs:+3:3: +5:2 - drop(_1) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + drop(_1) -> [return: bb4, unwind: bb7]; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 } - bb3: { + bb4: { return; // scope 0 at $DIR/issue-78442.rs:+5:2: +5:2 } - bb4 (cleanup): { - drop(_1) -> bb5; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + bb5 (cleanup): { + drop(_4) -> bb6; // scope 0 at $DIR/issue-78442.rs:+4:17: +4:18 } - bb5 (cleanup): { + bb6 (cleanup): { + drop(_1) -> bb7; // scope 0 at $DIR/issue-78442.rs:+5:1: +5:2 + } + + bb7 (cleanup): { resume; // scope 0 at $DIR/issue-78442.rs:+0:1: +5:2 } } From 3b495baef1d57322234189e79e5377439fc2be13 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 12 Sep 2022 11:58:24 +0200 Subject: [PATCH 09/13] extend error message --- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 9 +++++++++ .../src/traits/const_evaluatable.rs | 10 ++-------- .../generic_const_exprs/issue-76595.stderr | 3 +++ src/test/ui/const-generics/issues/issue-86530.stderr | 3 +++ src/test/ui/impl-trait/in-ctfe/array-len.stderr | 5 +++++ src/test/ui/impl-trait/in-ctfe/enum-discr.stderr | 3 +++ src/test/ui/issues/issue-77919.stderr | 3 +++ .../ui/specialization/ctfe/default-assoc-const.stderr | 3 +++ .../ui/specialization/ctfe/default-assoc-type.stderr | 3 +++ 9 files changed, 34 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 67526c2228937..5cf2ba39de7df 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -3199,4 +3199,13 @@ impl<'tcx> InferCtxt<'_, 'tcx> { _ => false, } } + + pub fn concrete_ctfe_failure_error(&self, span: Span) -> ErrorGuaranteed { + self.tcx + .sess + .struct_span_err(span, "unable to use constant with a hidden value in the type system") + .note("this most often happens when trying to look into an opaque type") + .note("the type system cannot access the hidden type of opaque types") + .emit() + } } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 372be4bac7310..69ad1f020fd51 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -186,10 +186,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); match concrete { Err(ErrorHandled::TooGeneric) => { - Err(NotConstEvaluatable::Error(infcx.tcx.sess.span_err( - span, - format!("unable to use constant with a hidden value in the type system"), - ))) + Err(NotConstEvaluatable::Error(infcx.concrete_ctfe_failure_error(span))) } Err(ErrorHandled::Linted) => { let reported = infcx @@ -240,10 +237,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } else if uv.has_param_types_or_consts() { NotConstEvaluatable::MentionsParam } else { - NotConstEvaluatable::Error(infcx.tcx.sess.span_err( - span, - format!("unable to use constant with a hidden value in the type system"), - )) + NotConstEvaluatable::Error(infcx.concrete_ctfe_failure_error(span)) }), Err(ErrorHandled::Linted) => { let reported = diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr index 9d5c9fd415ff0..35269a2445a32 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr @@ -21,6 +21,9 @@ error: unable to use constant with a hidden value in the type system | LL | test::<2>(); | ^^^^^^^^^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/issues/issue-86530.stderr b/src/test/ui/const-generics/issues/issue-86530.stderr index cfd4e65ae111f..be6e664facd23 100644 --- a/src/test/ui/const-generics/issues/issue-86530.stderr +++ b/src/test/ui/const-generics/issues/issue-86530.stderr @@ -3,6 +3,9 @@ error: unable to use constant with a hidden value in the type system | LL | z(" "); | ^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types error[E0277]: the trait bound `&str: X` is not satisfied --> $DIR/issue-86530.rs:16:7 diff --git a/src/test/ui/impl-trait/in-ctfe/array-len.stderr b/src/test/ui/impl-trait/in-ctfe/array-len.stderr index 5fe9567818fe8..6caef9894eabb 100644 --- a/src/test/ui/impl-trait/in-ctfe/array-len.stderr +++ b/src/test/ui/impl-trait/in-ctfe/array-len.stderr @@ -3,6 +3,9 @@ error: unable to use constant with a hidden value in the type system | LL | let x = [0u8; output(yeet())]; | ^^^^^^^^^^^^^^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types error: unable to use constant with a hidden value in the type system --> $DIR/array-len.rs:23:22 @@ -10,6 +13,8 @@ error: unable to use constant with a hidden value in the type system LL | println!("{:?}", x); | ^ | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr b/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr index 7e65766473f80..ad15ebb7f239f 100644 --- a/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr +++ b/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr @@ -3,6 +3,9 @@ error: unable to use constant with a hidden value in the type system | LL | Bar = output(yeet()), | ^^^^^^^^^^^^^^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types error: aborting due to previous error diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index fef68f4fffd73..9bb26f1671192 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -31,6 +31,9 @@ error: unable to use constant with a hidden value in the type system | LL | [1; >::VAL]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types error: aborting due to 4 previous errors diff --git a/src/test/ui/specialization/ctfe/default-assoc-const.stderr b/src/test/ui/specialization/ctfe/default-assoc-const.stderr index 209621164f7a8..aaf5c4978e7a5 100644 --- a/src/test/ui/specialization/ctfe/default-assoc-const.stderr +++ b/src/test/ui/specialization/ctfe/default-assoc-const.stderr @@ -24,6 +24,9 @@ error: unable to use constant with a hidden value in the type system | LL | [0; ::ASSOC] | ^^^^^^^^^^^^^^^^^^^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types error: aborting due to 2 previous errors; 1 warning emitted diff --git a/src/test/ui/specialization/ctfe/default-assoc-type.stderr b/src/test/ui/specialization/ctfe/default-assoc-type.stderr index 879ca34ecd1f0..c9716667fb25d 100644 --- a/src/test/ui/specialization/ctfe/default-assoc-type.stderr +++ b/src/test/ui/specialization/ctfe/default-assoc-type.stderr @@ -24,6 +24,9 @@ error: unable to use constant with a hidden value in the type system | LL | [0; < as Foo>::Assoc as Trait>::ASSOC] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types error: aborting due to 2 previous errors; 1 warning emitted From db6d09d80426de4a2e85702271f333b8eb6d1771 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 12 Sep 2022 14:45:19 +0200 Subject: [PATCH 10/13] add transmute tests --- .../ui/impl-trait/transmute/in-defining-scope.rs | 13 +++++++++++++ .../impl-trait/transmute/in-defining-scope.stderr | 12 ++++++++++++ .../transmute/outside-of-defining-scope.rs | 14 ++++++++++++++ .../transmute/outside-of-defining-scope.stderr | 12 ++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 src/test/ui/impl-trait/transmute/in-defining-scope.rs create mode 100644 src/test/ui/impl-trait/transmute/in-defining-scope.stderr create mode 100644 src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs create mode 100644 src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr diff --git a/src/test/ui/impl-trait/transmute/in-defining-scope.rs b/src/test/ui/impl-trait/transmute/in-defining-scope.rs new file mode 100644 index 0000000000000..896ce9136cedb --- /dev/null +++ b/src/test/ui/impl-trait/transmute/in-defining-scope.rs @@ -0,0 +1,13 @@ +// This previously caused a query cycle which changed in #101478. +// +// See that PR for more details. +use std::mem::transmute; +fn foo() -> impl Sized { + unsafe { + transmute::<_, u8>(foo()); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types + } + 0u8 +} + +fn main() {} diff --git a/src/test/ui/impl-trait/transmute/in-defining-scope.stderr b/src/test/ui/impl-trait/transmute/in-defining-scope.stderr new file mode 100644 index 0000000000000..1a3c856afd0f8 --- /dev/null +++ b/src/test/ui/impl-trait/transmute/in-defining-scope.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/in-defining-scope.rs:7:9 + | +LL | transmute::<_, u8>(foo()); + | ^^^^^^^^^^^^^^^^^^ + | + = note: source type: `impl Sized` (this type does not have a fixed size) + = note: target type: `u8` (8 bits) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs new file mode 100644 index 0000000000000..ec7fabfa0fa26 --- /dev/null +++ b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs @@ -0,0 +1,14 @@ +// This previously compiled, but was intentionally changed in #101478. +// +// See that PR for more details. +use std::mem::transmute; +fn foo() -> impl Sized { + 0u8 +} + +fn main() { + unsafe { + transmute::<_, u8>(foo()); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types + } +} diff --git a/src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr new file mode 100644 index 0000000000000..4d69718a36c92 --- /dev/null +++ b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/outside-of-defining-scope.rs:11:9 + | +LL | transmute::<_, u8>(foo()); + | ^^^^^^^^^^^^^^^^^^ + | + = note: source type: `impl Sized` (this type does not have a fixed size) + = note: target type: `u8` (8 bits) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0512`. From 52c796ee63384220dbc26a7dfb42f8689876f5f6 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 12 Sep 2022 15:17:47 +0200 Subject: [PATCH 11/13] add test for the breakage of the `name-it` crate --- .../impl-trait/in-ctfe/array-len-size-of.rs | 19 +++++++++++++++++++ .../in-ctfe/array-len-size-of.stderr | 11 +++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs create mode 100644 src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr diff --git a/src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs new file mode 100644 index 0000000000000..2988d063b76c5 --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs @@ -0,0 +1,19 @@ +// This previously compiled, but was intentionally changed in #101478. +// This was used in https://github.com/GoldsteinE/name-it. +// +// See that PR for more details. +use std::mem; +fn returns_opaque() -> impl Sized { + 0u8 +} + +struct NamedOpaqueType { + data: [mem::MaybeUninit; size_of_fut(returns_opaque)] + //~^ ERROR unable to use constant with a hidden value in the type system +} + +const fn size_of_fut(x: fn() -> FUT) -> usize { + mem::size_of::() +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr new file mode 100644 index 0000000000000..f47d7fbb81176 --- /dev/null +++ b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr @@ -0,0 +1,11 @@ +error: unable to use constant with a hidden value in the type system + --> $DIR/array-len-size-of.rs:11:11 + | +LL | data: [mem::MaybeUninit; size_of_fut(returns_opaque)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this most often happens when trying to look into an opaque type + = note: the type system cannot access the hidden type of opaque types + +error: aborting due to previous error + From 64c7c1176094a1cab38ee47f17f1c922290e3041 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 16 Sep 2022 19:52:38 +0200 Subject: [PATCH 12/13] reduce ctfe changes to a future compat lint --- compiler/rustc_lint_defs/src/builtin.rs | 42 ++++++++++++++++ .../rustc_middle/src/mir/interpret/queries.rs | 50 ++++++++++++++++++- .../src/traits/const_evaluatable.rs | 10 ++-- .../generic_const_exprs/issue-76595.rs | 1 - .../generic_const_exprs/issue-76595.stderr | 11 +--- .../ui/const-generics/issues/issue-86530.rs | 1 - .../const-generics/issues/issue-86530.stderr | 11 +--- .../impl-trait/in-ctfe/array-len-size-of.rs | 5 +- .../in-ctfe/array-len-size-of.stderr | 14 +++--- src/test/ui/impl-trait/in-ctfe/array-len.rs | 8 ++- .../ui/impl-trait/in-ctfe/array-len.stderr | 26 +++++----- src/test/ui/impl-trait/in-ctfe/enum-discr.rs | 5 +- .../ui/impl-trait/in-ctfe/enum-discr.stderr | 12 +++-- src/test/ui/issues/issue-77919.rs | 1 - src/test/ui/issues/issue-77919.stderr | 17 ++----- .../ctfe/default-assoc-const.rs | 8 ++- .../ctfe/default-assoc-const.stderr | 28 +++++------ .../specialization/ctfe/default-assoc-type.rs | 8 ++- .../ctfe/default-assoc-type.stderr | 28 +++++------ 19 files changed, 186 insertions(+), 100 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index e5dfda24dc701..cd2ed3cbb841b 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3365,6 +3365,7 @@ declare_lint_pass! { DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DUPLICATE_MACRO_ATTRIBUTES, SUSPICIOUS_AUTO_TRAIT_IMPLS, + HIDDEN_TYPE_OF_OPAQUE_TYPES_IN_TYPE_SYSTEM, DEPRECATED_WHERE_CLAUSE_LOCATION, TEST_UNSTABLE_LINT, FFI_UNWIND_CALLS, @@ -3981,6 +3982,47 @@ declare_lint! { }; } +declare_lint! { + /// The `hidden_type_of_opaque_types_in_type_system` backward compatibility + /// lint detects when the hidden type of an opaque type is required by the type + /// system. + /// + /// + /// ### Example + /// + /// ```rust + /// use std::mem::transmute; + /// fn foo() -> impl Sized { + /// 0u8 + /// } + /// + /// fn main() { + /// unsafe { + /// transmute::<_, u8>(foo()); + /// } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// When using an opaque type, i.e. `impl Trait`, the + /// concrete underlying type should not be revealed to + /// the type system. The compiler previously revealed this + /// underlying type in some instances causing bugs. + /// It is still unclear whether this lint will be converted to + /// a hard error in the future or whether a different implementation + /// can support these use-cases. + pub HIDDEN_TYPE_OF_OPAQUE_TYPES_IN_TYPE_SYSTEM, + Warn, + "the rules governing auto traits will change in the future", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::FutureReleaseError, + reference: "issue # ", + }; +} + declare_lint! { /// The `deprecated_where_clause_location` lint detects when a where clause in front of the equals /// in an associated type. diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 4122aeef8af5b..fe3daa64759a5 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -1,10 +1,11 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}; use crate::mir; +use crate::traits::Reveal; use crate::ty::subst::InternalSubsts; use crate::ty::visit::TypeVisitable; use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_span::{Span, DUMMY_SP}; impl<'tcx> TyCtxt<'tcx> { @@ -61,6 +62,42 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// HACK: We retry evaluation with `Reveal::All` for backwards + /// compatability reasons, see #101478 for more details. + #[cold] + fn const_eval_resolve_for_typeck_backcompat_hack( + self, + param_env: ty::ParamEnv<'tcx>, + ct: ty::Unevaluated<'tcx>, + span: Option, + ) -> EvalToValTreeResult<'tcx> { + let param_env_reveal_all = ty::ParamEnv::new( + self.normalize_opaque_types(param_env.caller_bounds()), + Reveal::All, + param_env.constness(), + ); + + match self.const_eval_resolve_for_typeck(param_env_reveal_all, ct, span) { + Ok(Some(v)) => { + let local_def_id = ct.def.did.as_local().unwrap_or(CRATE_DEF_ID); + self.struct_span_lint_hir( + rustc_session::lint::builtin::HIDDEN_TYPE_OF_OPAQUE_TYPES_IN_TYPE_SYSTEM, + self.hir().local_def_id_to_hir_id(local_def_id), + self.def_span(ct.def.did), + |err| { + err.build( + "relying on the underlying type of an opaque type in the type system", + ) + .note("evaluating this constant relies on the underlying type of an opaque type") + .emit() + }, + ); + Ok(Some(v)) + } + res => res, + } + } + #[instrument(level = "debug", skip(self))] pub fn const_eval_resolve_for_typeck( self, @@ -78,13 +115,22 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { + let result = match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: ct.promoted }; self.const_eval_global_id_for_typeck(param_env, cid, span) } Ok(None) => Err(ErrorHandled::TooGeneric), Err(error_reported) => Err(ErrorHandled::Reported(error_reported)), + }; + + match result { + Err(ErrorHandled::TooGeneric) + if param_env.reveal() != Reveal::All && !ct.needs_subst() => + { + self.const_eval_resolve_for_typeck_backcompat_hack(param_env, ct, span) + } + result => result, } } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 69ad1f020fd51..254bc4ab66386 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -186,7 +186,10 @@ pub fn is_const_evaluatable<'cx, 'tcx>( let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); match concrete { Err(ErrorHandled::TooGeneric) => { - Err(NotConstEvaluatable::Error(infcx.concrete_ctfe_failure_error(span))) + Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug( + span, + format!("Missing value for constant, but no error reported?"), + ))) } Err(ErrorHandled::Linted) => { let reported = infcx @@ -234,10 +237,11 @@ pub fn is_const_evaluatable<'cx, 'tcx>( Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { NotConstEvaluatable::MentionsInfer - } else if uv.has_param_types_or_consts() { + } else if uv.has_param_types_or_consts() { NotConstEvaluatable::MentionsParam } else { - NotConstEvaluatable::Error(infcx.concrete_ctfe_failure_error(span)) + let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?")); + NotConstEvaluatable::Error(guar) }), Err(ErrorHandled::Linted) => { let reported = diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs b/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs index a30740466d3aa..faa8b3d10de4f 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs +++ b/src/test/ui/const-generics/generic_const_exprs/issue-76595.rs @@ -14,5 +14,4 @@ fn test() where Bool<{core::mem::size_of::() > 4}>: True { fn main() { test::<2>(); //~^ ERROR this function takes 2 generic arguments - //~| ERROR unable to use constant with a hidden value in the type system } diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr index 35269a2445a32..c587a7e153fe3 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-76595.stderr @@ -16,15 +16,6 @@ help: add missing generic argument LL | test::<2, P>(); | +++ -error: unable to use constant with a hidden value in the type system - --> $DIR/issue-76595.rs:15:5 - | -LL | test::<2>(); - | ^^^^^^^^^ - | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/const-generics/issues/issue-86530.rs b/src/test/ui/const-generics/issues/issue-86530.rs index 50d49dfe21e85..b024decd4e11c 100644 --- a/src/test/ui/const-generics/issues/issue-86530.rs +++ b/src/test/ui/const-generics/issues/issue-86530.rs @@ -15,7 +15,6 @@ where fn unit_literals() { z(" "); //~^ ERROR: the trait bound `&str: X` is not satisfied - //~| ERROR: unable to use constant with a hidden value in the type system } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-86530.stderr b/src/test/ui/const-generics/issues/issue-86530.stderr index be6e664facd23..c63857b2314e9 100644 --- a/src/test/ui/const-generics/issues/issue-86530.stderr +++ b/src/test/ui/const-generics/issues/issue-86530.stderr @@ -1,12 +1,3 @@ -error: unable to use constant with a hidden value in the type system - --> $DIR/issue-86530.rs:16:5 - | -LL | z(" "); - | ^ - | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types - error[E0277]: the trait bound `&str: X` is not satisfied --> $DIR/issue-86530.rs:16:7 | @@ -24,6 +15,6 @@ LL | where LL | T: X, | ^ required by this bound in `z` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs index 2988d063b76c5..6bdea1a6e4027 100644 --- a/src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs +++ b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.rs @@ -2,6 +2,8 @@ // This was used in https://github.com/GoldsteinE/name-it. // // See that PR for more details. +// +// check-pass use std::mem; fn returns_opaque() -> impl Sized { 0u8 @@ -9,7 +11,8 @@ fn returns_opaque() -> impl Sized { struct NamedOpaqueType { data: [mem::MaybeUninit; size_of_fut(returns_opaque)] - //~^ ERROR unable to use constant with a hidden value in the type system + //~^ WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler } const fn size_of_fut(x: fn() -> FUT) -> usize { diff --git a/src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr index f47d7fbb81176..a86e1e474f038 100644 --- a/src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr +++ b/src/test/ui/impl-trait/in-ctfe/array-len-size-of.stderr @@ -1,11 +1,13 @@ -error: unable to use constant with a hidden value in the type system - --> $DIR/array-len-size-of.rs:11:11 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/array-len-size-of.rs:13:34 | LL | data: [mem::MaybeUninit; size_of_fut(returns_opaque)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types + = note: `#[warn(hidden_type_of_opaque_types_in_type_system)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: aborting due to previous error +warning: 1 warning emitted diff --git a/src/test/ui/impl-trait/in-ctfe/array-len.rs b/src/test/ui/impl-trait/in-ctfe/array-len.rs index 4d7fac09f3e73..425b93f9e2d2b 100644 --- a/src/test/ui/impl-trait/in-ctfe/array-len.rs +++ b/src/test/ui/impl-trait/in-ctfe/array-len.rs @@ -1,6 +1,8 @@ // This previously compiled, but was intentionally changed in #101478. // // See that PR for more details. +// +// check-pass trait MyTrait: Copy { const ASSOC: usize; } @@ -19,7 +21,9 @@ const fn output(_: T) -> usize { fn main() { let x = [0u8; output(yeet())]; - //~^ ERROR unable to use constant with a hidden value in the type system + //~^ WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler + //~| WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler println!("{:?}", x); - //~^ ERROR unable to use constant with a hidden value in the type system } diff --git a/src/test/ui/impl-trait/in-ctfe/array-len.stderr b/src/test/ui/impl-trait/in-ctfe/array-len.stderr index 6caef9894eabb..a852d71dcb411 100644 --- a/src/test/ui/impl-trait/in-ctfe/array-len.stderr +++ b/src/test/ui/impl-trait/in-ctfe/array-len.stderr @@ -1,21 +1,23 @@ -error: unable to use constant with a hidden value in the type system - --> $DIR/array-len.rs:21:19 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/array-len.rs:23:19 | LL | let x = [0u8; output(yeet())]; | ^^^^^^^^^^^^^^ | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types + = note: `#[warn(hidden_type_of_opaque_types_in_type_system)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: unable to use constant with a hidden value in the type system - --> $DIR/array-len.rs:23:22 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/array-len.rs:23:19 | -LL | println!("{:?}", x); - | ^ +LL | let x = [0u8; output(yeet())]; + | ^^^^^^^^^^^^^^ | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: aborting due to 2 previous errors +warning: 2 warnings emitted diff --git a/src/test/ui/impl-trait/in-ctfe/enum-discr.rs b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs index c44411b72aa2b..53c0bdcd030eb 100644 --- a/src/test/ui/impl-trait/in-ctfe/enum-discr.rs +++ b/src/test/ui/impl-trait/in-ctfe/enum-discr.rs @@ -1,6 +1,8 @@ // This previously compiled, but was intentionally changed in #101478. // // See that PR for more details. +// +// check-pass trait MyTrait: Copy { const ASSOC: usize; } @@ -20,7 +22,8 @@ const fn output(_: T) -> usize { #[repr(usize)] enum Foo { Bar = output(yeet()), - //~^ ERROR unable to use constant with a hidden value in the type system + //~^ WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler } fn main() { diff --git a/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr b/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr index ad15ebb7f239f..e4f3a5dbf762c 100644 --- a/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr +++ b/src/test/ui/impl-trait/in-ctfe/enum-discr.stderr @@ -1,11 +1,13 @@ -error: unable to use constant with a hidden value in the type system - --> $DIR/enum-discr.rs:22:11 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/enum-discr.rs:24:11 | LL | Bar = output(yeet()), | ^^^^^^^^^^^^^^ | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types + = note: `#[warn(hidden_type_of_opaque_types_in_type_system)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: aborting due to previous error +warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index a63b246f9a519..966d76d148af3 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -1,6 +1,5 @@ fn main() { [1; >::VAL]; - //~^ ERROR unable to use constant with a hidden value in the type system } trait TypeVal { const VAL: T; diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index 9bb26f1671192..ca256847b1f3b 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `PhantomData` in this scope - --> $DIR/issue-77919.rs:10:9 + --> $DIR/issue-77919.rs:9:9 | LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> $DIR/issue-77919.rs:12:63 + --> $DIR/issue-77919.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | - ^^^ not found in this scope @@ -18,7 +18,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | help: you might be missing a type parameter: `, VAL` error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:12:1 + --> $DIR/issue-77919.rs:11:1 | LL | const VAL: T; | ------------ `VAL` from trait @@ -26,16 +26,7 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error: unable to use constant with a hidden value in the type system - --> $DIR/issue-77919.rs:2:9 - | -LL | [1; >::VAL]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0412. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/specialization/ctfe/default-assoc-const.rs b/src/test/ui/specialization/ctfe/default-assoc-const.rs index 896c2a3743135..3d091c93ad34d 100644 --- a/src/test/ui/specialization/ctfe/default-assoc-const.rs +++ b/src/test/ui/specialization/ctfe/default-assoc-const.rs @@ -1,6 +1,8 @@ // ICE fixed by #101478. // // See that PR for more details. +// +// check-pass #![feature(specialization)] //~^ WARNING the feature `specialization` is incomplete and may not be safe to use @@ -15,8 +17,10 @@ impl Foo for u32 { fn foo() -> [u8; 0] { [0; ::ASSOC] - //~^ ERROR unable to use constant with a hidden value in the type system - //~| ERROR mismatched types + //~^ WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler + //~| WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler } fn main() {} diff --git a/src/test/ui/specialization/ctfe/default-assoc-const.stderr b/src/test/ui/specialization/ctfe/default-assoc-const.stderr index aaf5c4978e7a5..1093754771ebf 100644 --- a/src/test/ui/specialization/ctfe/default-assoc-const.stderr +++ b/src/test/ui/specialization/ctfe/default-assoc-const.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-assoc-const.rs:4:12 + --> $DIR/default-assoc-const.rs:6:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -8,26 +8,26 @@ LL | #![feature(specialization)] = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete -error[E0308]: mismatched types - --> $DIR/default-assoc-const.rs:17:5 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/default-assoc-const.rs:19:9 | -LL | fn foo() -> [u8; 0] { - | ------- expected `[u8; 0]` because of return type LL | [0; ::ASSOC] - | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `0`, found `::ASSOC` + | ^^^^^^^^^^^^^^^^^^^ | - = note: expected array `[u8; 0]` - found array `[u8; _]` + = note: `#[warn(hidden_type_of_opaque_types_in_type_system)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: unable to use constant with a hidden value in the type system - --> $DIR/default-assoc-const.rs:17:9 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/default-assoc-const.rs:19:9 | LL | [0; ::ASSOC] | ^^^^^^^^^^^^^^^^^^^ | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: aborting due to 2 previous errors; 1 warning emitted +warning: 3 warnings emitted -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/specialization/ctfe/default-assoc-type.rs b/src/test/ui/specialization/ctfe/default-assoc-type.rs index fbaab89a2d834..89dabf108ec36 100644 --- a/src/test/ui/specialization/ctfe/default-assoc-type.rs +++ b/src/test/ui/specialization/ctfe/default-assoc-type.rs @@ -1,6 +1,8 @@ // ICE fixed by #101478. // // See that PR for more details. +// +// check-pass #![feature(specialization)] //~^ WARNING the feature `specialization` is incomplete and may not be safe to use @@ -22,8 +24,10 @@ impl Trait for u32 { fn foo() -> [u8; 0] { [0; < as Foo>::Assoc as Trait>::ASSOC] - //~^ ERROR unable to use constant with a hidden value in the type system - //~| ERROR mismatched types + //~^ WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler + //~| WARNING relying on the underlying type of an opaque type in the type system + //~| WARNING this was previously accepted by the compiler } fn main() {} diff --git a/src/test/ui/specialization/ctfe/default-assoc-type.stderr b/src/test/ui/specialization/ctfe/default-assoc-type.stderr index c9716667fb25d..4d0e69430d950 100644 --- a/src/test/ui/specialization/ctfe/default-assoc-type.stderr +++ b/src/test/ui/specialization/ctfe/default-assoc-type.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-assoc-type.rs:4:12 + --> $DIR/default-assoc-type.rs:6:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -8,26 +8,26 @@ LL | #![feature(specialization)] = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete -error[E0308]: mismatched types - --> $DIR/default-assoc-type.rs:24:5 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/default-assoc-type.rs:26:9 | -LL | fn foo() -> [u8; 0] { - | ------- expected `[u8; 0]` because of return type LL | [0; < as Foo>::Assoc as Trait>::ASSOC] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `0`, found `< as Foo>::Assoc as Trait>::ASSOC` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected array `[u8; 0]` - found array `[u8; _]` + = note: `#[warn(hidden_type_of_opaque_types_in_type_system)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: unable to use constant with a hidden value in the type system - --> $DIR/default-assoc-type.rs:24:9 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/default-assoc-type.rs:26:9 | LL | [0; < as Foo>::Assoc as Trait>::ASSOC] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this most often happens when trying to look into an opaque type - = note: the type system cannot access the hidden type of opaque types + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: evaluating this constant relies on the underlying type of an opaque type -error: aborting due to 2 previous errors; 1 warning emitted +warning: 3 warnings emitted -For more information about this error, try `rustc --explain E0308`. From f112c3794e174184895d8bba93d94257186a1afe Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 16 Sep 2022 20:24:44 +0200 Subject: [PATCH 13/13] use future compat lint for transmute as well --- compiler/rustc_typeck/src/check/expr.rs | 2 +- compiler/rustc_typeck/src/check/inherited.rs | 2 +- .../rustc_typeck/src/check/intrinsicck.rs | 151 ++++++++++++------ .../impl-trait/transmute/in-defining-scope.rs | 7 +- .../transmute/in-defining-scope.stderr | 64 +++++++- .../transmute/outside-of-defining-scope.rs | 6 +- .../outside-of-defining-scope.stderr | 13 +- .../transmute-specialization.rs | 4 +- .../transmute-specialization.stderr | 15 +- .../ui/type-alias-impl-trait/issue-53092-2.rs | 5 +- .../issue-53092-2.stderr | 31 +++- .../no_inferrable_concrete_type.stderr | 2 +- 12 files changed, 221 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 93b00850069c2..110f960f2dc10 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -541,7 +541,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // been resolved or we errored. This is important as we can only check transmute // on concrete types, but the output type may not be known yet (it would only // be known if explicitly specified via turbofish). - self.deferred_transmute_checks.borrow_mut().push((from, to, expr.span)); + self.deferred_transmute_checks.borrow_mut().push((from, to, expr.hir_id)); } if !tcx.features().unsized_fn_params { // We want to remove some Sized bounds from std functions, diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs index 37c830d4e3850..2546227e13858 100644 --- a/compiler/rustc_typeck/src/check/inherited.rs +++ b/compiler/rustc_typeck/src/check/inherited.rs @@ -55,7 +55,7 @@ pub struct Inherited<'a, 'tcx> { pub(super) deferred_cast_checks: RefCell>>, - pub(super) deferred_transmute_checks: RefCell, Ty<'tcx>, Span)>>, + pub(super) deferred_transmute_checks: RefCell, Ty<'tcx>, hir::HirId)>>, pub(super) deferred_asm_checks: RefCell, hir::HirId)>>, diff --git a/compiler/rustc_typeck/src/check/intrinsicck.rs b/compiler/rustc_typeck/src/check/intrinsicck.rs index d8fe63dbf084a..8913be0c85734 100644 --- a/compiler/rustc_typeck/src/check/intrinsicck.rs +++ b/compiler/rustc_typeck/src/check/intrinsicck.rs @@ -1,12 +1,14 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_hir as hir; +use rustc_hir::HirId; use rustc_index::vec::Idx; +use rustc_middle::traits::Reveal; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy}; use rustc_session::lint; -use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_span::{Symbol, DUMMY_SP}; use rustc_target::abi::{Pointer, VariantIdx}; use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType}; @@ -39,63 +41,108 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { ty } -impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) { - let convert = |ty: Ty<'tcx>| { - let ty = self.resolve_vars_if_possible(ty); - let ty = self.tcx.normalize_erasing_regions(self.param_env, ty); - (SizeSkeleton::compute(ty, self.tcx, self.param_env), ty) - }; - let (sk_from, from) = convert(from); - let (sk_to, to) = convert(to); +fn inner_check_transmute<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + hir_id: HirId, + from: Ty<'tcx>, + to: Ty<'tcx>, +) -> Result<(), ErrorGuaranteed> { + let convert = |ty: Ty<'tcx>| { + let ty = tcx.normalize_erasing_regions(param_env, ty); + (SizeSkeleton::compute(ty, tcx, param_env), ty) + }; + let (sk_from, from) = convert(from); + let (sk_to, to) = convert(to); - // Check for same size using the skeletons. - if let (Ok(sk_from), Ok(sk_to)) = (sk_from, sk_to) { - if sk_from.same_size(sk_to) { - return; - } + // Check for same size using the skeletons. + if let (Ok(sk_from), Ok(sk_to)) = (sk_from, sk_to) { + if sk_from.same_size(sk_to) { + return Ok(()); + } - // Special-case transmuting from `typeof(function)` and - // `Option` to present a clearer error. - let from = unpack_option_like(self.tcx, from); - if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&self.tcx) { - struct_span_err!(self.tcx.sess, span, E0591, "can't transmute zero-sized type") - .note(&format!("source type: {from}")) - .note(&format!("target type: {to}")) - .help("cast with `as` to a pointer instead") - .emit(); - return; - } + // Special-case transmuting from `typeof(function)` and + // `Option` to present a clearer error. + let from = unpack_option_like(tcx, from); + if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&tcx) { + let err = struct_span_err!( + tcx.sess, + tcx.hir().span(hir_id), + E0591, + "can't transmute zero-sized type", + ) + .note(&format!("source type: {from}")) + .note(&format!("target type: {to}")) + .help("cast with `as` to a pointer instead") + .emit(); + return Err(err); } + } - // Try to display a sensible error with as much information as possible. - let skeleton_string = |ty: Ty<'tcx>, sk| match sk { - Ok(SizeSkeleton::Known(size)) => format!("{} bits", size.bits()), - Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), - Err(LayoutError::Unknown(bad)) => { - if bad == ty { - "this type does not have a fixed size".to_owned() - } else { - format!("size can vary because of {bad}") - } + // HACK: We retry with `Reveal::All` for backwards + // compatability reasons, see #101478 for more details. + if param_env.reveal() != Reveal::All { + let param_env_reveal_all = ty::ParamEnv::new( + tcx.normalize_opaque_types(param_env.caller_bounds()), + Reveal::All, + param_env.constness(), + ); + + match inner_check_transmute(tcx, param_env_reveal_all, hir_id, from, to) { + Ok(()) => { + tcx.struct_span_lint_hir( + rustc_session::lint::builtin::HIDDEN_TYPE_OF_OPAQUE_TYPES_IN_TYPE_SYSTEM, + hir_id, + tcx.hir().span(hir_id), + |err| { + err.build( + "relying on the underlying type of an opaque type in the type system", + ) + .note("checking whether this transmute is valid relies on the underlying type of an opaque type") + .emit() + }, + ); + return Ok(()); } - Err(err) => err.to_string(), - }; + Err(e) => return Err(e), + } + } - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0512, - "cannot transmute between types of different sizes, \ - or dependently-sized types" - ); - if from == to { - err.note(&format!("`{from}` does not have a fixed size")); - } else { - err.note(&format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) - .note(&format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); + // Try to display a sensible error with as much information as possible. + let skeleton_string = |ty: Ty<'tcx>, sk| match sk { + Ok(SizeSkeleton::Known(size)) => format!("{} bits", size.bits()), + Ok(SizeSkeleton::Pointer { tail, .. }) => format!("pointer to `{tail}`"), + Err(LayoutError::Unknown(bad)) => { + if bad == ty { + "this type does not have a fixed size".to_owned() + } else { + format!("size can vary because of {bad}") + } } - err.emit(); + Err(err) => err.to_string(), + }; + + let mut err = struct_span_err!( + tcx.sess, + tcx.hir().span(hir_id), + E0512, + "cannot transmute between types of different sizes, \ + or dependently-sized types" + ); + if from == to { + err.note(&format!("`{from}` does not have a fixed size")); + } else { + err.note(&format!("source type: `{}` ({})", from, skeleton_string(from, sk_from))) + .note(&format!("target type: `{}` ({})", to, skeleton_string(to, sk_to))); + } + Err(err.emit()) +} + +impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + pub fn check_transmute(&self, hir_id: HirId, from: Ty<'tcx>, to: Ty<'tcx>) { + let from = self.resolve_vars_if_possible(from); + let to = self.resolve_vars_if_possible(to); + let _ = inner_check_transmute(self.tcx, self.param_env, hir_id, from, to); } } diff --git a/src/test/ui/impl-trait/transmute/in-defining-scope.rs b/src/test/ui/impl-trait/transmute/in-defining-scope.rs index 896ce9136cedb..eacd1e8cf301d 100644 --- a/src/test/ui/impl-trait/transmute/in-defining-scope.rs +++ b/src/test/ui/impl-trait/transmute/in-defining-scope.rs @@ -1,11 +1,14 @@ -// This previously caused a query cycle which changed in #101478. +// This causes a query cycle due to incorrectly using `Reveal::All`, +// in #101478 this was changed to a future compat error which only +// triggers after the query cycle. // // See that PR for more details. use std::mem::transmute; fn foo() -> impl Sized { + //~^ ERROR cycle detected when computing type of unsafe { transmute::<_, u8>(foo()); - //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types + //~^ ERROR cannot transmute between types of different sizes } 0u8 } diff --git a/src/test/ui/impl-trait/transmute/in-defining-scope.stderr b/src/test/ui/impl-trait/transmute/in-defining-scope.stderr index 1a3c856afd0f8..d00d4eca59999 100644 --- a/src/test/ui/impl-trait/transmute/in-defining-scope.stderr +++ b/src/test/ui/impl-trait/transmute/in-defining-scope.stderr @@ -1,12 +1,68 @@ +error[E0391]: cycle detected when computing type of `foo::{opaque#0}` + --> $DIR/in-defining-scope.rs:7:13 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^ + | +note: ...which requires borrow-checking `foo`... + --> $DIR/in-defining-scope.rs:7:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing `foo`... + --> $DIR/in-defining-scope.rs:7:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing MIR for `foo`... + --> $DIR/in-defining-scope.rs:7:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires unsafety-checking `foo`... + --> $DIR/in-defining-scope.rs:7:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building MIR for `foo`... + --> $DIR/in-defining-scope.rs:7:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building THIR for `foo`... + --> $DIR/in-defining-scope.rs:7:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires type-checking `foo`... + --> $DIR/in-defining-scope.rs:7:1 + | +LL | fn foo() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `impl Sized`... + = note: ...which again requires computing type of `foo::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/in-defining-scope.rs:6:1 + | +LL | / use std::mem::transmute; +LL | | fn foo() -> impl Sized { +LL | | +LL | | unsafe { +... | +LL | | +LL | | fn main() {} + | |____________^ + error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/in-defining-scope.rs:7:9 + --> $DIR/in-defining-scope.rs:10:9 | LL | transmute::<_, u8>(foo()); | ^^^^^^^^^^^^^^^^^^ | - = note: source type: `impl Sized` (this type does not have a fixed size) + = note: source type: `[type error]` (this type does not have a fixed size) = note: target type: `u8` (8 bits) -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0512`. +Some errors have detailed explanations: E0391, E0512. +For more information about an error, try `rustc --explain E0391`. diff --git a/src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs index ec7fabfa0fa26..94c851e396a89 100644 --- a/src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs +++ b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.rs @@ -1,6 +1,9 @@ // This previously compiled, but was intentionally changed in #101478. +// Lowered back to a future compat lint. // // See that PR for more details. +// +// check-pass use std::mem::transmute; fn foo() -> impl Sized { 0u8 @@ -9,6 +12,7 @@ fn foo() -> impl Sized { fn main() { unsafe { transmute::<_, u8>(foo()); - //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types + //~^ WARN relying on the underlying type of an opaque type in the type system + //~| WARN this was previously accepted by the compiler but is being phased out } } diff --git a/src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr index 4d69718a36c92..5c311d2c7a364 100644 --- a/src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr +++ b/src/test/ui/impl-trait/transmute/outside-of-defining-scope.stderr @@ -1,12 +1,13 @@ -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/outside-of-defining-scope.rs:11:9 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/outside-of-defining-scope.rs:14:9 | LL | transmute::<_, u8>(foo()); | ^^^^^^^^^^^^^^^^^^ | - = note: source type: `impl Sized` (this type does not have a fixed size) - = note: target type: `u8` (8 bits) + = note: `#[warn(hidden_type_of_opaque_types_in_type_system)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: checking whether this transmute is valid relies on the underlying type of an opaque type -error: aborting due to previous error +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/specialization/transmute-specialization.rs b/src/test/ui/specialization/transmute-specialization.rs index 3c4a0b869cb83..d2587cdce2226 100644 --- a/src/test/ui/specialization/transmute-specialization.rs +++ b/src/test/ui/specialization/transmute-specialization.rs @@ -1,3 +1,4 @@ +// check-pass #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Specializable { type Output; } @@ -9,6 +10,7 @@ impl Specializable for T { fn main() { unsafe { std::mem::transmute::::Output>(0); - //~^ ERROR cannot transmute between types of different sizes + //~^ WARN relying on the underlying type of an opaque type in the type system + //~| WARN this was previously accepted by the compiler but is being phased out } } diff --git a/src/test/ui/specialization/transmute-specialization.stderr b/src/test/ui/specialization/transmute-specialization.stderr index 39ba33b00fa8b..5a15577816f6b 100644 --- a/src/test/ui/specialization/transmute-specialization.stderr +++ b/src/test/ui/specialization/transmute-specialization.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/transmute-specialization.rs:1:12 + --> $DIR/transmute-specialization.rs:2:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -8,15 +8,16 @@ LL | #![feature(specialization)] = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-specialization.rs:11:9 +warning: relying on the underlying type of an opaque type in the type system + --> $DIR/transmute-specialization.rs:12:9 | LL | std::mem::transmute::::Output>(0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: source type: `u16` (16 bits) - = note: target type: `<() as Specializable>::Output` (this type does not have a fixed size) + = note: `#[warn(hidden_type_of_opaque_types_in_type_system)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue # + = note: checking whether this transmute is valid relies on the underlying type of an opaque type -error: aborting due to previous error; 1 warning emitted +warning: 2 warnings emitted -For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.rs b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs index a3070c8e93eaa..1f8169683482d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53092-2.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs @@ -1,13 +1,14 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -type Bug = impl Fn(T) -> U + Copy; +type Bug = impl Fn(T) -> U + Copy; //~ ERROR cycle detected const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; //~^ ERROR: cannot transmute fn make_bug>() -> Bug { - |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied + |x| x.into() + //~^ ERROR the trait bound `U: From` is not satisfied } fn main() { diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr index 8fcf4a6d2bc48..1f51652c70731 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -1,3 +1,28 @@ +error[E0391]: cycle detected when computing type of `Bug::{opaque#0}` + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `CONST_BUG`... + --> $DIR/issue-53092-2.rs:6:1 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires normalizing `Bug`... + = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/issue-53092-2.rs:1:1 + | +LL | / #![feature(type_alias_impl_trait)] +LL | | #![allow(dead_code)] +LL | | +LL | | type Bug = impl Fn(T) -> U + Copy; +... | +LL | | CONST_BUG(0); +LL | | } + | |_^ + error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/issue-53092-2.rs:6:41 | @@ -5,7 +30,7 @@ LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; | ^^^^^^^^^^^^^^^^^^^ | = note: source type: `[closure@$DIR/issue-53092-2.rs:6:61: 6:68]` (0 bits) - = note: target type: `Bug` (this type does not have a fixed size) + = note: target type: `[type error]` (this type does not have a fixed size) error[E0277]: the trait bound `U: From` is not satisfied --> $DIR/issue-53092-2.rs:10:5 @@ -23,7 +48,7 @@ help: consider restricting type parameter `U` LL | type Bug> = impl Fn(T) -> U + Copy; | +++++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0512. +Some errors have detailed explanations: E0277, E0391, E0512. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index 3f3d337a82d20..7434b75ca1e8b 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -13,7 +13,7 @@ LL | let _: foo::Foo = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^ | = note: source type: `u8` (8 bits) - = note: target type: `Foo` (this type does not have a fixed size) + = note: target type: `[type error]` (this type does not have a fixed size) error: aborting due to 2 previous errors