Auto merge of #133261 - matthiaskrgr:rollup-ekui4we, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #129838 (uefi: process: Add args support) - #130800 (Mark `get_mut` and `set_position` in `std::io::Cursor` as const.) - #132708 (Point at `const` definition when used instead of a binding in a `let` statement) - #133226 (Make `PointerLike` opt-in instead of built-in) - #133244 (Account for `wasm32v1-none` when exporting TLS symbols) - #133257 (Add `UnordMap::clear` method) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2d0ea7956c
51 changed files with 627 additions and 266 deletions
|
@ -144,12 +144,20 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
|
|||
let mut targets = Vec::new();
|
||||
for arm in rest {
|
||||
let arm = &self.thir[*arm];
|
||||
let PatKind::Constant { value } = arm.pattern.kind else {
|
||||
return Err(ParseError {
|
||||
span: arm.pattern.span,
|
||||
item_description: format!("{:?}", arm.pattern.kind),
|
||||
expected: "constant pattern".to_string(),
|
||||
});
|
||||
let value = match arm.pattern.kind {
|
||||
PatKind::Constant { value } => value,
|
||||
PatKind::ExpandedConstant { ref subpattern, def_id: _, is_inline: false }
|
||||
if let PatKind::Constant { value } = subpattern.kind =>
|
||||
{
|
||||
value
|
||||
}
|
||||
_ => {
|
||||
return Err(ParseError {
|
||||
span: arm.pattern.span,
|
||||
item_description: format!("{:?}", arm.pattern.kind),
|
||||
expected: "constant pattern".to_string(),
|
||||
});
|
||||
}
|
||||
};
|
||||
values.push(value.eval_bits(self.tcx, self.typing_env));
|
||||
targets.push(self.parse_block(arm.body)?);
|
||||
|
|
|
@ -162,7 +162,11 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
|
|||
TestCase::Irrefutable { ascription: None, binding }
|
||||
}
|
||||
|
||||
PatKind::InlineConstant { subpattern: ref pattern, def, .. } => {
|
||||
PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
|
||||
subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
|
||||
default_irrefutable()
|
||||
}
|
||||
PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
|
||||
// Apply a type ascription for the inline constant to the value at `match_pair.place`
|
||||
let ascription = place.map(|source| {
|
||||
let span = pattern.span;
|
||||
|
@ -173,7 +177,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
|
|||
})
|
||||
.args;
|
||||
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
|
||||
def.to_def_id(),
|
||||
def_id,
|
||||
ty::UserArgs { args, user_self_ty: None },
|
||||
));
|
||||
let annotation = ty::CanonicalUserTypeAnnotation {
|
||||
|
|
|
@ -926,7 +926,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
self.visit_primary_bindings(subpattern, subpattern_user_ty, f)
|
||||
}
|
||||
|
||||
PatKind::InlineConstant { ref subpattern, .. } => {
|
||||
PatKind::ExpandedConstant { ref subpattern, .. } => {
|
||||
self.visit_primary_bindings(subpattern, pattern_user_ty, f)
|
||||
}
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
PatKind::Wild |
|
||||
// these just wrap other patterns, which we recurse on below.
|
||||
PatKind::Or { .. } |
|
||||
PatKind::InlineConstant { .. } |
|
||||
PatKind::ExpandedConstant { .. } |
|
||||
PatKind::AscribeUserType { .. } |
|
||||
PatKind::Error(_) => {}
|
||||
}
|
||||
|
@ -386,8 +386,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
visit::walk_pat(self, pat);
|
||||
self.inside_adt = old_inside_adt;
|
||||
}
|
||||
PatKind::InlineConstant { def, .. } => {
|
||||
self.visit_inner_body(*def);
|
||||
PatKind::ExpandedConstant { def_id, is_inline, .. } => {
|
||||
if let Some(def) = def_id.as_local()
|
||||
&& *is_inline
|
||||
{
|
||||
self.visit_inner_body(def);
|
||||
}
|
||||
visit::walk_pat(self, pat);
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -860,8 +860,10 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
|
|||
pub(crate) uncovered: Uncovered,
|
||||
#[subdiagnostic]
|
||||
pub(crate) inform: Option<Inform>,
|
||||
#[label(mir_build_confused)]
|
||||
pub(crate) interpreted_as_const: Option<Span>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) interpreted_as_const: Option<InterpretedAsConst>,
|
||||
pub(crate) interpreted_as_const_sugg: Option<InterpretedAsConst>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) adt_defined_here: Option<AdtDefinedHere<'tcx>>,
|
||||
#[note(mir_build_privately_uninhabited)]
|
||||
|
@ -911,9 +913,9 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> {
|
|||
#[suggestion(
|
||||
mir_build_interpreted_as_const,
|
||||
code = "{variable}_var",
|
||||
applicability = "maybe-incorrect"
|
||||
applicability = "maybe-incorrect",
|
||||
style = "verbose"
|
||||
)]
|
||||
#[label(mir_build_confused)]
|
||||
pub(crate) struct InterpretedAsConst {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
|
|
|
@ -678,8 +678,25 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
|
|||
let mut let_suggestion = None;
|
||||
let mut misc_suggestion = None;
|
||||
let mut interpreted_as_const = None;
|
||||
let mut interpreted_as_const_sugg = None;
|
||||
|
||||
if let PatKind::Constant { .. }
|
||||
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. }
|
||||
| PatKind::AscribeUserType {
|
||||
subpattern:
|
||||
box Pat { kind: PatKind::ExpandedConstant { def_id, is_inline: false, .. }, .. },
|
||||
..
|
||||
} = pat.kind
|
||||
&& let DefKind::Const = self.tcx.def_kind(def_id)
|
||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
|
||||
// We filter out paths with multiple path::segments.
|
||||
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
|
||||
{
|
||||
let span = self.tcx.def_span(def_id);
|
||||
let variable = self.tcx.item_name(def_id).to_string();
|
||||
// When we encounter a constant as the binding name, point at the `const` definition.
|
||||
interpreted_as_const = Some(span);
|
||||
interpreted_as_const_sugg = Some(InterpretedAsConst { span: pat.span, variable });
|
||||
} else if let PatKind::Constant { .. }
|
||||
| PatKind::AscribeUserType {
|
||||
subpattern: box Pat { kind: PatKind::Constant { .. }, .. },
|
||||
..
|
||||
|
@ -692,9 +709,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
|
|||
misc_suggestion = Some(MiscPatternSuggestion::AttemptedIntegerLiteral {
|
||||
start_span: pat.span.shrink_to_lo(),
|
||||
});
|
||||
} else if snippet.chars().all(|c| c.is_alphanumeric() || c == '_') {
|
||||
interpreted_as_const =
|
||||
Some(InterpretedAsConst { span: pat.span, variable: snippet });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,6 +757,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
|
|||
uncovered: Uncovered::new(pat.span, &cx, witnesses),
|
||||
inform,
|
||||
interpreted_as_const,
|
||||
interpreted_as_const_sugg,
|
||||
witness_1_is_privately_uninhabited,
|
||||
_p: (),
|
||||
pattern_ty,
|
||||
|
@ -1112,13 +1127,13 @@ fn report_non_exhaustive_match<'p, 'tcx>(
|
|||
if ty.is_ptr_sized_integral() {
|
||||
if ty.inner() == cx.tcx.types.usize {
|
||||
err.note(format!(
|
||||
"`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
|
||||
exhaustively",
|
||||
"`{ty}` does not have a fixed maximum value, so half-open ranges are \
|
||||
necessary to match exhaustively",
|
||||
));
|
||||
} else if ty.inner() == cx.tcx.types.isize {
|
||||
err.note(format!(
|
||||
"`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
|
||||
exhaustively",
|
||||
"`{ty}` does not have fixed minimum and maximum values, so half-open \
|
||||
ranges are necessary to match exhaustively",
|
||||
));
|
||||
}
|
||||
} else if ty.inner() == cx.tcx.types.str_ {
|
||||
|
@ -1139,6 +1154,31 @@ fn report_non_exhaustive_match<'p, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
for &arm in arms {
|
||||
let arm = &thir.arms[arm];
|
||||
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = arm.pattern.kind
|
||||
&& let Ok(snippet) = cx.tcx.sess.source_map().span_to_snippet(arm.pattern.span)
|
||||
// We filter out paths with multiple path::segments.
|
||||
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
|
||||
{
|
||||
let const_name = cx.tcx.item_name(def_id);
|
||||
err.span_label(
|
||||
arm.pattern.span,
|
||||
format!(
|
||||
"this pattern doesn't introduce a new catch-all binding, but rather pattern \
|
||||
matches against the value of constant `{const_name}`",
|
||||
),
|
||||
);
|
||||
err.span_note(cx.tcx.def_span(def_id), format!("constant `{const_name}` defined here"));
|
||||
err.span_suggestion_verbose(
|
||||
arm.pattern.span.shrink_to_hi(),
|
||||
"if you meant to introduce a binding, use a different name",
|
||||
"_var".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Whether we suggest the actual missing patterns or `_`.
|
||||
let suggest_the_witnesses = witnesses.len() < 4;
|
||||
let suggested_arm = if suggest_the_witnesses {
|
||||
|
|
|
@ -149,21 +149,30 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
None => Ok((None, None, None)),
|
||||
Some(expr) => {
|
||||
let (kind, ascr, inline_const) = match self.lower_lit(expr) {
|
||||
PatKind::InlineConstant { subpattern, def } => {
|
||||
(subpattern.kind, None, Some(def))
|
||||
PatKind::ExpandedConstant { subpattern, def_id, is_inline: true } => {
|
||||
(subpattern.kind, None, def_id.as_local())
|
||||
}
|
||||
PatKind::ExpandedConstant { subpattern, is_inline: false, .. } => {
|
||||
(subpattern.kind, None, None)
|
||||
}
|
||||
PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
|
||||
(kind, Some(ascription), None)
|
||||
}
|
||||
kind => (kind, None, None),
|
||||
};
|
||||
let value = if let PatKind::Constant { value } = kind {
|
||||
value
|
||||
} else {
|
||||
let msg = format!(
|
||||
"found bad range pattern endpoint `{expr:?}` outside of error recovery"
|
||||
);
|
||||
return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
|
||||
let value = match kind {
|
||||
PatKind::Constant { value } => value,
|
||||
PatKind::ExpandedConstant { subpattern, .. }
|
||||
if let PatKind::Constant { value } = subpattern.kind =>
|
||||
{
|
||||
value
|
||||
}
|
||||
_ => {
|
||||
let msg = format!(
|
||||
"found bad range pattern endpoint `{expr:?}` outside of error recovery"
|
||||
);
|
||||
return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
|
||||
}
|
||||
};
|
||||
Ok((Some(PatRangeBoundary::Finite(value)), ascr, inline_const))
|
||||
}
|
||||
|
@ -288,7 +297,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
};
|
||||
}
|
||||
for def in [lo_inline, hi_inline].into_iter().flatten() {
|
||||
kind = PatKind::InlineConstant { def, subpattern: Box::new(Pat { span, ty, kind }) };
|
||||
kind = PatKind::ExpandedConstant {
|
||||
def_id: def.to_def_id(),
|
||||
is_inline: true,
|
||||
subpattern: Box::new(Pat { span, ty, kind }),
|
||||
};
|
||||
}
|
||||
Ok(kind)
|
||||
}
|
||||
|
@ -562,7 +575,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
|
||||
let args = self.typeck_results.node_args(id);
|
||||
let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args });
|
||||
let pattern = self.const_to_pat(c, ty, id, span);
|
||||
let subpattern = self.const_to_pat(c, ty, id, span);
|
||||
let pattern = Box::new(Pat {
|
||||
span,
|
||||
ty,
|
||||
kind: PatKind::ExpandedConstant { subpattern, def_id, is_inline: false },
|
||||
});
|
||||
|
||||
if !is_associated_const {
|
||||
return pattern;
|
||||
|
@ -637,7 +655,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
|||
|
||||
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args };
|
||||
let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span);
|
||||
PatKind::InlineConstant { subpattern, def: def_id }
|
||||
PatKind::ExpandedConstant { subpattern, def_id: def_id.to_def_id(), is_inline: true }
|
||||
}
|
||||
|
||||
/// Converts literals, paths and negation of literals to patterns.
|
||||
|
|
|
@ -707,9 +707,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
|||
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
|
||||
print_indented!(self, "}", depth_lvl + 1);
|
||||
}
|
||||
PatKind::InlineConstant { def, subpattern } => {
|
||||
print_indented!(self, "InlineConstant {", depth_lvl + 1);
|
||||
print_indented!(self, format!("def: {:?}", def), depth_lvl + 2);
|
||||
PatKind::ExpandedConstant { def_id, is_inline, subpattern } => {
|
||||
print_indented!(self, "ExpandedConstant {", depth_lvl + 1);
|
||||
print_indented!(self, format!("def_id: {def_id:?}"), depth_lvl + 2);
|
||||
print_indented!(self, format!("is_inline: {is_inline:?}"), depth_lvl + 2);
|
||||
print_indented!(self, "subpattern:", depth_lvl + 2);
|
||||
self.print_pat(subpattern, depth_lvl + 2);
|
||||
print_indented!(self, "}", depth_lvl + 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue