@@ -18,10 +18,12 @@ use rustc_span::edit_distance::find_best_match_for_name;
1818use rustc_span:: hygiene:: DesugaringKind ;
1919use rustc_span:: source_map:: Spanned ;
2020use 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 } ;
2322use 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+ } ;
2527use ty:: VariantDef ;
2628
2729use std:: cmp;
@@ -202,6 +204,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
202204 PatKind :: Tuple ( elements, ddpos) => {
203205 self . check_pat_tuple ( pat. span , elements, ddpos, expected, pat_info)
204206 }
207+ PatKind :: Box ( inner) if self . tcx . features ( ) . deref_patterns => {
208+ self . check_pat_deref ( pat. span , inner, expected, pat_info)
209+ }
205210 PatKind :: Box ( inner) => self . check_pat_box ( pat. span , inner, expected, pat_info) ,
206211 PatKind :: Ref ( inner, mutbl) => self . check_pat_ref ( pat, inner, mutbl, expected, pat_info) ,
207212 PatKind :: Slice ( before, slice, after) => {
@@ -1966,6 +1971,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19661971 box_ty
19671972 }
19681973
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+
19692010 // Precondition: Pat is Ref(inner)
19702011 fn check_pat_ref (
19712012 & self ,
0 commit comments