diff options
Diffstat (limited to 'compiler/rustc_middle')
24 files changed, 137 insertions, 497 deletions
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 4c238308fe8..bb8e774cea3 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -13,7 +13,7 @@ gsgdt = "0.1.2" field-offset = "0.3.5" measureme = "10.0.0" polonius-engine = "0.13.0" -rustc_apfloat = { path = "../rustc_apfloat" } +rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index cd1c6c330bc..fca16d8e509 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -43,7 +43,7 @@ macro_rules! span_bug { #[macro_export] macro_rules! CloneLiftImpls { - ($($ty:ty,)+) => { + ($($ty:ty),+ $(,)?) => { $( impl<'tcx> $crate::ty::Lift<'tcx> for $ty { type Lifted = Self; @@ -59,7 +59,7 @@ macro_rules! CloneLiftImpls { /// allocated data** (i.e., don't need to be folded). #[macro_export] macro_rules! TrivialTypeTraversalImpls { - ($($ty:ty,)+) => { + ($($ty:ty),+ $(,)?) => { $( impl<'tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<'tcx>> for $ty { fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<'tcx>>>( diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index 7722e7b47cf..0ad17e819c7 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -178,9 +178,7 @@ impl<'tcx> graph::WithPredecessors for BasicBlocks<'tcx> { } } -TrivialTypeTraversalAndLiftImpls! { - Cache, -} +TrivialTypeTraversalAndLiftImpls! { Cache } impl<S: Encoder> Encodable<S> for Cache { #[inline] diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index b8030d9db13..c1cb2f2e497 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -571,7 +571,7 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes> assert!(self.mutability == Mutability::Mut); // `to_bits_or_ptr_internal` is the right method because we just want to store this data - // as-is into memory. + // as-is into memory. This also double-checks that `val.size()` matches `range.size`. let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? { Right(ptr) => { let (provenance, offset) = ptr.into_parts(); diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 1bcef17d73b..6161b16fc46 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -12,7 +12,8 @@ use rustc_errors::{ use rustc_macros::HashStable; use rustc_session::CtfeBacktrace; use rustc_span::def_id::DefId; -use rustc_target::abi::{call, Align, Size, WrappingRange}; +use rustc_target::abi::{call, Align, Size, VariantIdx, WrappingRange}; + use std::borrow::Cow; use std::{any::Any, backtrace::Backtrace, fmt}; @@ -66,9 +67,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo { } } -TrivialTypeTraversalAndLiftImpls! { - ErrorHandled, -} +TrivialTypeTraversalAndLiftImpls! { ErrorHandled } pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>; pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>; @@ -191,9 +190,8 @@ pub enum InvalidProgramInfo<'tcx> { FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), /// SizeOf of unsized type was requested. SizeOfUnsizedType(Ty<'tcx>), - /// An unsized local was accessed without having been initialized. - /// This is not meaningful as we can't even have backing memory for such locals. - UninitUnsizedLocal, + /// We are runnning into a nonsense situation due to ConstProp violating our invariants. + ConstPropNonsense, } /// Details of why a pointer had to be in-bounds. @@ -324,7 +322,9 @@ pub enum UndefinedBehaviorInfo<'a> { /// Data size is not equal to target size. ScalarSizeMismatch(ScalarSizeMismatch), /// A discriminant of an uninhabited enum variant is written. - UninhabitedEnumVariantWritten, + UninhabitedEnumVariantWritten(VariantIdx), + /// An uninhabited enum variant is projected. + UninhabitedEnumVariantRead(VariantIdx), /// Validation error. Validation(ValidationErrorInfo<'a>), // FIXME(fee1-dead) these should all be actual variants of the enum instead of dynamically @@ -388,11 +388,13 @@ pub enum ValidationErrorKind<'tcx> { MutableRefInConst, NullFnPtr, NeverVal, + NullablePtrOutOfRange { range: WrappingRange, max_value: u128 }, PtrOutOfRange { range: WrappingRange, max_value: u128 }, OutOfRange { value: String, range: WrappingRange, max_value: u128 }, UnsafeCell, UninhabitedVal { ty: Ty<'tcx> }, InvalidEnumTag { value: String }, + UninhabitedEnumTag, UninitEnumTag, UninitStr, Uninit { expected: ExpectedKind }, diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index c8133bcc387..65d04919357 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -19,19 +19,33 @@ pub trait PointerArithmetic: HasDataLayout { #[inline(always)] fn max_size_of_val(&self) -> Size { - Size::from_bytes(self.data_layout().target_isize_max()) + Size::from_bytes(self.target_isize_max()) + } + + #[inline] + fn target_usize_max(&self) -> u64 { + self.pointer_size().unsigned_int_max().try_into().unwrap() + } + + #[inline] + fn target_isize_min(&self) -> i64 { + self.pointer_size().signed_int_min().try_into().unwrap() + } + + #[inline] + fn target_isize_max(&self) -> i64 { + self.pointer_size().signed_int_max().try_into().unwrap() } #[inline] fn target_usize_to_isize(&self, val: u64) -> i64 { - let dl = self.data_layout(); let val = val as i64; // Now wrap-around into the machine_isize range. - if val > dl.target_isize_max() { + if val > self.target_isize_max() { // This can only happen if the ptr size is < 64, so we know max_usize_plus_1 fits into // i64. - debug_assert!(dl.pointer_size.bits() < 64); - let max_usize_plus_1 = 1u128 << dl.pointer_size.bits(); + debug_assert!(self.pointer_size().bits() < 64); + let max_usize_plus_1 = 1u128 << self.pointer_size().bits(); val - i64::try_from(max_usize_plus_1).unwrap() } else { val @@ -44,7 +58,7 @@ pub trait PointerArithmetic: HasDataLayout { #[inline] fn truncate_to_ptr(&self, (val, over): (u64, bool)) -> (u64, bool) { let val = u128::from(val); - let max_ptr_plus_1 = 1u128 << self.data_layout().pointer_size.bits(); + let max_ptr_plus_1 = 1u128 << self.pointer_size().bits(); (u64::try_from(val % max_ptr_plus_1).unwrap(), over || val >= max_ptr_plus_1) } @@ -62,11 +76,11 @@ pub trait PointerArithmetic: HasDataLayout { let n = i.unsigned_abs(); if i >= 0 { let (val, over) = self.overflowing_offset(val, n); - (val, over || i > self.data_layout().target_isize_max()) + (val, over || i > self.target_isize_max()) } else { let res = val.overflowing_sub(n); let (val, over) = self.truncate_to_ptr(res); - (val, over || i < self.data_layout().target_isize_min()) + (val, over || i < self.target_isize_min()) } } diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index c9db0e7c11d..fc659ce18a4 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -139,7 +139,6 @@ impl<'tcx> TyCtxt<'tcx> { cid: GlobalId<'tcx>, span: Option<Span>, ) -> EvalToConstValueResult<'tcx> { - let param_env = param_env.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.erase_regions(param_env.and(cid)); @@ -158,8 +157,6 @@ impl<'tcx> TyCtxt<'tcx> { cid: GlobalId<'tcx>, span: Option<Span>, ) -> EvalToValTreeResult<'tcx> { - let param_env = param_env.with_const(); - debug!(?param_env); // Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should // improve caching of queries. let inputs = self.erase_regions(param_env.and(cid)); @@ -204,7 +201,6 @@ impl<'tcx> TyCtxtAt<'tcx> { gid: GlobalId<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> { - let param_env = param_env.with_const(); trace!("eval_to_allocation: Need to compute {:?}", gid); let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?; Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory()) @@ -224,8 +220,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> { let args = GenericArgs::identity_for_item(self.tcx, def_id); let instance = ty::Instance::new(def_id, args); 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(def_id).with_reveal_all_normalized(self.tcx); // 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)); @@ -238,7 +233,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> { assert!(self.tcx.is_static(def_id)); let instance = ty::Instance::mono(self.tcx, def_id); let gid = GlobalId { instance, promoted: None }; - let param_env = ty::ParamEnv::reveal_all().with_const(); + let param_env = ty::ParamEnv::reveal_all(); trace!("eval_to_allocation: Need to compute {:?}", gid); self.eval_to_allocation_raw(param_env.and(gid)) } diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 0416411dfe1..47421d0f037 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -320,6 +320,14 @@ impl<Prov> Scalar<Prov> { } }) } + + #[inline] + pub fn size(self) -> Size { + match self { + Scalar::Int(int) => int.size(), + Scalar::Ptr(_ptr, sz) => Size::from_bytes(sz), + } + } } impl<'tcx, Prov: Provenance> Scalar<Prov> { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 97f53a59fd6..3a958548515 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -706,9 +706,7 @@ pub enum BindingForm<'tcx> { RefForGuard, } -TrivialTypeTraversalAndLiftImpls! { - BindingForm<'tcx>, -} +TrivialTypeTraversalAndLiftImpls! { BindingForm<'tcx> } mod binding_form_impl { use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 9bf02267005..2c481745d98 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -111,11 +111,6 @@ impl EraseType >()]; } -impl EraseType for Result<ty::layout::TyAndNaiveLayout<'_>, &ty::layout::LayoutError<'_>> { - type Result = - [u8; size_of::<Result<ty::layout::TyAndNaiveLayout<'_>, &ty::layout::LayoutError<'_>>>()]; -} - impl EraseType for Result<ty::Const<'_>, mir::interpret::LitToConstError> { type Result = [u8; size_of::<Result<ty::Const<'static>, mir::interpret::LitToConstError>>()]; } @@ -296,7 +291,6 @@ trivial! { rustc_span::Symbol, rustc_span::symbol::Ident, rustc_target::spec::PanicStrategy, - rustc_target::abi::ReferenceNichePolicy, rustc_type_ir::Variance, u32, usize, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b5b00b7b640..fb796587352 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1394,18 +1394,6 @@ rustc_queries! { desc { "computing layout of `{}`", key.value } } - /// Computes the naive layout approximation of a type. Note that this implicitly - /// executes in "reveal all" mode, and will normalize the input type. - /// - /// Unlike `layout_of`, this doesn't look past references (beyond the `Pointee::Metadata` - /// projection), and as such can be called on generic types like `Option<&T>`. - query naive_layout_of( - key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> - ) -> Result<ty::layout::TyAndNaiveLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> { - depth_limit - desc { "computing layout (naive) of `{}`", key.value } - } - /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. /// /// NB: this doesn't handle virtual calls - those should use `fn_abi_of_instance` @@ -1481,11 +1469,6 @@ rustc_queries! { desc { "getting a crate's configured panic-in-drop strategy" } separate_provide_extern } - query reference_niches_policy(_: CrateNum) -> abi::ReferenceNichePolicy { - fatal_cycle - desc { "getting a crate's policy for size and alignment niches of references" } - separate_provide_extern - } query is_no_builtins(_: CrateNum) -> bool { fatal_cycle desc { "getting whether a crate has `#![no_builtins]`" } @@ -2081,9 +2064,9 @@ rustc_queries! { } } - query is_impossible_method(key: (DefId, DefId)) -> bool { + query is_impossible_associated_item(key: (DefId, DefId)) -> bool { desc { |tcx| - "checking if `{}` is impossible to call within `{}`", + "checking if `{}` is impossible to reference within `{}`", tcx.def_path_str(key.1), tcx.def_path_str(key.0), } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index b7ffed57a0b..a2b33bb2737 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -649,43 +649,31 @@ pub enum ImplSource<'tcx, N> { /// for some type parameter. The `Vec<N>` represents the /// obligations incurred from normalizing the where-clause (if /// any). - Param(Vec<N>, ty::BoundConstness), + Param(ty::BoundConstness, Vec<N>), - /// Virtual calls through an object. - Object(ImplSourceObjectData<N>), - - /// Successful resolution for a builtin trait. - Builtin(Vec<N>), - - /// ImplSource for trait upcasting coercion - TraitUpcasting(ImplSourceTraitUpcastingData<N>), + /// Successful resolution for a builtin impl. + Builtin(BuiltinImplSource, Vec<N>), } impl<'tcx, N> ImplSource<'tcx, N> { pub fn nested_obligations(self) -> Vec<N> { match self { ImplSource::UserDefined(i) => i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, - ImplSource::Object(d) => d.nested, - ImplSource::TraitUpcasting(d) => d.nested, + ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n, } } pub fn borrow_nested_obligations(&self) -> &[N] { match self { ImplSource::UserDefined(i) => &i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n, - ImplSource::Object(d) => &d.nested, - ImplSource::TraitUpcasting(d) => &d.nested, + ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => &n, } } pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] { match self { ImplSource::UserDefined(i) => &mut i.nested, - ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, - ImplSource::Object(d) => &mut d.nested, - ImplSource::TraitUpcasting(d) => &mut d.nested, + ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n, } } @@ -699,17 +687,9 @@ impl<'tcx, N> ImplSource<'tcx, N> { args: i.args, nested: i.nested.into_iter().map(f).collect(), }), - ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct), - ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()), - ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData { - vtable_base: o.vtable_base, - nested: o.nested.into_iter().map(f).collect(), - }), - ImplSource::TraitUpcasting(d) => { - ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData { - vtable_vptr_slot: d.vtable_vptr_slot, - nested: d.nested.into_iter().map(f).collect(), - }) + ImplSource::Param(ct, n) => ImplSource::Param(ct, n.into_iter().map(f).collect()), + ImplSource::Builtin(source, n) => { + ImplSource::Builtin(source, n.into_iter().map(f).collect()) } } } @@ -733,29 +713,31 @@ pub struct ImplSourceUserDefinedData<'tcx, N> { pub nested: Vec<N>, } -#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] -#[derive(TypeFoldable, TypeVisitable)] -pub struct ImplSourceTraitUpcastingData<N> { +#[derive(Copy, Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Debug)] +pub enum BuiltinImplSource { + /// Some builtin impl we don't need to differentiate. This should be used + /// unless more specific information is necessary. + Misc, + /// A builtin impl for trait objects. + /// + /// The vtable is formed by concatenating together the method lists of + /// the base object trait and all supertraits, pointers to supertrait vtable will + /// be provided when necessary; this is the start of `upcast_trait_ref`'s methods + /// in that vtable. + Object { vtable_base: usize }, /// The vtable is formed by concatenating together the method lists of /// the base object trait and all supertraits, pointers to supertrait vtable will /// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable /// within that vtable. - pub vtable_vptr_slot: Option<usize>, - - pub nested: Vec<N>, + TraitUpcasting { vtable_vptr_slot: Option<usize> }, + /// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`. + /// + /// This needs to be a separate variant as it is still unstable and we need to emit + /// a feature error when using it on stable. + TupleUnsizing, } -#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)] -#[derive(TypeFoldable, TypeVisitable)] -pub struct ImplSourceObjectData<N> { - /// The vtable is formed by concatenating together the method lists of - /// the base object trait and all supertraits, pointers to supertrait vtable will - /// be provided when necessary; this is the start of `upcast_trait_ref`'s methods - /// in that vtable. - pub vtable_base: usize, - - pub nested: Vec<N>, -} +TrivialTypeTraversalAndLiftImpls! { BuiltinImplSource } #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] pub enum ObjectSafetyViolation { diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index f2dda003b99..a90d58f5fc1 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -304,9 +304,7 @@ impl From<ErrorGuaranteed> for OverflowError { } } -TrivialTypeTraversalAndLiftImpls! { - OverflowError, -} +TrivialTypeTraversalAndLiftImpls! { OverflowError } impl<'tcx> From<OverflowError> for SelectionError<'tcx> { fn from(overflow_error: OverflowError) -> SelectionError<'tcx> { diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index 8698cf86022..e793f481995 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -73,8 +73,12 @@ pub struct GoalCandidate<'tcx> { pub enum CandidateKind<'tcx> { /// Probe entered when normalizing the self ty during candidate assembly NormalizedSelfTyAssembly, + DynUpcastingAssembly, /// A normal candidate for proving a goal - Candidate { name: String, result: QueryResult<'tcx> }, + Candidate { + name: String, + result: QueryResult<'tcx>, + }, } impl Debug for GoalCandidate<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs index f19f1189e44..39f84279259 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs @@ -15,11 +15,11 @@ struct Indentor<'a, 'b> { impl Write for Indentor<'_, '_> { fn write_str(&mut self, s: &str) -> std::fmt::Result { - for line in s.split_inclusive("\n") { + for line in s.split_inclusive('\n') { if self.on_newline { self.f.write_str(" ")?; } - self.on_newline = line.ends_with("\n"); + self.on_newline = line.ends_with('\n'); self.f.write_str(line)?; } @@ -100,6 +100,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> { CandidateKind::NormalizedSelfTyAssembly => { writeln!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:") } + CandidateKind::DynUpcastingAssembly => { + writeln!(self.f, "ASSEMBLING CANDIDATES FOR DYN UPCASTING:") + } CandidateKind::Candidate { name, result } => { writeln!(self.f, "CANDIDATE {}: {:?}", name, result) } diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index e2cd118500b..530d1ec5d35 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -6,18 +6,16 @@ use std::fmt; impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v), + match self { + super::ImplSource::UserDefined(v) => write!(f, "{:?}", v), - super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d), - - super::ImplSource::Object(ref d) => write!(f, "{:?}", d), + super::ImplSource::Builtin(source, d) => { + write!(f, "Builtin({source:?}, {d:?})") + } - super::ImplSource::Param(ref n, ct) => { + super::ImplSource::Param(ct, n) => { write!(f, "ImplSourceParamData({:?}, {:?})", n, ct) } - - super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d), } } } @@ -31,23 +29,3 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx, ) } } - -impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitUpcastingData<N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "ImplSourceTraitUpcastingData(vtable_vptr_slot={:?}, nested={:?})", - self.vtable_vptr_slot, self.nested - ) - } -} - -impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "ImplSourceObjectData(vtable_base={}, nested={:?})", - self.vtable_base, self.nested - ) - } -} diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 0364a620810..cdd8351499b 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -27,9 +27,7 @@ impl From<ErrorGuaranteed> for NotConstEvaluatable { } } -TrivialTypeTraversalAndLiftImpls! { - NotConstEvaluatable, -} +TrivialTypeTraversalAndLiftImpls! { NotConstEvaluatable } pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>; diff --git a/compiler/rustc_middle/src/ty/binding.rs b/compiler/rustc_middle/src/ty/binding.rs index a5b05a4f9b5..2fec8ac9095 100644 --- a/compiler/rustc_middle/src/ty/binding.rs +++ b/compiler/rustc_middle/src/ty/binding.rs @@ -6,7 +6,7 @@ pub enum BindingMode { BindByValue(Mutability), } -TrivialTypeTraversalAndLiftImpls! { BindingMode, } +TrivialTypeTraversalAndLiftImpls! { BindingMode } impl BindingMode { pub fn convert(BindingAnnotation(by_ref, mutbl): BindingAnnotation) -> BindingMode { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index b4f4f9bef8e..7c05deae90a 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -168,7 +168,6 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::ParamEnv<'tcx> { fn encode(&self, e: &mut E) { self.caller_bounds().encode(e); self.reveal().encode(e); - self.constness().encode(e); } } @@ -306,8 +305,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::ParamEnv<'tcx> { fn decode(d: &mut D) -> Self { let caller_bounds = Decodable::decode(d); let reveal = Decodable::decode(d); - let constness = Decodable::decode(d); - ty::ParamEnv::new(caller_bounds, reveal, constness) + ty::ParamEnv::new(caller_bounds, reveal) } } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index c794c3faded..3fdbaf5e947 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -339,12 +339,17 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { - let width = self.sess.diagnostic_width(); - let length_limit = width.saturating_sub(30); let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) .pretty_print_type(ty) .expect("could not write to `String`") .into_buffer(); + + if !self.sess.opts.unstable_opts.write_long_types_to_disk { + return (regular, None); + } + + let width = self.sess.diagnostic_width(); + let length_limit = width.saturating_sub(30); if regular.len() <= width { return (regular, None); } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 26137e86fa0..81e7dc3728a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -313,16 +313,7 @@ impl<'tcx> SizeSkeleton<'tcx> { ) -> Result<SizeSkeleton<'tcx>, &'tcx LayoutError<'tcx>> { debug_assert!(!ty.has_non_region_infer()); - // First, try computing an exact naive layout (this covers simple types with generic - // references, where a full static layout would fail). - if let Ok(layout) = tcx.naive_layout_of(param_env.and(ty)) { - if layout.exact { - return Ok(SizeSkeleton::Known(layout.size)); - } - } - - // Second, try computing a full static layout (this covers cases when the naive layout - // wasn't smart enough, but cannot deal with generic references). + // First try computing a static layout. let err = match tcx.layout_of(param_env.and(ty)) { Ok(layout) => { return Ok(SizeSkeleton::Known(layout.size)); @@ -336,7 +327,6 @@ impl<'tcx> SizeSkeleton<'tcx> { ) => return Err(e), }; - // Third, fall back to ad-hoc cases. match *ty.kind() { ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { let non_zero = !ty.is_unsafe_ptr(); @@ -631,219 +621,6 @@ impl<T, E> MaybeResult<T> for Result<T, E> { pub type TyAndLayout<'tcx> = rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>; -#[derive(Copy, Clone, Debug, HashStable)] -pub struct TyAndNaiveLayout<'tcx> { - pub ty: Ty<'tcx>, - pub layout: NaiveLayout, -} - -impl std::ops::Deref for TyAndNaiveLayout<'_> { - type Target = NaiveLayout; - fn deref(&self) -> &Self::Target { - &self.layout - } -} - -impl std::ops::DerefMut for TyAndNaiveLayout<'_> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.layout - } -} - -/// Extremely simplified approximation of a type's layout returned by the -/// `naive_layout_of` query. -#[derive(Copy, Clone, Debug, HashStable)] -pub struct NaiveLayout { - pub abi: NaiveAbi, - /// Niche information, required for tracking non-null enum optimizations. - pub niches: NaiveNiches, - /// An underestimate of the layout's size. - pub size: Size, - /// An underestimate of the layout's required alignment. - pub align: Align, - /// If `true`, `size` and `align` must be exact values. - pub exact: bool, -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] -pub enum NaiveNiches { - None, - Some, - Maybe, -} - -#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] -pub enum NaiveAbi { - /// A scalar layout, always implies `exact` and a non-zero `size`. - Scalar(Primitive), - /// An uninhabited layout. (needed to properly track `Scalar` and niches) - Uninhabited, - /// An unsized aggregate. (needed to properly track `Scalar` and niches) - Unsized, - /// Any other sized layout. - Sized, -} - -impl NaiveAbi { - #[inline] - pub fn as_aggregate(self) -> Self { - match self { - NaiveAbi::Scalar(_) => NaiveAbi::Sized, - _ => self, - } - } -} - -impl NaiveLayout { - /// The layout of an empty aggregate, e.g. `()`. - pub const EMPTY: Self = Self { - size: Size::ZERO, - align: Align::ONE, - exact: true, - abi: NaiveAbi::Sized, - niches: NaiveNiches::None, - }; - - /// Returns whether `self` is a valid approximation of the given full `layout`. - /// - /// This should always return `true` when both layouts are computed from the same type. - pub fn is_refined_by(&self, layout: Layout<'_>) -> bool { - if self.size > layout.size() || self.align > layout.align().abi { - return false; - } - - if let NaiveAbi::Scalar(prim) = self.abi { - if !self.exact - || self.size == Size::ZERO - || !matches!(layout.abi(), Abi::Scalar(s) if s.primitive() == prim) - { - return false; - } - } - - match (self.niches, layout.largest_niche()) { - (NaiveNiches::None, Some(_)) => return false, - (NaiveNiches::Some, None) => return false, - _ => (), - } - - !self.exact || (self.size, self.align) == (layout.size(), layout.align().abi) - } - - /// Returns if this layout is known to be pointer-like (`None` if uncertain) - /// - /// See the corresponding `Layout::is_pointer_like` method. - pub fn is_pointer_like(&self, dl: &TargetDataLayout) -> Option<bool> { - match self.abi { - NaiveAbi::Scalar(_) => { - assert!(self.exact); - Some(self.size == dl.pointer_size && self.align == dl.pointer_align.abi) - } - NaiveAbi::Uninhabited | NaiveAbi::Unsized => Some(false), - NaiveAbi::Sized if self.exact => Some(false), - NaiveAbi::Sized => None, - } - } - - /// Artificially lowers the alignment of this layout. - #[must_use] - #[inline] - pub fn packed(mut self, align: Align) -> Self { - if self.align > align { - self.align = align; - self.abi = self.abi.as_aggregate(); - } - self - } - - /// Artificially raises the alignment of this layout. - #[must_use] - #[inline] - pub fn align_to(mut self, align: Align) -> Self { - if align > self.align { - self.align = align; - self.abi = self.abi.as_aggregate(); - } - self - } - - /// Artificially makes this layout inexact. - #[must_use] - #[inline] - pub fn inexact(mut self) -> Self { - self.abi = self.abi.as_aggregate(); - self.exact = false; - self - } - - /// Pads this layout so that its size is a multiple of `align`. - #[must_use] - #[inline] - pub fn pad_to_align(mut self, align: Align) -> Self { - let new_size = self.size.align_to(align); - if new_size > self.size { - self.abi = self.abi.as_aggregate(); - self.size = new_size; - } - self - } - - /// Returns the layout of `self` immediately followed by `other`, without any - /// padding between them, as in a packed `struct` or tuple. - #[must_use] - #[inline] - pub fn concat(&self, other: &Self, dl: &TargetDataLayout) -> Option<Self> { - use NaiveAbi::*; - - let size = self.size.checked_add(other.size, dl)?; - let align = cmp::max(self.align, other.align); - let exact = self.exact && other.exact; - let abi = match (self.abi, other.abi) { - // The uninhabited and unsized ABIs override everything. - (Uninhabited, _) | (_, Uninhabited) => Uninhabited, - (Unsized, _) | (_, Unsized) => Unsized, - // A scalar struct must have a single non ZST-field. - (_, s @ Scalar(_)) if exact && self.size == Size::ZERO => s, - (s @ Scalar(_), _) if exact && other.size == Size::ZERO => s, - // Default case. - (_, _) => Sized, - }; - let niches = match (self.niches, other.niches) { - (NaiveNiches::Some, _) | (_, NaiveNiches::Some) => NaiveNiches::Some, - (NaiveNiches::None, NaiveNiches::None) => NaiveNiches::None, - (_, _) => NaiveNiches::Maybe, - }; - Some(Self { abi, size, align, exact, niches }) - } - - /// Returns the layout of `self` superposed with `other`, as in an `enum` - /// or an `union`. - /// - /// Note: This always ignore niche information from `other`. - #[must_use] - #[inline] - pub fn union(&self, other: &Self) -> Self { - use NaiveAbi::*; - - let size = cmp::max(self.size, other.size); - let align = cmp::max(self.align, other.align); - let exact = self.exact && other.exact; - let abi = match (self.abi, other.abi) { - // The unsized ABI overrides everything. - (Unsized, _) | (_, Unsized) => Unsized, - // A scalar union must have a single non ZST-field... - (_, s @ Scalar(_)) if exact && self.size == Size::ZERO => s, - (s @ Scalar(_), _) if exact && other.size == Size::ZERO => s, - // ...or identical scalar fields. - (Scalar(s1), Scalar(s2)) if s1 == s2 => Scalar(s1), - // Default cases. - (Uninhabited, Uninhabited) => Uninhabited, - (_, _) => Sized, - }; - Self { abi, size, align, exact, niches: self.niches } - } -} - /// Trait for contexts that want to be able to compute layouts of types. /// This automatically gives access to `LayoutOf`, through a blanket `impl`. pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasParamEnv<'tcx> { @@ -896,19 +673,6 @@ pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> { .map_err(|err| self.handle_layout_err(*err, span, ty)), ) } - - /// Computes the naive layout estimate of a type. Note that this implicitly - /// executes in "reveal all" mode, and will normalize the input type. - /// - /// Unlike `layout_of`, this doesn't look past references (beyond the `Pointee::Metadata` - /// projection), and as such can be called on generic types like `Option<&T>`. - #[inline] - fn naive_layout_of( - &self, - ty: Ty<'tcx>, - ) -> Result<TyAndNaiveLayout<'tcx>, &'tcx LayoutError<'tcx>> { - self.tcx().naive_layout_of(self.param_env().and(ty)) - } } impl<'tcx, C: LayoutOfHelpers<'tcx>> LayoutOf<'tcx> for C {} @@ -977,9 +741,9 @@ where let fields = match this.ty.kind() { ty::Adt(def, _) if def.variants().is_empty() => - bug!("for_variant called on zero-variant enum"), + bug!("for_variant called on zero-variant enum {}", this.ty), ty::Adt(def, _) => def.variant(variant_index).fields.len(), - _ => bug!(), + _ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty), }; tcx.mk_layout(LayoutS { variants: Variants::Single { index: variant_index }, @@ -1205,9 +969,6 @@ where this: TyAndLayout<'tcx>, cx: &C, offset: Size, - // If true, assume that pointers are either null or valid (according to their type), - // enabling extra optimizations. - mut assume_valid_ptr: bool, ) -> Option<PointeeInfo> { let tcx = cx.tcx(); let param_env = cx.param_env(); @@ -1230,19 +991,19 @@ where // Freeze/Unpin queries, and can save time in the codegen backend (noalias // attributes in LLVM have compile-time cost even in unoptimized builds). let optimize = tcx.sess.opts.optimize != OptLevel::No; - let safe = match (assume_valid_ptr, mt) { - (true, hir::Mutability::Not) => Some(PointerKind::SharedRef { + let kind = match mt { + hir::Mutability::Not => PointerKind::SharedRef { frozen: optimize && ty.is_freeze(tcx, cx.param_env()), - }), - (true, hir::Mutability::Mut) => Some(PointerKind::MutableRef { + }, + hir::Mutability::Mut => PointerKind::MutableRef { unpin: optimize && ty.is_unpin(tcx, cx.param_env()), - }), - (false, _) => None, + }, }; + tcx.layout_of(param_env.and(ty)).ok().map(|layout| PointeeInfo { size: layout.size, align: layout.align.abi, - safe, + safe: Some(kind), }) } @@ -1251,21 +1012,19 @@ where // Within the discriminant field, only the niche itself is // always initialized, so we only check for a pointer at its // offset. + // + // If the niche is a pointer, it's either valid (according + // to its type), or null (which the niche field's scalar + // validity range encodes). This allows using + // `dereferenceable_or_null` for e.g., `Option<&T>`, and + // this will continue to work as long as we don't start + // using more niches than just null (e.g., the first page of + // the address space, or unaligned pointers). Variants::Multiple { - tag_encoding: - TagEncoding::Niche { - untagged_variant, - niche_variants: ref variants, - niche_start, - }, + tag_encoding: TagEncoding::Niche { untagged_variant, .. }, tag_field, .. } if this.fields.offset(tag_field) == offset => { - // We can only continue assuming pointer validity if the only possible - // discriminant value is null. The null special-case is permitted by LLVM's - // `dereferenceable_or_null`, and allow types like `Option<&T>` to benefit - // from optimizations. - assume_valid_ptr &= niche_start == 0 && variants.start() == variants.end(); Some(this.for_variant(cx, untagged_variant)) } _ => Some(this), @@ -1291,12 +1050,9 @@ where result = field.to_result().ok().and_then(|field| { if ptr_end <= field_start + field.size { // We found the right field, look inside it. - Self::ty_and_layout_pointee_info_at( - field, - cx, - offset - field_start, - assume_valid_ptr, - ) + let field_info = + field.pointee_info_at(cx, offset - field_start); + field_info } else { None } @@ -1311,7 +1067,7 @@ where // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`. if let Some(ref mut pointee) = result { if let ty::Adt(def, _) = this.ty.kind() { - if assume_valid_ptr && def.is_box() && offset.bytes() == 0 { + if def.is_box() && offset.bytes() == 0 { let optimize = tcx.sess.opts.optimize != OptLevel::No; pointee.safe = Some(PointerKind::Box { unpin: optimize && this.ty.boxed_ty().is_unpin(tcx, cx.param_env()), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0411890ab51..f9c0fbb23c3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -867,20 +867,6 @@ pub struct TraitPredicate<'tcx> { pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; impl<'tcx> TraitPredicate<'tcx> { - pub fn remap_constness(&mut self, param_env: &mut ParamEnv<'tcx>) { - *param_env = param_env.with_constness(self.constness.and(param_env.constness())) - } - - /// Remap the constness of this predicate before emitting it for diagnostics. - pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) { - // this is different to `remap_constness` that callees want to print this predicate - // in case of selection errors. `T: ~const Drop` bounds cannot end up here when the - // param_env is not const because it is always satisfied in non-const contexts. - if let hir::Constness::NotConst = param_env.constness() { - self.constness = ty::BoundConstness::NotConst; - } - } - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self } } @@ -922,14 +908,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> { self.map_bound(|trait_ref| trait_ref.self_ty()) } - /// Remap the constness of this predicate before emitting it for diagnostics. - pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) { - *self = self.map_bound(|mut p| { - p.remap_constness_diag(param_env); - p - }); - } - #[inline] pub fn is_const_if_const(self) -> bool { self.skip_binder().is_const_if_const() @@ -1700,15 +1678,12 @@ pub struct ParamEnv<'tcx> { #[derive(Copy, Clone)] struct ParamTag { reveal: traits::Reveal, - constness: hir::Constness, } impl_tag! { impl Tag for ParamTag; - ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst }, - ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::NotConst }, - ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const }, - ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::Const }, + ParamTag { reveal: traits::Reveal::UserFacing }, + ParamTag { reveal: traits::Reveal::All }, } impl<'tcx> fmt::Debug for ParamEnv<'tcx> { @@ -1716,7 +1691,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> { f.debug_struct("ParamEnv") .field("caller_bounds", &self.caller_bounds()) .field("reveal", &self.reveal()) - .field("constness", &self.constness()) .finish() } } @@ -1725,7 +1699,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.caller_bounds().hash_stable(hcx, hasher); self.reveal().hash_stable(hcx, hasher); - self.constness().hash_stable(hcx, hasher); } } @@ -1737,7 +1710,6 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> { Ok(ParamEnv::new( self.caller_bounds().try_fold_with(folder)?, self.reveal().try_fold_with(folder)?, - self.constness(), )) } } @@ -1756,7 +1728,7 @@ impl<'tcx> ParamEnv<'tcx> { /// type-checking. #[inline] pub fn empty() -> Self { - Self::new(List::empty(), Reveal::UserFacing, hir::Constness::NotConst) + Self::new(List::empty(), Reveal::UserFacing) } #[inline] @@ -1769,16 +1741,6 @@ impl<'tcx> ParamEnv<'tcx> { self.packed.tag().reveal } - #[inline] - pub fn constness(self) -> hir::Constness { - self.packed.tag().constness - } - - #[inline] - pub fn is_const(self) -> bool { - self.packed.tag().constness == hir::Constness::Const - } - /// Construct a trait environment with no where-clauses in scope /// where the values of all `impl Trait` and other hidden types /// are revealed. This is suitable for monomorphized, post-typeck @@ -1788,17 +1750,13 @@ impl<'tcx> ParamEnv<'tcx> { /// or invoke `param_env.with_reveal_all()`. #[inline] pub fn reveal_all() -> Self { - Self::new(List::empty(), Reveal::All, hir::Constness::NotConst) + Self::new(List::empty(), Reveal::All) } /// Construct a trait environment with the given set of predicates. #[inline] - pub fn new( - caller_bounds: &'tcx List<Clause<'tcx>>, - reveal: Reveal, - constness: hir::Constness, - ) -> Self { - ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) } + pub fn new(caller_bounds: &'tcx List<Clause<'tcx>>, reveal: Reveal) -> Self { + ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) } } pub fn with_user_facing(mut self) -> Self { @@ -1806,29 +1764,6 @@ impl<'tcx> ParamEnv<'tcx> { self } - #[inline] - pub fn with_constness(mut self, constness: hir::Constness) -> Self { - self.packed.set_tag(ParamTag { constness, ..self.packed.tag() }); - self - } - - #[inline] - pub fn with_const(mut self) -> Self { - self.packed.set_tag(ParamTag { constness: hir::Constness::Const, ..self.packed.tag() }); - self - } - - #[inline] - pub fn without_const(mut self) -> Self { - self.packed.set_tag(ParamTag { constness: hir::Constness::NotConst, ..self.packed.tag() }); - self - } - - #[inline] - pub fn remap_constness_with(&mut self, mut constness: ty::BoundConstness) { - *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 @@ -1843,17 +1778,13 @@ impl<'tcx> ParamEnv<'tcx> { return self; } - ParamEnv::new( - tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), - Reveal::All, - self.constness(), - ) + ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All) } /// Returns this same environment but with no caller bounds. #[inline] pub fn without_caller_bounds(self) -> Self { - Self::new(List::empty(), self.reveal(), self.constness()) + Self::new(List::empty(), self.reveal()) } /// Creates a suitable environment in which to perform trait diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 9d380a58d9f..50bf9afa531 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -602,7 +602,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { type Lifted = ty::ParamEnv<'tcx>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { tcx.lift(self.caller_bounds()) - .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness())) + .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal())) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f9c1ca9a8b1..3e023ccdead 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2670,11 +2670,6 @@ impl<'tcx> Ty<'tcx> { variant_index: VariantIdx, ) -> Option<Discr<'tcx>> { match self.kind() { - TyKind::Adt(adt, _) if adt.variants().is_empty() => { - // This can actually happen during CTFE, see - // https://github.com/rust-lang/rust/issues/89765. - None - } TyKind::Adt(adt, _) if adt.is_enum() => { Some(adt.discriminant_for_variant(tcx, variant_index)) } |
