Auto merge of #99210 - Dylan-DPC:rollup-879cp1t, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #98574 (Lower let-else in MIR) - #99011 (`UnsafeCell` blocks niches inside its nested type from being available outside) - #99030 (diagnostics: error messages when struct literals fail to parse) - #99155 (Keep unstable target features for asm feature checking) - #99199 (Refactor: remove an unnecessary `span_to_snippet`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -182,6 +182,9 @@ pub enum StmtKind<'tcx> {
|
||||
/// `let pat: ty = <INIT>`
|
||||
initializer: Option<ExprId>,
|
||||
|
||||
/// `let pat: ty = <INIT> else { <ELSE> }
|
||||
else_block: Option<Block>,
|
||||
|
||||
/// The lint level for this `let` statement.
|
||||
lint_level: LintLevel,
|
||||
},
|
||||
|
||||
@@ -167,11 +167,15 @@ pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stm
|
||||
init_scope: _,
|
||||
ref pattern,
|
||||
lint_level: _,
|
||||
else_block,
|
||||
} => {
|
||||
if let Some(init) = initializer {
|
||||
visitor.visit_expr(&visitor.thir()[*init]);
|
||||
}
|
||||
visitor.visit_pat(pattern);
|
||||
if let Some(block) = else_block {
|
||||
visitor.visit_block(block)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ bitflags! {
|
||||
/// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
|
||||
/// (i.e., this flag is never set unless this ADT is an enum).
|
||||
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8;
|
||||
/// Indicates whether the type is `UnsafeCell`.
|
||||
const IS_UNSAFE_CELL = 1 << 9;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,6 +249,9 @@ impl AdtDefData {
|
||||
if Some(did) == tcx.lang_items().manually_drop() {
|
||||
flags |= AdtFlags::IS_MANUALLY_DROP;
|
||||
}
|
||||
if Some(did) == tcx.lang_items().unsafe_cell_type() {
|
||||
flags |= AdtFlags::IS_UNSAFE_CELL;
|
||||
}
|
||||
|
||||
AdtDefData { did, variants, flags, repr }
|
||||
}
|
||||
@@ -333,6 +338,12 @@ impl<'tcx> AdtDef<'tcx> {
|
||||
self.flags().contains(AdtFlags::IS_BOX)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is UnsafeCell<T>.
|
||||
#[inline]
|
||||
pub fn is_unsafe_cell(self) -> bool {
|
||||
self.flags().contains(AdtFlags::IS_UNSAFE_CELL)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is `ManuallyDrop<T>`.
|
||||
#[inline]
|
||||
pub fn is_manually_drop(self) -> bool {
|
||||
|
||||
@@ -542,14 +542,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
debug!("univariant offset: {:?} field: {:#?}", offset, field);
|
||||
offsets[i as usize] = offset;
|
||||
|
||||
if !repr.hide_niche() {
|
||||
if let Some(mut niche) = field.largest_niche {
|
||||
let available = niche.available(dl);
|
||||
if available > largest_niche_available {
|
||||
largest_niche_available = available;
|
||||
niche.offset += offset;
|
||||
largest_niche = Some(niche);
|
||||
}
|
||||
if let Some(mut niche) = field.largest_niche {
|
||||
let available = niche.available(dl);
|
||||
if available > largest_niche_available {
|
||||
largest_niche_available = available;
|
||||
niche.offset += offset;
|
||||
largest_niche = Some(niche);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1078,6 +1076,29 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
|
||||
let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr(), kind)?;
|
||||
st.variants = Variants::Single { index: v };
|
||||
|
||||
if def.is_unsafe_cell() {
|
||||
let hide_niches = |scalar: &mut _| match scalar {
|
||||
Scalar::Initialized { value, valid_range } => {
|
||||
*valid_range = WrappingRange::full(value.size(dl))
|
||||
}
|
||||
// Already doesn't have any niches
|
||||
Scalar::Union { .. } => {}
|
||||
};
|
||||
match &mut st.abi {
|
||||
Abi::Uninhabited => {}
|
||||
Abi::Scalar(scalar) => hide_niches(scalar),
|
||||
Abi::ScalarPair(a, b) => {
|
||||
hide_niches(a);
|
||||
hide_niches(b);
|
||||
}
|
||||
Abi::Vector { element, count: _ } => hide_niches(element),
|
||||
Abi::Aggregate { sized: _ } => {}
|
||||
}
|
||||
st.largest_niche = None;
|
||||
return Ok(tcx.intern_layout(st));
|
||||
}
|
||||
|
||||
let (start, end) = self.tcx.layout_scalar_valid_range(def.did());
|
||||
match st.abi {
|
||||
Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => {
|
||||
@@ -1106,11 +1127,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
}
|
||||
|
||||
// Update `largest_niche` if we have introduced a larger niche.
|
||||
let niche = if def.repr().hide_niche() {
|
||||
None
|
||||
} else {
|
||||
Niche::from_scalar(dl, Size::ZERO, *scalar)
|
||||
};
|
||||
let niche = Niche::from_scalar(dl, Size::ZERO, *scalar);
|
||||
if let Some(niche) = niche {
|
||||
match st.largest_niche {
|
||||
Some(largest_niche) => {
|
||||
|
||||
@@ -1720,11 +1720,9 @@ bitflags! {
|
||||
const IS_TRANSPARENT = 1 << 2;
|
||||
// Internal only for now. If true, don't reorder fields.
|
||||
const IS_LINEAR = 1 << 3;
|
||||
// If true, don't expose any niche to type's context.
|
||||
const HIDE_NICHE = 1 << 4;
|
||||
// If true, the type's layout can be randomized using
|
||||
// the seed stored in `ReprOptions.layout_seed`
|
||||
const RANDOMIZE_LAYOUT = 1 << 5;
|
||||
const RANDOMIZE_LAYOUT = 1 << 4;
|
||||
// Any of these flags being set prevent field reordering optimisation.
|
||||
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits
|
||||
| ReprFlags::IS_SIMD.bits
|
||||
@@ -1781,7 +1779,6 @@ impl ReprOptions {
|
||||
ReprFlags::empty()
|
||||
}
|
||||
attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
|
||||
attr::ReprNoNiche => ReprFlags::HIDE_NICHE,
|
||||
attr::ReprSimd => ReprFlags::IS_SIMD,
|
||||
attr::ReprInt(i) => {
|
||||
size = Some(i);
|
||||
@@ -1834,11 +1831,6 @@ impl ReprOptions {
|
||||
self.flags.contains(ReprFlags::IS_LINEAR)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hide_niche(&self) -> bool {
|
||||
self.flags.contains(ReprFlags::HIDE_NICHE)
|
||||
}
|
||||
|
||||
/// Returns the discriminant type, given these `repr` options.
|
||||
/// This must only be called on enums!
|
||||
pub fn discr_type(&self) -> attr::IntType {
|
||||
|
||||
Reference in New Issue
Block a user