Skip to content

Commit 8516c64

Browse files
committed
Replace AscribeUserType and ExpandedConstant with per-node data
1 parent bd77048 commit 8516c64

File tree

12 files changed

+69
-212
lines changed

12 files changed

+69
-212
lines changed

‎compiler/rustc_middle/src/thir.rs‎

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -778,11 +778,6 @@ pub enum PatKind<'tcx> {
778778
/// A wildcard pattern: `_`.
779779
Wild,
780780

781-
AscribeUserType {
782-
ascription: Ascription<'tcx>,
783-
subpattern: Box<Pat<'tcx>>,
784-
},
785-
786781
/// `x`, `ref x`, `x @ P`, etc.
787782
Binding {
788783
name: Symbol,
@@ -847,21 +842,6 @@ pub enum PatKind<'tcx> {
847842
value: ty::Value<'tcx>,
848843
},
849844

850-
/// Wrapper node representing a named constant that was lowered to a pattern
851-
/// using `const_to_pat`.
852-
///
853-
/// This is used by some diagnostics for non-exhaustive matches, to map
854-
/// the pattern node back to the `DefId` of its original constant.
855-
///
856-
/// FIXME(#150498): Can we make this an `Option<DefId>` field on `Pat`
857-
/// instead, so that non-diagnostic code can ignore it more easily?
858-
ExpandedConstant {
859-
/// [DefId] of the constant item.
860-
def_id: DefId,
861-
/// The pattern that the constant lowered to.
862-
subpattern: Box<Pat<'tcx>>,
863-
},
864-
865845
Range(Arc<PatRange<'tcx>>),
866846

867847
/// Matches against a slice, checking the length and extracting elements.

‎compiler/rustc_middle/src/thir/visit.rs‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,9 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
269269
| PatKind::Never
270270
| PatKind::Error(_) => {}
271271

272-
PatKind::AscribeUserType { subpattern, .. }
273-
| PatKind::Binding { subpattern: Some(subpattern), .. }
272+
PatKind::Binding { subpattern: Some(subpattern), .. }
274273
| PatKind::Deref { subpattern }
275-
| PatKind::DerefPattern { subpattern, .. }
276-
| PatKind::ExpandedConstant { subpattern, .. } => callback(subpattern),
274+
| PatKind::DerefPattern { subpattern, .. } => callback(subpattern),
277275

278276
PatKind::Variant { subpatterns, .. } | PatKind::Leaf { subpatterns } => {
279277
for field_pat in subpatterns {

‎compiler/rustc_mir_build/src/builder/custom/parse.rs‎

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -287,22 +287,14 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
287287
self.parse_var(pattern)
288288
}
289289

290-
fn parse_var(&mut self, mut pat: &Pat<'tcx>) -> PResult<(LocalVarId, Ty<'tcx>, Span)> {
291-
// Make sure we throw out any `AscribeUserType` we find
292-
loop {
293-
match &pat.kind {
294-
PatKind::Binding { var, ty, .. } => break Ok((*var, *ty, pat.span)),
295-
PatKind::AscribeUserType { subpattern, .. } => {
296-
pat = subpattern;
297-
}
298-
_ => {
299-
break Err(ParseError {
300-
span: pat.span,
301-
item_description: format!("{:?}", pat.kind),
302-
expected: "local".to_string(),
303-
});
304-
}
305-
}
290+
fn parse_var(&mut self, pat: &Pat<'tcx>) -> PResult<(LocalVarId, Ty<'tcx>, Span)> {
291+
match &pat.kind {
292+
PatKind::Binding { var, ty, .. } => Ok((*var, *ty, pat.span)),
293+
_ => Err(ParseError {
294+
span: pat.span,
295+
item_description: format!("{:?}", pat.kind),
296+
expected: "local".to_string(),
297+
}),
306298
}
307299
}
308300

‎compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,6 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
144144
let arm = &self.thir[*arm];
145145
let value = match arm.pattern.kind {
146146
PatKind::Constant { value } => value,
147-
PatKind::ExpandedConstant { ref subpattern, def_id: _ }
148-
if let PatKind::Constant { value } = subpattern.kind =>
149-
{
150-
value
151-
}
152147
_ => {
153148
return Err(ParseError {
154149
span: arm.pattern.span,

‎compiler/rustc_mir_build/src/builder/matches/match_pair.rs‎

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ impl<'tcx> MatchPairTree<'tcx> {
133133
}
134134

135135
let place = place_builder.try_to_place(cx);
136+
137+
// Apply any type ascriptions to the value at `match_pair.place`.
138+
if let Some(place) = place
139+
&& let Some(extra) = &pattern.extra
140+
{
141+
for &Ascription { ref annotation, variance } in &extra.ascriptions {
142+
extra_data.ascriptions.push(super::Ascription {
143+
source: place,
144+
annotation: annotation.clone(),
145+
variance,
146+
});
147+
}
148+
}
149+
136150
let mut subpairs = Vec::new();
137151
let testable_case = match pattern.kind {
138152
PatKind::Missing | PatKind::Wild | PatKind::Error(_) => None,
@@ -195,28 +209,6 @@ impl<'tcx> MatchPairTree<'tcx> {
195209
Some(TestableCase::Constant { value, kind: const_kind })
196210
}
197211

198-
PatKind::AscribeUserType {
199-
ascription: Ascription { ref annotation, variance },
200-
ref subpattern,
201-
..
202-
} => {
203-
MatchPairTree::for_pattern(
204-
place_builder,
205-
subpattern,
206-
cx,
207-
&mut subpairs,
208-
extra_data,
209-
);
210-
211-
// Apply the type ascription to the value at `match_pair.place`
212-
if let Some(source) = place {
213-
let annotation = annotation.clone();
214-
extra_data.ascriptions.push(super::Ascription { source, annotation, variance });
215-
}
216-
217-
None
218-
}
219-
220212
PatKind::Binding { mode, var, is_shorthand, ref subpattern, .. } => {
221213
// In order to please the borrow checker, when lowering a pattern
222214
// like `x @ subpat` we must establish any bindings in `subpat`
@@ -263,11 +255,6 @@ impl<'tcx> MatchPairTree<'tcx> {
263255
None
264256
}
265257

266-
PatKind::ExpandedConstant { subpattern: ref pattern, .. } => {
267-
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
268-
None
269-
}
270-
271258
PatKind::Array { ref prefix, ref slice, ref suffix } => {
272259
cx.prefix_slice_suffix(
273260
&mut subpairs,

‎compiler/rustc_mir_build/src/builder/matches/mod.rs‎

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
576576
initializer_id: ExprId,
577577
) -> BlockAnd<()> {
578578
match irrefutable_pat.kind {
579-
// Optimize the case of `let x = ...` to write directly into `x`
579+
// Optimize `let x = ...` and `let x: T = ...` to write directly into `x`,
580+
// and then require that `T == typeof(x)` if present.
580581
PatKind::Binding { mode: BindingMode(ByRef::No, _), var, subpattern: None, .. } => {
581582
let place = self.storage_live_binding(
582583
block,
@@ -592,43 +593,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
592593
let source_info = self.source_info(irrefutable_pat.span);
593594
self.cfg.push_fake_read(block, source_info, FakeReadCause::ForLet(None), place);
594595

595-
self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
596-
block.unit()
597-
}
598-
599-
// Optimize the case of `let x: T = ...` to write directly
600-
// into `x` and then require that `T == typeof(x)`.
601-
PatKind::AscribeUserType {
602-
ref subpattern,
603-
ascription: thir::Ascription { ref annotation, variance: _ },
604-
} if let PatKind::Binding {
605-
mode: BindingMode(ByRef::No, _),
606-
var,
607-
subpattern: None,
608-
..
609-
} = subpattern.kind =>
610-
{
611-
let place = self.storage_live_binding(
612-
block,
613-
var,
614-
irrefutable_pat.span,
615-
false,
616-
OutsideGuard,
617-
ScheduleDrops::Yes,
618-
);
619-
block = self.expr_into_dest(place, block, initializer_id).into_block();
596+
let ascriptions: &[_] =
597+
try { irrefutable_pat.extra.as_deref()?.ascriptions.as_slice() }
598+
.unwrap_or_default();
599+
for thir::Ascription { annotation, variance: _ } in ascriptions {
600+
let ty_source_info = self.source_info(annotation.span);
620601

621-
// Inject a fake read, see comments on `FakeReadCause::ForLet`.
622-
let pattern_source_info = self.source_info(irrefutable_pat.span);
623-
let cause_let = FakeReadCause::ForLet(None);
624-
self.cfg.push_fake_read(block, pattern_source_info, cause_let, place);
625-
626-
let ty_source_info = self.source_info(annotation.span);
627-
628-
let base = self.canonical_user_type_annotations.push(annotation.clone());
629-
self.cfg.push(
630-
block,
631-
Statement::new(
602+
let base = self.canonical_user_type_annotations.push(annotation.clone());
603+
let stmt = Statement::new(
632604
ty_source_info,
633605
StatementKind::AscribeUserType(
634606
Box::new((place, UserTypeProjection { base, projs: Vec::new() })),
@@ -648,8 +620,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
648620
// `<expr>`.
649621
ty::Invariant,
650622
),
651-
),
652-
);
623+
);
624+
self.cfg.push(block, stmt);
625+
}
653626

654627
self.schedule_drop_for_binding(var, irrefutable_pat.span, OutsideGuard);
655628
block.unit()
@@ -884,9 +857,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
884857
// Caution: Pushing user types here is load-bearing even for
885858
// patterns containing no bindings, to ensure that the type ends
886859
// up represented in MIR _somewhere_.
887-
let user_tys = match pattern.kind {
888-
PatKind::AscribeUserType { ref ascription, .. } => {
889-
let base_user_tys = std::iter::once(ascription)
860+
let user_tys = match pattern.extra.as_deref() {
861+
Some(PatExtra { ascriptions, .. }) if !ascriptions.is_empty() => {
862+
let base_user_tys = ascriptions
863+
.iter()
890864
.map(|thir::Ascription { annotation, variance: _ }| {
891865
// Note that the variance doesn't apply here, as we are tracking the effect
892866
// of user types on any bindings contained with subpattern.
@@ -943,15 +917,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
943917
visit_subpat(self, subpattern, &ProjectedUserTypesNode::None, f);
944918
}
945919

946-
PatKind::AscribeUserType { ref subpattern, ascription: _ } => {
947-
// The ascription was already handled above, so just recurse to the subpattern.
948-
visit_subpat(self, subpattern, user_tys, f)
949-
}
950-
951-
PatKind::ExpandedConstant { ref subpattern, .. } => {
952-
visit_subpat(self, subpattern, user_tys, f)
953-
}
954-
955920
PatKind::Leaf { ref subpatterns } => {
956921
for subpattern in subpatterns {
957922
let subpattern_user_tys = user_tys.leaf(subpattern.field);

‎compiler/rustc_mir_build/src/check_unsafety.rs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,6 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
342342
PatKind::Wild |
343343
// these just wrap other patterns, which we recurse on below.
344344
PatKind::Or { .. } |
345-
PatKind::ExpandedConstant { .. } |
346-
PatKind::AscribeUserType { .. } |
347345
PatKind::Error(_) => {}
348346
}
349347
};

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

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -680,20 +680,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
680680
let mut interpreted_as_const = None;
681681
let mut interpreted_as_const_sugg = None;
682682

683-
// These next few matches want to peek through `AscribeUserType` to see
684-
// the underlying pattern.
685-
let mut unpeeled_pat = pat;
686-
while let PatKind::AscribeUserType { ref subpattern, .. } = unpeeled_pat.kind {
687-
unpeeled_pat = subpattern;
688-
}
689-
690-
if let Some(def_id) = is_const_pat_that_looks_like_binding(self.tcx, unpeeled_pat) {
683+
if let Some(def_id) = is_const_pat_that_looks_like_binding(self.tcx, pat) {
691684
let span = self.tcx.def_span(def_id);
692685
let variable = self.tcx.item_name(def_id).to_string();
693686
// When we encounter a constant as the binding name, point at the `const` definition.
694687
interpreted_as_const = Some(InterpretedAsConst { span, variable: variable.clone() });
695688
interpreted_as_const_sugg = Some(InterpretedAsConstSugg { span: pat.span, variable });
696-
} else if let PatKind::Constant { .. } = unpeeled_pat.kind
689+
} else if let PatKind::Constant { .. } = pat.kind
697690
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
698691
{
699692
// If the pattern to match is an integer literal:
@@ -1213,7 +1206,7 @@ fn is_const_pat_that_looks_like_binding<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat<'tcx>
12131206
// The pattern must be a named constant, and the name that appears in
12141207
// the pattern's source text must resemble a plain identifier without any
12151208
// `::` namespace separators or other non-identifier characters.
1216-
if let PatKind::ExpandedConstant { def_id, .. } = pat.kind
1209+
if let Some(def_id) = try { pat.extra.as_deref()?.expanded_const? }
12171210
&& matches!(tcx.def_kind(def_id), DefKind::Const)
12181211
&& let Ok(snippet) = tcx.sess.source_map().span_to_snippet(pat.span)
12191212
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')

‎compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,9 @@ impl<'tcx> ConstToPat<'tcx> {
186186
}
187187
}
188188

189-
// Wrap the pattern in a marker node to indicate that it is the result of lowering a
189+
// Mark the pattern to indicate that it is the result of lowering a named
190190
// constant. This is used for diagnostics.
191-
thir_pat = Box::new(Pat {
192-
ty: thir_pat.ty,
193-
span: thir_pat.span,
194-
kind: PatKind::ExpandedConstant { def_id: uv.def, subpattern: thir_pat },
195-
extra: None,
196-
});
191+
thir_pat.extra.get_or_insert_default().expanded_const = Some(uv.def);
197192
thir_pat
198193
}
199194

0 commit comments

Comments
 (0)