Skip to content

Commit 3bf62cc

Browse files
committed
Auto merge of rust-lang#134499 - jieyouxu:rollup-zmaveur, r=jieyouxu
Rollup of 7 pull requests Successful merges: - rust-lang#133702 (Variants::Single: do not use invalid VariantIdx for uninhabited enums) - rust-lang#134427 (ci: remove duplicate task definition) - rust-lang#134432 (Fix intra doc links not generated inside footnote definitions) - rust-lang#134437 (reduce compiler `Assemble` complexity) - rust-lang#134474 (Forbid overwriting types in typeck) - rust-lang#134477 (move lint_unused_mut into sub-fn) - rust-lang#134491 (Some destructor/drop related tweaks) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a4079b2 + e2bc718 commit 3bf62cc

File tree

59 files changed

+446
-367
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+446
-367
lines changed

compiler/rustc_abi/src/callconv.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
206206
let (mut result, mut total) = from_fields_at(*self, Size::ZERO)?;
207207

208208
match &self.variants {
209-
abi::Variants::Single { .. } => {}
209+
abi::Variants::Single { .. } | abi::Variants::Empty => {}
210210
abi::Variants::Multiple { variants, .. } => {
211211
// Treat enum variants like union members.
212212
// HACK(eddyb) pretend the `enum` field (discriminant)

compiler/rustc_abi/src/layout.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
213213
&self,
214214
) -> LayoutData<FieldIdx, VariantIdx> {
215215
let dl = self.cx.data_layout();
216+
// This is also used for uninhabited enums, so we use `Variants::Empty`.
216217
LayoutData {
217-
variants: Variants::Single { index: VariantIdx::new(0) },
218+
variants: Variants::Empty,
218219
fields: FieldsShape::Primitive,
219220
backend_repr: BackendRepr::Uninhabited,
220221
largest_niche: None,
@@ -1004,8 +1005,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10041005
Variants::Multiple { tag, tag_encoding, tag_field, .. } => {
10051006
Variants::Multiple { tag, tag_encoding, tag_field, variants: best_layout.variants }
10061007
}
1007-
Variants::Single { .. } => {
1008-
panic!("encountered a single-variant enum during multi-variant layout")
1008+
Variants::Single { .. } | Variants::Empty => {
1009+
panic!("encountered a single-variant or empty enum during multi-variant layout")
10091010
}
10101011
};
10111012
Ok(best_layout.layout)

compiler/rustc_abi/src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1504,10 +1504,12 @@ impl BackendRepr {
15041504
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
15051505
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
15061506
pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
1507+
/// A type with no valid variants. Must be uninhabited.
1508+
Empty,
1509+
15071510
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
15081511
Single {
1509-
/// Always 0 for non-enums/generators.
1510-
/// For enums without a variant, this is an invalid index!
1512+
/// Always `0` for types that cannot have multiple variants.
15111513
index: VariantIdx,
15121514
},
15131515

compiler/rustc_borrowck/src/lib.rs

+33-29
Original file line numberDiff line numberDiff line change
@@ -334,35 +334,7 @@ fn do_mir_borrowck<'tcx>(
334334
mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals);
335335

336336
debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
337-
let used_mut = std::mem::take(&mut mbcx.used_mut);
338-
for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
339-
let local_decl = &mbcx.body.local_decls[local];
340-
let lint_root = match &mbcx.body.source_scopes[local_decl.source_info.scope].local_data {
341-
ClearCrossCrate::Set(data) => data.lint_root,
342-
_ => continue,
343-
};
344-
345-
// Skip over locals that begin with an underscore or have no name
346-
match mbcx.local_names[local] {
347-
Some(name) => {
348-
if name.as_str().starts_with('_') {
349-
continue;
350-
}
351-
}
352-
None => continue,
353-
}
354-
355-
let span = local_decl.source_info.span;
356-
if span.desugaring_kind().is_some() {
357-
// If the `mut` arises as part of a desugaring, we should ignore it.
358-
continue;
359-
}
360-
361-
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
362-
363-
tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
364-
}
365-
337+
mbcx.lint_unused_mut();
366338
let tainted_by_errors = mbcx.emit_errors();
367339

368340
let result = BorrowCheckResult {
@@ -2390,6 +2362,38 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
23902362
// `BasicBlocks` computes dominators on-demand and caches them.
23912363
self.body.basic_blocks.dominators()
23922364
}
2365+
2366+
fn lint_unused_mut(&self) {
2367+
let tcx = self.infcx.tcx;
2368+
let body = self.body;
2369+
for local in body.mut_vars_and_args_iter().filter(|local| !self.used_mut.contains(local)) {
2370+
let local_decl = &body.local_decls[local];
2371+
let lint_root = match &body.source_scopes[local_decl.source_info.scope].local_data {
2372+
ClearCrossCrate::Set(data) => data.lint_root,
2373+
_ => continue,
2374+
};
2375+
2376+
// Skip over locals that begin with an underscore or have no name
2377+
match self.local_names[local] {
2378+
Some(name) => {
2379+
if name.as_str().starts_with('_') {
2380+
continue;
2381+
}
2382+
}
2383+
None => continue,
2384+
}
2385+
2386+
let span = local_decl.source_info.span;
2387+
if span.desugaring_kind().is_some() {
2388+
// If the `mut` arises as part of a desugaring, we should ignore it.
2389+
continue;
2390+
}
2391+
2392+
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
2393+
2394+
tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
2395+
}
2396+
}
23932397
}
23942398

23952399
mod diags {

compiler/rustc_codegen_cranelift/src/discriminant.rs

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
1818
return;
1919
}
2020
match layout.variants {
21+
Variants::Empty => unreachable!("we already handled uninhabited types"),
2122
Variants::Single { index } => {
2223
assert_eq!(index, variant_index);
2324
}
@@ -85,6 +86,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
8586
}
8687

8788
let (tag_scalar, tag_field, tag_encoding) = match &layout.variants {
89+
Variants::Empty => unreachable!("we already handled uninhabited types"),
8890
Variants::Single { index } => {
8991
let discr_val = layout
9092
.ty

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -212,21 +212,17 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
212212
),
213213
|cx, enum_type_di_node| {
214214
match enum_type_and_layout.variants {
215-
Variants::Single { index: variant_index } => {
216-
if enum_adt_def.variants().is_empty() {
217-
// Uninhabited enums have Variants::Single. We don't generate
218-
// any members for them.
219-
return smallvec![];
220-
}
221-
222-
build_single_variant_union_fields(
223-
cx,
224-
enum_adt_def,
225-
enum_type_and_layout,
226-
enum_type_di_node,
227-
variant_index,
228-
)
215+
Variants::Empty => {
216+
// We don't generate any members for uninhabited types.
217+
return smallvec![];
229218
}
219+
Variants::Single { index: variant_index } => build_single_variant_union_fields(
220+
cx,
221+
enum_adt_def,
222+
enum_type_and_layout,
223+
enum_type_di_node,
224+
variant_index,
225+
),
230226
Variants::Multiple {
231227
tag_encoding: TagEncoding::Direct,
232228
ref variants,
@@ -303,6 +299,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
303299
)
304300
}
305301
Variants::Single { .. }
302+
| Variants::Empty
306303
| Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => {
307304
bug!(
308305
"Encountered coroutine with non-direct-tag layout: {:?}",

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ fn compute_discriminant_value<'ll, 'tcx>(
392392
variant_index: VariantIdx,
393393
) -> DiscrResult {
394394
match enum_type_and_layout.layout.variants() {
395-
&Variants::Single { .. } => DiscrResult::NoDiscriminant,
395+
&Variants::Single { .. } | &Variants::Empty => DiscrResult::NoDiscriminant,
396396
&Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => DiscrResult::Value(
397397
enum_type_and_layout.ty.discriminant_for_variant(cx.tcx, variant_index).unwrap().val,
398398
),

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ fn build_discr_member_di_node<'ll, 'tcx>(
358358
let containing_scope = enum_or_coroutine_type_di_node;
359359

360360
match enum_or_coroutine_type_and_layout.layout.variants() {
361-
// A single-variant enum has no discriminant.
362-
&Variants::Single { .. } => None,
361+
// A single-variant or no-variant enum has no discriminant.
362+
&Variants::Single { .. } | &Variants::Empty => None,
363363

364364
&Variants::Multiple { tag_field, .. } => {
365365
let tag_base_type = tag_base_type(cx.tcx, enum_or_coroutine_type_and_layout);

compiler/rustc_codegen_llvm/src/type_of.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fn uncached_llvm_type<'a, 'tcx>(
3838
if let (&ty::Adt(def, _), &Variants::Single { index }) =
3939
(layout.ty.kind(), &layout.variants)
4040
{
41-
if def.is_enum() && !def.variants().is_empty() {
41+
if def.is_enum() {
4242
write!(&mut name, "::{}", def.variant(index).name).unwrap();
4343
}
4444
}

compiler/rustc_codegen_ssa/src/debuginfo/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ fn tag_base_type_opt<'tcx>(
6565
});
6666

6767
match enum_type_and_layout.layout.variants() {
68-
// A single-variant enum has no discriminant.
69-
Variants::Single { .. } => None,
68+
// A single-variant or no-variant enum has no discriminant.
69+
Variants::Single { .. } | Variants::Empty => None,
7070

7171
Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. } => {
7272
// Niche tags are always normalized to unsized integers of the correct size.

compiler/rustc_codegen_ssa/src/mir/place.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
243243
return bx.cx().const_poison(cast_to);
244244
}
245245
let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants {
246+
Variants::Empty => unreachable!("we already handled uninhabited types"),
246247
Variants::Single { index } => {
247248
let discr_val = self
248249
.layout
@@ -365,9 +366,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
365366
return;
366367
}
367368
match self.layout.variants {
368-
Variants::Single { index } => {
369-
assert_eq!(index, variant_index);
370-
}
369+
Variants::Empty => unreachable!("we already handled uninhabited types"),
370+
Variants::Single { index } => assert_eq!(index, variant_index),
371+
371372
Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } => {
372373
let ptr = self.project_field(bx, tag_field);
373374
let to =

compiler/rustc_const_eval/src/interpret/discriminant.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
4444
}
4545
}
4646

47-
/// Read discriminant, return the runtime value as well as the variant index.
47+
/// Read discriminant, return the variant index.
4848
/// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
4949
///
5050
/// Will never return an uninhabited variant.
@@ -65,21 +65,17 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
6565
// We use "tag" to refer to how the discriminant is encoded in memory, which can be either
6666
// straight-forward (`TagEncoding::Direct`) or with a niche (`TagEncoding::Niche`).
6767
let (tag_scalar_layout, tag_encoding, tag_field) = match op.layout().variants {
68+
Variants::Empty => {
69+
throw_ub!(UninhabitedEnumVariantRead(None));
70+
}
6871
Variants::Single { index } => {
69-
// Do some extra checks on enums.
70-
if ty.is_enum() {
71-
// Hilariously, `Single` is used even for 0-variant enums.
72-
// (See https://github.com/rust-lang/rust/issues/89765).
73-
if ty.ty_adt_def().unwrap().variants().is_empty() {
74-
throw_ub!(UninhabitedEnumVariantRead(index))
75-
}
72+
if op.layout().is_uninhabited() {
7673
// For consistency with `write_discriminant`, and to make sure that
7774
// `project_downcast` cannot fail due to strange layouts, we declare immediate UB
78-
// for uninhabited variants.
79-
if op.layout().for_variant(self, index).is_uninhabited() {
80-
throw_ub!(UninhabitedEnumVariantRead(index))
81-
}
75+
// for uninhabited enums.
76+
throw_ub!(UninhabitedEnumVariantRead(Some(index)));
8277
}
78+
// Since the type is inhabited, there must be an index.
8379
return interp_ok(index);
8480
}
8581
Variants::Multiple { tag, ref tag_encoding, tag_field, .. } => {
@@ -199,11 +195,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
199195
// `uninhabited_enum_branching` MIR pass. It also ensures consistency with
200196
// `write_discriminant`.
201197
if op.layout().for_variant(self, index).is_uninhabited() {
202-
throw_ub!(UninhabitedEnumVariantRead(index))
198+
throw_ub!(UninhabitedEnumVariantRead(Some(index)))
203199
}
204200
interp_ok(index)
205201
}
206202

203+
/// Read discriminant, return the user-visible discriminant.
204+
/// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
207205
pub fn discriminant_for_variant(
208206
&self,
209207
ty: Ty<'tcx>,
@@ -243,6 +241,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
243241
}
244242

245243
match layout.variants {
244+
abi::Variants::Empty => unreachable!("we already handled uninhabited types"),
246245
abi::Variants::Single { .. } => {
247246
// The tag of a `Single` enum is like the tag of the niched
248247
// variant: there's no tag as the discriminant is encoded

compiler/rustc_const_eval/src/interpret/validity.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
302302
};
303303
}
304304
}
305-
Variants::Single { .. } => {}
305+
Variants::Single { .. } | Variants::Empty => {}
306306
}
307307

308308
// Now we know we are projecting to a field, so figure out which one.
@@ -344,6 +344,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
344344
// Inside a variant
345345
PathElem::Field(def.variant(index).fields[FieldIdx::from_usize(field)].name)
346346
}
347+
Variants::Empty => panic!("there is no field in Variants::Empty types"),
347348
Variants::Multiple { .. } => bug!("we handled variants above"),
348349
}
349350
}
@@ -1010,7 +1011,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
10101011
}
10111012
// Don't forget potential other variants.
10121013
match &layout.variants {
1013-
Variants::Single { .. } => {
1014+
Variants::Single { .. } | Variants::Empty => {
10141015
// Fully handled above.
10151016
}
10161017
Variants::Multiple { variants, .. } => {

compiler/rustc_const_eval/src/interpret/visitor.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
218218
// recurse with the inner type
219219
self.visit_variant(v, idx, &inner)?;
220220
}
221-
// For single-variant layouts, we already did anything there is to do.
222-
Variants::Single { .. } => {}
221+
// For single-variant layouts, we already did everything there is to do.
222+
Variants::Single { .. } | Variants::Empty => {}
223223
}
224224

225225
interp_ok(())

compiler/rustc_const_eval/src/util/check_validity_requirement.rs

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ fn check_validity_requirement_lax<'tcx>(
155155
}
156156

157157
match &this.variants {
158+
Variants::Empty => return Ok(false),
158159
Variants::Single { .. } => {
159160
// All fields of this single variant have already been checked above, there is nothing
160161
// else to do.

0 commit comments

Comments
 (0)