11use crate :: build:: expr:: as_place:: { PlaceBase , PlaceBuilder } ;
22use crate :: build:: matches:: { MatchPair , TestCase } ;
33use crate :: build:: Builder ;
4+ use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
45use rustc_middle:: mir:: * ;
5- use rustc_middle:: thir:: * ;
6+ use rustc_middle:: thir:: { self , * } ;
67use rustc_middle:: ty;
78use 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