Skip to content

Commit b1a0607

Browse files
committed
Process bindings and ascriptions in MatchPair::new()
1 parent a181bdc commit b1a0607

File tree

4 files changed

+77
-90
lines changed

4 files changed

+77
-90
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,7 @@ struct Ascription<'tcx> {
10541054

10551055
#[derive(Debug, Clone)]
10561056
enum TestCase<'pat, 'tcx> {
1057-
Irrefutable,
1057+
Irrefutable { binding: Option<Binding<'tcx>>, ascription: Option<Ascription<'tcx>> },
10581058
Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
10591059
Constant { value: mir::Const<'tcx> },
10601060
Range(&'pat PatRange<'tcx>),

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

+6-74
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
use crate::build::expr::as_place::PlaceBuilder;
1616
use crate::build::matches::{Ascription, Binding, Candidate, MatchPair, TestCase};
1717
use crate::build::Builder;
18-
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
19-
use rustc_middle::thir::{self, *};
20-
use rustc_middle::ty;
18+
use rustc_middle::thir::{Pat, PatKind};
2119

2220
use std::mem;
2321

@@ -128,79 +126,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
128126
ascriptions: &mut Vec<Ascription<'tcx>>,
129127
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
130128
) -> Result<(), MatchPair<'pat, 'tcx>> {
131-
// Collect bindings and ascriptions.
132-
match match_pair.pattern.kind {
133-
PatKind::AscribeUserType {
134-
ascription: thir::Ascription { ref annotation, variance },
135-
..
136-
} => {
137-
// Apply the type ascription to the value at `match_pair.place`
138-
if let Some(source) = match_pair.place.try_to_place(self) {
139-
ascriptions.push(Ascription {
140-
annotation: annotation.clone(),
141-
source,
142-
variance,
143-
});
144-
}
129+
if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case {
130+
if let Some(binding) = binding {
131+
bindings.push(binding);
145132
}
146-
147-
PatKind::Binding {
148-
name: _,
149-
mutability: _,
150-
mode,
151-
var,
152-
ty: _,
153-
subpattern: _,
154-
is_primary: _,
155-
} => {
156-
if let Some(source) = match_pair.place.try_to_place(self) {
157-
bindings.push(Binding {
158-
span: match_pair.pattern.span,
159-
source,
160-
var_id: var,
161-
binding_mode: mode,
162-
});
163-
}
133+
if let Some(ascription) = ascription {
134+
ascriptions.push(ascription);
164135
}
165-
166-
PatKind::InlineConstant { subpattern: ref pattern, def } => {
167-
// Apply a type ascription for the inline constant to the value at `match_pair.place`
168-
if let Some(source) = match_pair.place.try_to_place(self) {
169-
let span = match_pair.pattern.span;
170-
let parent_id = self.tcx.typeck_root_def_id(self.def_id.to_def_id());
171-
let args = ty::InlineConstArgs::new(
172-
self.tcx,
173-
ty::InlineConstArgsParts {
174-
parent_args: ty::GenericArgs::identity_for_item(self.tcx, parent_id),
175-
ty: self.infcx.next_ty_var(TypeVariableOrigin {
176-
kind: TypeVariableOriginKind::MiscVariable,
177-
span,
178-
}),
179-
},
180-
)
181-
.args;
182-
let user_ty =
183-
self.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
184-
def.to_def_id(),
185-
ty::UserArgs { args, user_self_ty: None },
186-
));
187-
let annotation = ty::CanonicalUserTypeAnnotation {
188-
inferred_ty: pattern.ty,
189-
span,
190-
user_ty: Box::new(user_ty),
191-
};
192-
ascriptions.push(Ascription {
193-
annotation,
194-
source,
195-
variance: ty::Contravariant,
196-
});
197-
}
198-
}
199-
200-
_ => {}
201-
}
202-
203-
if let TestCase::Irrefutable = match_pair.test_case {
204136
// Simplifiable pattern; we replace it with its subpairs.
205137
match_pairs.append(&mut match_pair.subpairs);
206138
Ok(())

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
6060

6161
TestCase::Or { .. } => bug!("or-patterns should have already been handled"),
6262

63-
TestCase::Irrefutable => span_bug!(
63+
TestCase::Irrefutable { .. } => span_bug!(
6464
match_pair.pattern.span,
6565
"simplifiable pattern found: {:?}",
6666
match_pair.pattern

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

+69-14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::build::expr::as_place::{PlaceBase, PlaceBuilder};
22
use crate::build::matches::{MatchPair, TestCase};
33
use crate::build::Builder;
4+
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
45
use rustc_middle::mir::*;
5-
use rustc_middle::thir::*;
6+
use rustc_middle::thir::{self, *};
67
use rustc_middle::ty;
78
use rustc_middle::ty::TypeVisitableExt;
89

@@ -116,48 +117,102 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
116117
place = place.project(ProjectionElem::OpaqueCast(pattern.ty));
117118
}
118119

120+
let default_irrefutable = || TestCase::Irrefutable { binding: None, ascription: None };
119121
let mut subpairs = Vec::new();
120122
let test_case = match pattern.kind {
121-
PatKind::Never | PatKind::Wild | PatKind::Error(_) => TestCase::Irrefutable,
123+
PatKind::Never | PatKind::Wild | PatKind::Error(_) => default_irrefutable(),
122124
PatKind::Or { .. } => TestCase::Or,
123125

124126
PatKind::Range(ref range) => {
125127
if range.is_full_range(cx.tcx) == Some(true) {
126-
TestCase::Irrefutable
128+
default_irrefutable()
127129
} else {
128130
TestCase::Range(range)
129131
}
130132
}
131133

132134
PatKind::Constant { value } => TestCase::Constant { value },
133135

134-
PatKind::AscribeUserType { ref subpattern, .. } => {
136+
PatKind::AscribeUserType {
137+
ascription: thir::Ascription { ref annotation, variance },
138+
ref subpattern,
139+
..
140+
} => {
141+
// Apply the type ascription to the value at `match_pair.place`
142+
let ascription = place.try_to_place(cx).map(|source| super::Ascription {
143+
annotation: annotation.clone(),
144+
source,
145+
variance,
146+
});
147+
135148
subpairs.push(MatchPair::new(place.clone(), subpattern, cx));
136-
TestCase::Irrefutable
149+
TestCase::Irrefutable { ascription, binding: None }
137150
}
138151

139-
PatKind::Binding { ref subpattern, .. } => {
152+
PatKind::Binding {
153+
name: _,
154+
mutability: _,
155+
mode,
156+
var,
157+
ty: _,
158+
ref subpattern,
159+
is_primary: _,
160+
} => {
161+
let binding = place.try_to_place(cx).map(|source| super::Binding {
162+
span: pattern.span,
163+
source,
164+
var_id: var,
165+
binding_mode: mode,
166+
});
167+
140168
if let Some(subpattern) = subpattern.as_ref() {
141169
// this is the `x @ P` case; have to keep matching against `P` now
142170
subpairs.push(MatchPair::new(place.clone(), subpattern, cx));
143171
}
144-
TestCase::Irrefutable
172+
TestCase::Irrefutable { ascription: None, binding }
145173
}
146174

147-
PatKind::InlineConstant { subpattern: ref pattern, .. } => {
175+
PatKind::InlineConstant { subpattern: ref pattern, def, .. } => {
176+
// Apply a type ascription for the inline constant to the value at `match_pair.place`
177+
let ascription = place.try_to_place(cx).map(|source| {
178+
let span = pattern.span;
179+
let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id());
180+
let args = ty::InlineConstArgs::new(
181+
cx.tcx,
182+
ty::InlineConstArgsParts {
183+
parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id),
184+
ty: cx.infcx.next_ty_var(TypeVariableOrigin {
185+
kind: TypeVariableOriginKind::MiscVariable,
186+
span,
187+
}),
188+
},
189+
)
190+
.args;
191+
let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
192+
def.to_def_id(),
193+
ty::UserArgs { args, user_self_ty: None },
194+
));
195+
let annotation = ty::CanonicalUserTypeAnnotation {
196+
inferred_ty: pattern.ty,
197+
span,
198+
user_ty: Box::new(user_ty),
199+
};
200+
super::Ascription { annotation, source, variance: ty::Contravariant }
201+
});
202+
148203
subpairs.push(MatchPair::new(place.clone(), pattern, cx));
149-
TestCase::Irrefutable
204+
TestCase::Irrefutable { ascription, binding: None }
150205
}
151206

152207
PatKind::Array { ref prefix, ref slice, ref suffix } => {
153208
cx.prefix_slice_suffix(&mut subpairs, &place, prefix, slice, suffix);
154-
TestCase::Irrefutable
209+
default_irrefutable()
155210
}
156211
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
157212
cx.prefix_slice_suffix(&mut subpairs, &place, prefix, slice, suffix);
158213

159214
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
160-
TestCase::Irrefutable
215+
default_irrefutable()
161216
} else {
162217
TestCase::Slice {
163218
len: prefix.len() + suffix.len(),
@@ -182,21 +237,21 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
182237
}) && (adt_def.did().is_local()
183238
|| !adt_def.is_variant_list_non_exhaustive());
184239
if irrefutable {
185-
TestCase::Irrefutable
240+
default_irrefutable()
186241
} else {
187242
TestCase::Variant { adt_def, variant_index }
188243
}
189244
}
190245

191246
PatKind::Leaf { ref subpatterns } => {
192247
subpairs = cx.field_match_pairs(place.clone(), subpatterns);
193-
TestCase::Irrefutable
248+
default_irrefutable()
194249
}
195250

196251
PatKind::Deref { ref subpattern } => {
197252
let place_builder = place.clone().deref();
198253
subpairs.push(MatchPair::new(place_builder, subpattern, cx));
199-
TestCase::Irrefutable
254+
default_irrefutable()
200255
}
201256
};
202257

0 commit comments

Comments
 (0)