Skip to content

Commit d98a5da

Browse files
committed
Auto merge of #143459 - matthiaskrgr:rollup-gsv6uzl, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #141532 (std: sys: net: uefi: tcp4: Implement write) - #143085 (Port `#[non_exhaustive]` to the new attribute parsing infrastructure) - #143372 (Remove names_imported_by_glob_use query.) - #143386 (Assign dependency bump PRs to me) - #143406 (Remove some unnecessary `unsafe` in VecCache) - #143408 (mbe: Gracefully handle macro rules that end after `=>`) - #143414 (remove special-casing of boxes from match exhaustiveness/usefulness analysis) - #143444 (clean up GVN TypeId test) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e384365 + 1ff6e44 commit d98a5da

File tree

39 files changed

+385
-180
lines changed

39 files changed

+385
-180
lines changed

.github/workflows/dependencies.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ env:
1919
PR_TITLE: Weekly `cargo update`
2020
PR_MESSAGE: |
2121
Automation to keep dependencies in `Cargo.lock` current.
22+
r? dep-bumps
2223
2324
The following is the output from `cargo update`:
2425
COMMIT_MESSAGE: "cargo update \n\n"

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ pub enum AttributeKind {
284284
/// Represents `#[no_mangle]`
285285
NoMangle(Span),
286286

287+
/// Represents `#[non_exhaustive]`
288+
NonExhaustive(Span),
289+
287290
/// Represents `#[optimize(size|speed)]`
288291
Optimize(OptimizeAttr, Span),
289292

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ impl AttributeKind {
3636
Naked(..) => No,
3737
NoImplicitPrelude(..) => No,
3838
NoMangle(..) => No,
39+
NonExhaustive(..) => Yes,
3940
Optimize(..) => No,
4041
PassByValue(..) => Yes,
4142
PubTransparent(..) => Yes,

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub(crate) mod lint_helpers;
3636
pub(crate) mod loop_match;
3737
pub(crate) mod must_use;
3838
pub(crate) mod no_implicit_prelude;
39+
pub(crate) mod non_exhaustive;
3940
pub(crate) mod repr;
4041
pub(crate) mod rustc_internal;
4142
pub(crate) mod semantics;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use rustc_attr_data_structures::AttributeKind;
2+
use rustc_span::{Span, Symbol, sym};
3+
4+
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
5+
use crate::context::Stage;
6+
7+
pub(crate) struct NonExhaustiveParser;
8+
9+
impl<S: Stage> NoArgsAttributeParser<S> for NonExhaustiveParser {
10+
const PATH: &[Symbol] = &[sym::non_exhaustive];
11+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
12+
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive;
13+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTranspa
2727
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
2828
use crate::attributes::must_use::MustUseParser;
2929
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
30+
use crate::attributes::non_exhaustive::NonExhaustiveParser;
3031
use crate::attributes::repr::{AlignParser, ReprParser};
3132
use crate::attributes::rustc_internal::{
3233
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
@@ -144,6 +145,7 @@ attribute_parsers!(
144145
Single<WithoutArgs<MayDangleParser>>,
145146
Single<WithoutArgs<NoImplicitPreludeParser>>,
146147
Single<WithoutArgs<NoMangleParser>>,
148+
Single<WithoutArgs<NonExhaustiveParser>>,
147149
Single<WithoutArgs<PassByValueParser>>,
148150
Single<WithoutArgs<PubTransparentParser>>,
149151
Single<WithoutArgs<TrackCallerParser>>,

compiler/rustc_data_structures/src/vec_cache.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ impl SlotIndex {
7676
index_in_bucket: idx as usize,
7777
};
7878
}
79-
// SAFETY: We already ruled out idx 0, so `checked_ilog2` can't return `None`.
80-
let bucket = unsafe { idx.checked_ilog2().unwrap_unchecked() as usize };
79+
// We already ruled out idx 0, so this `ilog2` never panics (and the check optimizes away)
80+
let bucket = idx.ilog2() as usize;
8181
let entries = 1 << bucket;
8282
SlotIndex {
8383
bucket_idx: bucket - FIRST_BUCKET_SHIFT + 1,

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,15 @@ pub fn compile_declarative_macro(
411411
if let Err(e) = p.expect(exp!(FatArrow)) {
412412
return dummy_syn_ext(e.emit());
413413
}
414+
if p.token == token::Eof {
415+
let err_sp = p.token.span.shrink_to_hi();
416+
let guar = sess
417+
.dcx()
418+
.struct_span_err(err_sp, "macro definition ended unexpectedly")
419+
.with_span_label(err_sp, "expected right-hand side of macro rule")
420+
.emit();
421+
return dummy_syn_ext(guar);
422+
}
414423
let rhs_tt = p.parse_token_tree();
415424
let rhs_tt = mbe::quoted::parse(
416425
&TokenStream::new(vec![rhs_tt]),

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -779,9 +779,11 @@ fn lower_variant<'tcx>(
779779
fields,
780780
parent_did.to_def_id(),
781781
recovered,
782-
adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
783-
|| variant_did
784-
.is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)),
782+
adt_kind == AdtKind::Struct
783+
&& find_attr!(tcx.get_all_attrs(parent_did), AttributeKind::NonExhaustive(..))
784+
|| variant_did.is_some_and(|variant_did| {
785+
find_attr!(tcx.get_all_attrs(variant_did), AttributeKind::NonExhaustive(..))
786+
}),
785787
)
786788
}
787789

compiler/rustc_middle/src/query/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,9 +2264,6 @@ rustc_queries! {
22642264
query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
22652265
desc { "fetching potentially unused trait imports" }
22662266
}
2267-
query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxIndexSet<Symbol> {
2268-
desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) }
2269-
}
22702267

22712268
query stability_index(_: ()) -> &'tcx stability::Index {
22722269
arena_cache

compiler/rustc_middle/src/ty/adt.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::ops::Range;
44
use std::str;
55

66
use rustc_abi::{FIRST_VARIANT, ReprOptions, VariantIdx};
7+
use rustc_attr_data_structures::{AttributeKind, find_attr};
78
use rustc_data_structures::fingerprint::Fingerprint;
89
use rustc_data_structures::fx::FxHashMap;
910
use rustc_data_structures::intern::Interned;
@@ -278,7 +279,9 @@ impl AdtDefData {
278279
debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr);
279280
let mut flags = AdtFlags::NO_ADT_FLAGS;
280281

281-
if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) {
282+
if kind == AdtKind::Enum
283+
&& find_attr!(tcx.get_all_attrs(did), AttributeKind::NonExhaustive(..))
284+
{
282285
debug!("found non-exhaustive variant list for {:?}", did);
283286
flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
284287
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3417,10 +3417,6 @@ pub struct DeducedParamAttrs {
34173417
pub fn provide(providers: &mut Providers) {
34183418
providers.maybe_unused_trait_imports =
34193419
|tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
3420-
providers.names_imported_by_glob_use = |tcx, id| {
3421-
tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default())
3422-
};
3423-
34243420
providers.extern_mod_stmt_cnum =
34253421
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
34263422
providers.is_panic_runtime =

compiler/rustc_mir_build/src/thir/pattern/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
319319
}
320320
PatKind::Deref { subpattern }
321321
}
322-
hir::PatKind::Box(subpattern) => {
323-
PatKind::Deref { subpattern: self.lower_pattern(subpattern) }
324-
}
322+
hir::PatKind::Box(subpattern) => PatKind::DerefPattern {
323+
subpattern: self.lower_pattern(subpattern),
324+
borrow: hir::ByRef::No,
325+
},
325326

326327
hir::PatKind::Slice(prefix, slice, suffix) => {
327328
self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix)

compiler/rustc_parse/src/validate_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ fn emit_malformed_attribute(
303303
| sym::rustc_allow_const_fn_unstable
304304
| sym::naked
305305
| sym::no_mangle
306+
| sym::non_exhaustive
306307
| sym::must_use
307308
| sym::track_caller
308309
| sym::link_name

compiler/rustc_passes/src/check_attr.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
194194
Attribute::Parsed(AttributeKind::TrackCaller(attr_span)) => {
195195
self.check_track_caller(hir_id, *attr_span, attrs, span, target)
196196
}
197+
Attribute::Parsed(AttributeKind::NonExhaustive(attr_span)) => {
198+
self.check_non_exhaustive(hir_id, *attr_span, span, target, item)
199+
}
197200
Attribute::Parsed(
198201
AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span)
199202
| AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span),
@@ -237,7 +240,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
237240
[sym::no_sanitize, ..] => {
238241
self.check_no_sanitize(attr, span, target)
239242
}
240-
[sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target, item),
241243
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
242244
[sym::thread_local, ..] => self.check_thread_local(attr, span, target),
243245
[sym::doc, ..] => self.check_doc_attrs(
@@ -779,7 +781,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
779781
fn check_non_exhaustive(
780782
&self,
781783
hir_id: HirId,
782-
attr: &Attribute,
784+
attr_span: Span,
783785
span: Span,
784786
target: Target,
785787
item: Option<ItemLike<'_>>,
@@ -794,7 +796,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
794796
&& fields.iter().any(|f| f.default.is_some())
795797
{
796798
self.dcx().emit_err(errors::NonExhaustiveWithDefaultFieldValues {
797-
attr_span: attr.span(),
799+
attr_span,
798800
defn_span: span,
799801
});
800802
}
@@ -805,13 +807,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
805807
// erroneously allowed it and some crates used it accidentally, to be compatible
806808
// with crates depending on them, we can't throw an error here.
807809
Target::Field | Target::Arm | Target::MacroDef => {
808-
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "non_exhaustive");
810+
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "non_exhaustive");
809811
}
810812
_ => {
811-
self.dcx().emit_err(errors::NonExhaustiveWrongLocation {
812-
attr_span: attr.span(),
813-
defn_span: span,
814-
});
813+
self.dcx()
814+
.emit_err(errors::NonExhaustiveWrongLocation { attr_span, defn_span: span });
815815
}
816816
}
817817
}

compiler/rustc_pattern_analysis/src/rustc.rs

Lines changed: 24 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -221,27 +221,19 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
221221
let slice = match ctor {
222222
Struct | Variant(_) | UnionField => match ty.kind() {
223223
ty::Tuple(fs) => reveal_and_alloc(cx, fs.iter()),
224-
ty::Adt(adt, args) => {
225-
if adt.is_box() {
226-
// The only legal patterns of type `Box` (outside `std`) are `_` and box
227-
// patterns. If we're here we can assume this is a box pattern.
228-
reveal_and_alloc(cx, once(args.type_at(0)))
229-
} else {
230-
let variant =
231-
&adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt));
232-
let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| {
233-
let is_visible =
234-
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
235-
let is_uninhabited = cx.is_uninhabited(*ty);
236-
let is_unstable =
237-
cx.tcx.lookup_stability(field.did).is_some_and(|stab| {
238-
stab.is_unstable() && stab.feature != sym::rustc_private
239-
});
240-
let skip = is_uninhabited && (!is_visible || is_unstable);
241-
(ty, PrivateUninhabitedField(skip))
224+
ty::Adt(adt, _) => {
225+
let variant = &adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt));
226+
let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| {
227+
let is_visible =
228+
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
229+
let is_uninhabited = cx.is_uninhabited(*ty);
230+
let is_unstable = cx.tcx.lookup_stability(field.did).is_some_and(|stab| {
231+
stab.is_unstable() && stab.feature != sym::rustc_private
242232
});
243-
cx.dropless_arena.alloc_from_iter(tys)
244-
}
233+
let skip = is_uninhabited && (!is_visible || is_unstable);
234+
(ty, PrivateUninhabitedField(skip))
235+
});
236+
cx.dropless_arena.alloc_from_iter(tys)
245237
}
246238
_ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
247239
},
@@ -273,14 +265,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
273265
Struct | Variant(_) | UnionField => match ty.kind() {
274266
ty::Tuple(fs) => fs.len(),
275267
ty::Adt(adt, ..) => {
276-
if adt.is_box() {
277-
// The only legal patterns of type `Box` (outside `std`) are `_` and box
278-
// patterns. If we're here we can assume this is a box pattern.
279-
1
280-
} else {
281-
let variant_idx = RustcPatCtxt::variant_index_for_adt(&ctor, *adt);
282-
adt.variant(variant_idx).fields.len()
283-
}
268+
let variant_idx = RustcPatCtxt::variant_index_for_adt(&ctor, *adt);
269+
adt.variant(variant_idx).fields.len()
284270
}
285271
_ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
286272
},
@@ -470,8 +456,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
470456
fields = vec![self.lower_pat(subpattern).at_index(0)];
471457
arity = 1;
472458
ctor = match ty.kind() {
473-
// This is a box pattern.
474-
ty::Adt(adt, ..) if adt.is_box() => Struct,
475459
ty::Ref(..) => Ref,
476460
_ => span_bug!(
477461
pat.span,
@@ -501,28 +485,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
501485
.map(|ipat| self.lower_pat(&ipat.pattern).at_index(ipat.field.index()))
502486
.collect();
503487
}
504-
ty::Adt(adt, _) if adt.is_box() => {
505-
// The only legal patterns of type `Box` (outside `std`) are `_` and box
506-
// patterns. If we're here we can assume this is a box pattern.
507-
// FIXME(Nadrieril): A `Box` can in theory be matched either with `Box(_,
508-
// _)` or a box pattern. As a hack to avoid an ICE with the former, we
509-
// ignore other fields than the first one. This will trigger an error later
510-
// anyway.
511-
// See https://github.com/rust-lang/rust/issues/82772,
512-
// explanation: https://github.com/rust-lang/rust/pull/82789#issuecomment-796921977
513-
// The problem is that we can't know from the type whether we'll match
514-
// normally or through box-patterns. We'll have to figure out a proper
515-
// solution when we introduce generalized deref patterns. Also need to
516-
// prevent mixing of those two options.
517-
let pattern = subpatterns.into_iter().find(|pat| pat.field.index() == 0);
518-
if let Some(pat) = pattern {
519-
fields = vec![self.lower_pat(&pat.pattern).at_index(0)];
520-
} else {
521-
fields = vec![];
522-
}
523-
ctor = Struct;
524-
arity = 1;
525-
}
526488
ty::Adt(adt, _) => {
527489
ctor = match pat.kind {
528490
PatKind::Leaf { .. } if adt.is_union() => UnionField,
@@ -825,11 +787,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
825787
Bool(b) => b.to_string(),
826788
Str(s) => s.to_string(),
827789
IntRange(range) => return self.print_pat_range(range, *pat.ty()),
828-
Struct if pat.ty().is_box() => {
829-
// Outside of the `alloc` crate, the only way to create a struct pattern
830-
// of type `Box` is to use a `box` pattern via #[feature(box_patterns)].
831-
format!("box {}", print(&pat.fields[0]))
832-
}
833790
Struct | Variant(_) | UnionField => {
834791
let enum_info = match *pat.ty().kind() {
835792
ty::Adt(adt_def, _) if adt_def.is_enum() => EnumInfo::Enum {
@@ -866,6 +823,14 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
866823
print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap();
867824
s
868825
}
826+
DerefPattern(_) if pat.ty().is_box() && !self.tcx.features().deref_patterns() => {
827+
// FIXME(deref_patterns): Remove this special handling once `box_patterns` is gone.
828+
// HACK(@dianne): `box _` syntax is exposed on stable in diagnostics, e.g. to
829+
// witness non-exhaustiveness of `match Box::new(0) { Box { .. } if false => {} }`.
830+
// To avoid changing diagnostics before deref pattern syntax is finalized, let's use
831+
// `box _` syntax unless `deref_patterns` is enabled.
832+
format!("box {}", print(&pat.fields[0]))
833+
}
869834
DerefPattern(_) => format!("deref!({})", print(&pat.fields[0])),
870835
Slice(slice) => {
871836
let (prefix_len, has_dot_dot) = match slice.kind {
@@ -964,12 +929,8 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
964929
ty: &Self::Ty,
965930
) -> fmt::Result {
966931
if let ty::Adt(adt, _) = ty.kind() {
967-
if adt.is_box() {
968-
write!(f, "Box")?
969-
} else {
970-
let variant = adt.variant(Self::variant_index_for_adt(ctor, *adt));
971-
write!(f, "{}", variant.name)?;
972-
}
932+
let variant = adt.variant(Self::variant_index_for_adt(ctor, *adt));
933+
write!(f, "{}", variant.name)?;
973934
}
974935
Ok(())
975936
}

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::{
55
self as ast, CRATE_NODE_ID, Crate, ItemKind, MetaItemInner, MetaItemKind, ModKind, NodeId, Path,
66
};
77
use rustc_ast_pretty::pprust;
8-
use rustc_attr_data_structures::{self as attr, Stability};
8+
use rustc_attr_data_structures::{self as attr, AttributeKind, Stability, find_attr};
99
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1010
use rustc_data_structures::unord::{UnordMap, UnordSet};
1111
use rustc_errors::codes::*;
@@ -1998,9 +1998,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19981998
// Otherwise, point out if the struct has any private fields.
19991999
if let Some(def_id) = res.opt_def_id()
20002000
&& !def_id.is_local()
2001-
&& let Some(attr) = self.tcx.get_attr(def_id, sym::non_exhaustive)
2001+
&& let Some(attr_span) = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::NonExhaustive(span) => *span)
20022002
{
2003-
non_exhaustive = Some(attr.span());
2003+
non_exhaustive = Some(attr_span);
20042004
} else if let Some(span) = ctor_fields_span {
20052005
let label = errors::ConstructorPrivateIfAnyFieldPrivate { span };
20062006
err.subdiagnostic(label);

0 commit comments

Comments
 (0)