Skip to content

Commit 2d0ea79

Browse files
committed
Auto merge of rust-lang#133261 - matthiaskrgr:rollup-ekui4we, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#129838 (uefi: process: Add args support) - rust-lang#130800 (Mark `get_mut` and `set_position` in `std::io::Cursor` as const.) - rust-lang#132708 (Point at `const` definition when used instead of a binding in a `let` statement) - rust-lang#133226 (Make `PointerLike` opt-in instead of built-in) - rust-lang#133244 (Account for `wasm32v1-none` when exporting TLS symbols) - rust-lang#133257 (Add `UnordMap::clear` method) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3fee0f1 + 71d07dd commit 2d0ea79

Some content is hidden

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

51 files changed

+627
-266
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,7 @@ impl<'a> WasmLd<'a> {
12791279
let mut wasm_ld = WasmLd { cmd, sess };
12801280
if sess.target_features.contains(&sym::atomics) {
12811281
wasm_ld.link_args(&["--shared-memory", "--max-memory=1073741824", "--import-memory"]);
1282-
if sess.target.os == "unknown" {
1282+
if sess.target.os == "unknown" || sess.target.os == "none" {
12831283
wasm_ld.link_args(&[
12841284
"--export=__wasm_init_tls",
12851285
"--export=__tls_size",
@@ -1403,7 +1403,7 @@ impl<'a> Linker for WasmLd<'a> {
14031403
// symbols explicitly passed via the `--export` flags above and hides all
14041404
// others. Various bits and pieces of wasm32-unknown-unknown tooling use
14051405
// this, so be sure these symbols make their way out of the linker as well.
1406-
if self.sess.target.os == "unknown" {
1406+
if self.sess.target.os == "unknown" || self.sess.target.os == "none" {
14071407
self.link_args(&["--export=__heap_base", "--export=__data_end"]);
14081408
}
14091409
}

compiler/rustc_data_structures/src/unord.rs

+5
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,11 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
602602
.into_iter()
603603
.map(|(_, v)| v)
604604
}
605+
606+
#[inline]
607+
pub fn clear(&mut self) {
608+
self.inner.clear()
609+
}
605610
}
606611

607612
impl<K, Q: ?Sized, V> Index<&Q> for UnordMap<K, V>

compiler/rustc_hir_analysis/src/coherence/builtin.rs

+71-14
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,19 @@ pub(super) fn check_trait<'tcx>(
3737
) -> Result<(), ErrorGuaranteed> {
3838
let lang_items = tcx.lang_items();
3939
let checker = Checker { tcx, trait_def_id, impl_def_id, impl_header };
40-
let mut res = checker.check(lang_items.drop_trait(), visit_implementation_of_drop);
41-
res = res.and(checker.check(lang_items.copy_trait(), visit_implementation_of_copy));
42-
res = res.and(checker.check(lang_items.const_param_ty_trait(), |checker| {
40+
checker.check(lang_items.drop_trait(), visit_implementation_of_drop)?;
41+
checker.check(lang_items.copy_trait(), visit_implementation_of_copy)?;
42+
checker.check(lang_items.const_param_ty_trait(), |checker| {
4343
visit_implementation_of_const_param_ty(checker, LangItem::ConstParamTy)
44-
}));
45-
res = res.and(checker.check(lang_items.unsized_const_param_ty_trait(), |checker| {
44+
})?;
45+
checker.check(lang_items.unsized_const_param_ty_trait(), |checker| {
4646
visit_implementation_of_const_param_ty(checker, LangItem::UnsizedConstParamTy)
47-
}));
48-
49-
res = res.and(
50-
checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized),
51-
);
52-
res.and(
53-
checker
54-
.check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn),
55-
)
47+
})?;
48+
checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)?;
49+
checker
50+
.check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?;
51+
checker.check(lang_items.pointer_like(), visit_implementation_of_pointer_like)?;
52+
Ok(())
5653
}
5754

5855
struct Checker<'tcx> {
@@ -663,3 +660,63 @@ fn infringing_fields_error<'tcx>(
663660

664661
err.emit()
665662
}
663+
664+
fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
665+
let tcx = checker.tcx;
666+
let typing_env = ty::TypingEnv::non_body_analysis(tcx, checker.impl_def_id);
667+
let impl_span = tcx.def_span(checker.impl_def_id);
668+
let self_ty = tcx.impl_trait_ref(checker.impl_def_id).unwrap().instantiate_identity().self_ty();
669+
670+
// If an ADT is repr(transparent)...
671+
if let ty::Adt(def, args) = *self_ty.kind()
672+
&& def.repr().transparent()
673+
{
674+
// FIXME(compiler-errors): This should and could be deduplicated into a query.
675+
// Find the nontrivial field.
676+
let adt_typing_env = ty::TypingEnv::non_body_analysis(tcx, def.did());
677+
let nontrivial_field = def.all_fields().find(|field_def| {
678+
let field_ty = tcx.type_of(field_def.did).instantiate_identity();
679+
!tcx.layout_of(adt_typing_env.as_query_input(field_ty))
680+
.is_ok_and(|layout| layout.layout.is_1zst())
681+
});
682+
683+
if let Some(nontrivial_field) = nontrivial_field {
684+
// Check that the nontrivial field implements `PointerLike`.
685+
let nontrivial_field = nontrivial_field.ty(tcx, args);
686+
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
687+
let ocx = ObligationCtxt::new(&infcx);
688+
ocx.register_bound(
689+
ObligationCause::misc(impl_span, checker.impl_def_id),
690+
param_env,
691+
nontrivial_field,
692+
tcx.lang_items().pointer_like().unwrap(),
693+
);
694+
// FIXME(dyn-star): We should regionck this implementation.
695+
if ocx.select_all_or_error().is_empty() {
696+
return Ok(());
697+
}
698+
}
699+
}
700+
701+
let is_permitted_primitive = match *self_ty.kind() {
702+
ty::Adt(def, _) => def.is_box(),
703+
ty::Uint(..) | ty::Int(..) | ty::RawPtr(..) | ty::Ref(..) | ty::FnPtr(..) => true,
704+
_ => false,
705+
};
706+
707+
if is_permitted_primitive
708+
&& let Ok(layout) = tcx.layout_of(typing_env.as_query_input(self_ty))
709+
&& layout.layout.is_pointer_like(&tcx.data_layout)
710+
{
711+
return Ok(());
712+
}
713+
714+
Err(tcx
715+
.dcx()
716+
.struct_span_err(
717+
impl_span,
718+
"implementation must be applied to type that has the same ABI as a pointer, \
719+
or is `repr(transparent)` and whose field is `PointerLike`",
720+
)
721+
.emit())
722+
}

compiler/rustc_middle/src/thir.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ impl<'tcx> Pat<'tcx> {
656656
| Binding { subpattern: Some(subpattern), .. }
657657
| Deref { subpattern }
658658
| DerefPattern { subpattern, .. }
659-
| InlineConstant { subpattern, .. } => subpattern.walk_(it),
659+
| ExpandedConstant { subpattern, .. } => subpattern.walk_(it),
660660
Leaf { subpatterns } | Variant { subpatterns, .. } => {
661661
subpatterns.iter().for_each(|field| field.pattern.walk_(it))
662662
}
@@ -799,12 +799,17 @@ pub enum PatKind<'tcx> {
799799
value: mir::Const<'tcx>,
800800
},
801801

802-
/// Inline constant found while lowering a pattern.
803-
InlineConstant {
804-
/// [LocalDefId] of the constant, we need this so that we have a
802+
/// Pattern obtained by converting a constant (inline or named) to its pattern
803+
/// representation using `const_to_pat`.
804+
ExpandedConstant {
805+
/// [DefId] of the constant, we need this so that we have a
805806
/// reference that can be used by unsafety checking to visit nested
806-
/// unevaluated constants.
807-
def: LocalDefId,
807+
/// unevaluated constants and for diagnostics. If the `DefId` doesn't
808+
/// correspond to a local crate, it points at the `const` item.
809+
def_id: DefId,
810+
/// If `false`, then `def_id` points at a `const` item, otherwise it
811+
/// corresponds to a local inline const.
812+
is_inline: bool,
808813
/// If the inline constant is used in a range pattern, this subpattern
809814
/// represents the range (if both ends are inline constants, there will
810815
/// be multiple InlineConstant wrappers).

compiler/rustc_middle/src/thir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
247247
}
248248
}
249249
Constant { value: _ } => {}
250-
InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern),
250+
ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern),
251251
Range(_) => {}
252252
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
253253
for subpattern in prefix.iter() {

compiler/rustc_middle/src/ty/context.rs

-14
Original file line numberDiff line numberDiff line change
@@ -602,19 +602,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
602602
self.coroutine_is_async_gen(coroutine_def_id)
603603
}
604604

605-
// We don't use `TypingEnv` here as it's only defined in `rustc_middle` and
606-
// `rustc_next_trait_solver` shouldn't have to know about it.
607-
fn layout_is_pointer_like(
608-
self,
609-
typing_mode: ty::TypingMode<'tcx>,
610-
param_env: ty::ParamEnv<'tcx>,
611-
ty: Ty<'tcx>,
612-
) -> bool {
613-
let typing_env = ty::TypingEnv { typing_mode, param_env };
614-
self.layout_of(self.erase_regions(typing_env).as_query_input(self.erase_regions(ty)))
615-
.is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout))
616-
}
617-
618605
type UnsizingParams = &'tcx rustc_index::bit_set::BitSet<u32>;
619606
fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
620607
self.unsizing_params_for_adt(adt_def_id)
@@ -688,7 +675,6 @@ bidirectional_lang_item_map! {
688675
Metadata,
689676
Option,
690677
PointeeTrait,
691-
PointerLike,
692678
Poll,
693679
Sized,
694680
TransmuteTrait,

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,20 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
144144
let mut targets = Vec::new();
145145
for arm in rest {
146146
let arm = &self.thir[*arm];
147-
let PatKind::Constant { value } = arm.pattern.kind else {
148-
return Err(ParseError {
149-
span: arm.pattern.span,
150-
item_description: format!("{:?}", arm.pattern.kind),
151-
expected: "constant pattern".to_string(),
152-
});
147+
let value = match arm.pattern.kind {
148+
PatKind::Constant { value } => value,
149+
PatKind::ExpandedConstant { ref subpattern, def_id: _, is_inline: false }
150+
if let PatKind::Constant { value } = subpattern.kind =>
151+
{
152+
value
153+
}
154+
_ => {
155+
return Err(ParseError {
156+
span: arm.pattern.span,
157+
item_description: format!("{:?}", arm.pattern.kind),
158+
expected: "constant pattern".to_string(),
159+
});
160+
}
153161
};
154162
values.push(value.eval_bits(self.tcx, self.typing_env));
155163
targets.push(self.parse_block(arm.body)?);

compiler/rustc_mir_build/src/build/matches/match_pair.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,11 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
162162
TestCase::Irrefutable { ascription: None, binding }
163163
}
164164

165-
PatKind::InlineConstant { subpattern: ref pattern, def, .. } => {
165+
PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
166+
subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
167+
default_irrefutable()
168+
}
169+
PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
166170
// Apply a type ascription for the inline constant to the value at `match_pair.place`
167171
let ascription = place.map(|source| {
168172
let span = pattern.span;
@@ -173,7 +177,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
173177
})
174178
.args;
175179
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
176-
def.to_def_id(),
180+
def_id,
177181
ty::UserArgs { args, user_self_ty: None },
178182
));
179183
let annotation = ty::CanonicalUserTypeAnnotation {

compiler/rustc_mir_build/src/build/matches/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
926926
self.visit_primary_bindings(subpattern, subpattern_user_ty, f)
927927
}
928928

929-
PatKind::InlineConstant { ref subpattern, .. } => {
929+
PatKind::ExpandedConstant { ref subpattern, .. } => {
930930
self.visit_primary_bindings(subpattern, pattern_user_ty, f)
931931
}
932932

compiler/rustc_mir_build/src/check_unsafety.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
332332
PatKind::Wild |
333333
// these just wrap other patterns, which we recurse on below.
334334
PatKind::Or { .. } |
335-
PatKind::InlineConstant { .. } |
335+
PatKind::ExpandedConstant { .. } |
336336
PatKind::AscribeUserType { .. } |
337337
PatKind::Error(_) => {}
338338
}
@@ -386,8 +386,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
386386
visit::walk_pat(self, pat);
387387
self.inside_adt = old_inside_adt;
388388
}
389-
PatKind::InlineConstant { def, .. } => {
390-
self.visit_inner_body(*def);
389+
PatKind::ExpandedConstant { def_id, is_inline, .. } => {
390+
if let Some(def) = def_id.as_local()
391+
&& *is_inline
392+
{
393+
self.visit_inner_body(def);
394+
}
391395
visit::walk_pat(self, pat);
392396
}
393397
_ => {

compiler/rustc_mir_build/src/errors.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -860,8 +860,10 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
860860
pub(crate) uncovered: Uncovered,
861861
#[subdiagnostic]
862862
pub(crate) inform: Option<Inform>,
863+
#[label(mir_build_confused)]
864+
pub(crate) interpreted_as_const: Option<Span>,
863865
#[subdiagnostic]
864-
pub(crate) interpreted_as_const: Option<InterpretedAsConst>,
866+
pub(crate) interpreted_as_const_sugg: Option<InterpretedAsConst>,
865867
#[subdiagnostic]
866868
pub(crate) adt_defined_here: Option<AdtDefinedHere<'tcx>>,
867869
#[note(mir_build_privately_uninhabited)]
@@ -911,9 +913,9 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> {
911913
#[suggestion(
912914
mir_build_interpreted_as_const,
913915
code = "{variable}_var",
914-
applicability = "maybe-incorrect"
916+
applicability = "maybe-incorrect",
917+
style = "verbose"
915918
)]
916-
#[label(mir_build_confused)]
917919
pub(crate) struct InterpretedAsConst {
918920
#[primary_span]
919921
pub(crate) span: Span,

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

+48-8
Original file line numberDiff line numberDiff line change
@@ -678,8 +678,25 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
678678
let mut let_suggestion = None;
679679
let mut misc_suggestion = None;
680680
let mut interpreted_as_const = None;
681+
let mut interpreted_as_const_sugg = None;
681682

682-
if let PatKind::Constant { .. }
683+
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. }
684+
| PatKind::AscribeUserType {
685+
subpattern:
686+
box Pat { kind: PatKind::ExpandedConstant { def_id, is_inline: false, .. }, .. },
687+
..
688+
} = pat.kind
689+
&& let DefKind::Const = self.tcx.def_kind(def_id)
690+
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
691+
// We filter out paths with multiple path::segments.
692+
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
693+
{
694+
let span = self.tcx.def_span(def_id);
695+
let variable = self.tcx.item_name(def_id).to_string();
696+
// When we encounter a constant as the binding name, point at the `const` definition.
697+
interpreted_as_const = Some(span);
698+
interpreted_as_const_sugg = Some(InterpretedAsConst { span: pat.span, variable });
699+
} else if let PatKind::Constant { .. }
683700
| PatKind::AscribeUserType {
684701
subpattern: box Pat { kind: PatKind::Constant { .. }, .. },
685702
..
@@ -692,9 +709,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
692709
misc_suggestion = Some(MiscPatternSuggestion::AttemptedIntegerLiteral {
693710
start_span: pat.span.shrink_to_lo(),
694711
});
695-
} else if snippet.chars().all(|c| c.is_alphanumeric() || c == '_') {
696-
interpreted_as_const =
697-
Some(InterpretedAsConst { span: pat.span, variable: snippet });
698712
}
699713
}
700714

@@ -743,6 +757,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
743757
uncovered: Uncovered::new(pat.span, &cx, witnesses),
744758
inform,
745759
interpreted_as_const,
760+
interpreted_as_const_sugg,
746761
witness_1_is_privately_uninhabited,
747762
_p: (),
748763
pattern_ty,
@@ -1112,13 +1127,13 @@ fn report_non_exhaustive_match<'p, 'tcx>(
11121127
if ty.is_ptr_sized_integral() {
11131128
if ty.inner() == cx.tcx.types.usize {
11141129
err.note(format!(
1115-
"`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
1116-
exhaustively",
1130+
"`{ty}` does not have a fixed maximum value, so half-open ranges are \
1131+
necessary to match exhaustively",
11171132
));
11181133
} else if ty.inner() == cx.tcx.types.isize {
11191134
err.note(format!(
1120-
"`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
1121-
exhaustively",
1135+
"`{ty}` does not have fixed minimum and maximum values, so half-open \
1136+
ranges are necessary to match exhaustively",
11221137
));
11231138
}
11241139
} else if ty.inner() == cx.tcx.types.str_ {
@@ -1139,6 +1154,31 @@ fn report_non_exhaustive_match<'p, 'tcx>(
11391154
}
11401155
}
11411156

1157+
for &arm in arms {
1158+
let arm = &thir.arms[arm];
1159+
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = arm.pattern.kind
1160+
&& let Ok(snippet) = cx.tcx.sess.source_map().span_to_snippet(arm.pattern.span)
1161+
// We filter out paths with multiple path::segments.
1162+
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
1163+
{
1164+
let const_name = cx.tcx.item_name(def_id);
1165+
err.span_label(
1166+
arm.pattern.span,
1167+
format!(
1168+
"this pattern doesn't introduce a new catch-all binding, but rather pattern \
1169+
matches against the value of constant `{const_name}`",
1170+
),
1171+
);
1172+
err.span_note(cx.tcx.def_span(def_id), format!("constant `{const_name}` defined here"));
1173+
err.span_suggestion_verbose(
1174+
arm.pattern.span.shrink_to_hi(),
1175+
"if you meant to introduce a binding, use a different name",
1176+
"_var".to_string(),
1177+
Applicability::MaybeIncorrect,
1178+
);
1179+
}
1180+
}
1181+
11421182
// Whether we suggest the actual missing patterns or `_`.
11431183
let suggest_the_witnesses = witnesses.len() < 4;
11441184
let suggested_arm = if suggest_the_witnesses {

0 commit comments

Comments
 (0)