@@ -18,10 +18,12 @@ use rustc_span::edit_distance::find_best_match_for_name;
18
18
use rustc_span:: hygiene:: DesugaringKind ;
19
19
use rustc_span:: source_map:: Spanned ;
20
20
use rustc_span:: symbol:: { kw, sym, Ident } ;
21
- use rustc_span:: Span ;
22
- use rustc_span:: { BytePos , DUMMY_SP } ;
21
+ use rustc_span:: { BytePos , Span , DUMMY_SP } ;
23
22
use rustc_target:: abi:: FieldIdx ;
24
- use rustc_trait_selection:: traits:: { ObligationCause , Pattern } ;
23
+ use rustc_trait_selection:: traits:: {
24
+ error_reporting:: TypeErrCtxtExt , ObligationCause , Pattern , StructurallyNormalizeExt ,
25
+ TraitEngine , TraitEngineExt ,
26
+ } ;
25
27
use ty:: VariantDef ;
26
28
27
29
use std:: cmp;
@@ -202,6 +204,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
202
204
PatKind :: Tuple ( elements, ddpos) => {
203
205
self . check_pat_tuple ( pat. span , elements, ddpos, expected, pat_info)
204
206
}
207
+ PatKind :: Box ( inner) if self . tcx . features ( ) . deref_patterns => {
208
+ self . check_pat_deref ( pat. span , inner, expected, pat_info)
209
+ }
205
210
PatKind :: Box ( inner) => self . check_pat_box ( pat. span , inner, expected, pat_info) ,
206
211
PatKind :: Ref ( inner, mutbl) => self . check_pat_ref ( pat, inner, mutbl, expected, pat_info) ,
207
212
PatKind :: Slice ( before, slice, after) => {
@@ -1966,6 +1971,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1966
1971
box_ty
1967
1972
}
1968
1973
1974
+ fn check_pat_deref (
1975
+ & self ,
1976
+ span : Span ,
1977
+ inner : & ' tcx Pat < ' tcx > ,
1978
+ expected : Ty < ' tcx > ,
1979
+ pat_info : PatInfo < ' tcx , ' _ > ,
1980
+ ) -> Ty < ' tcx > {
1981
+ let tcx = self . tcx ;
1982
+ // FIXME(deref_patterns): use `DerefPure` for soundness
1983
+ // FIXME(deref_patterns): use `DerefMut` when required
1984
+ // <expected as Deref>::Target
1985
+ let ty = Ty :: new_projection (
1986
+ tcx,
1987
+ tcx. require_lang_item ( hir:: LangItem :: DerefTarget , Some ( span) ) ,
1988
+ [ expected] ,
1989
+ ) ;
1990
+
1991
+ let mut fulfill_cx = <dyn TraitEngine < ' _ > >:: new ( & self . infcx ) ;
1992
+ let cause = self . pattern_cause ( pat_info. top_info , span) ;
1993
+ let normalized_ty = match self
1994
+ . infcx
1995
+ . at ( & cause, self . param_env )
1996
+ . structurally_normalize ( ty, & mut * fulfill_cx)
1997
+ {
1998
+ Ok ( normalized_ty) => normalized_ty,
1999
+ Err ( errors) => {
2000
+ let reported = self . infcx . err_ctxt ( ) . report_fulfillment_errors ( errors) ;
2001
+ return Ty :: new_error ( tcx, reported) ;
2002
+ }
2003
+ } ;
2004
+
2005
+ let ty = self . resolve_vars_if_possible ( normalized_ty) ;
2006
+ self . check_pat ( inner, ty, pat_info) ;
2007
+ expected
2008
+ }
2009
+
1969
2010
// Precondition: Pat is Ref(inner)
1970
2011
fn check_pat_ref (
1971
2012
& self ,
0 commit comments