@@ -47,7 +47,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
47
47
) ;
48
48
49
49
let tcx = self . tcx ;
50
- let id = expr. hir_id ;
51
50
match expr. node {
52
51
ExprKind :: Box ( ref subexpr) => {
53
52
self . check_expr_box ( subexpr, expected)
@@ -68,63 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
68
67
self . check_expr_addr_of ( mutbl, oprnd, expected, expr)
69
68
}
70
69
ExprKind :: Path ( ref qpath) => {
71
- let ( res, opt_ty, segs) = self . resolve_ty_and_res_ufcs ( qpath, expr. hir_id ,
72
- expr. span ) ;
73
- let ty = match res {
74
- Res :: Err => {
75
- self . set_tainted_by_errors ( ) ;
76
- tcx. types . err
77
- }
78
- Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fictive ) , _) => {
79
- report_unexpected_variant_res ( tcx, res, expr. span , qpath) ;
80
- tcx. types . err
81
- }
82
- _ => self . instantiate_value_path ( segs, opt_ty, res, expr. span , id) . 0 ,
83
- } ;
84
-
85
- if let ty:: FnDef ( ..) = ty. sty {
86
- let fn_sig = ty. fn_sig ( tcx) ;
87
- if !tcx. features ( ) . unsized_locals {
88
- // We want to remove some Sized bounds from std functions,
89
- // but don't want to expose the removal to stable Rust.
90
- // i.e., we don't want to allow
91
- //
92
- // ```rust
93
- // drop as fn(str);
94
- // ```
95
- //
96
- // to work in stable even if the Sized bound on `drop` is relaxed.
97
- for i in 0 ..fn_sig. inputs ( ) . skip_binder ( ) . len ( ) {
98
- // We just want to check sizedness, so instead of introducing
99
- // placeholder lifetimes with probing, we just replace higher lifetimes
100
- // with fresh vars.
101
- let input = self . replace_bound_vars_with_fresh_vars (
102
- expr. span ,
103
- infer:: LateBoundRegionConversionTime :: FnCall ,
104
- & fn_sig. input ( i) ) . 0 ;
105
- self . require_type_is_sized_deferred ( input, expr. span ,
106
- traits:: SizedArgumentType ) ;
107
- }
108
- }
109
- // Here we want to prevent struct constructors from returning unsized types.
110
- // There were two cases this happened: fn pointer coercion in stable
111
- // and usual function call in presense of unsized_locals.
112
- // Also, as we just want to check sizedness, instead of introducing
113
- // placeholder lifetimes with probing, we just replace higher lifetimes
114
- // with fresh vars.
115
- let output = self . replace_bound_vars_with_fresh_vars (
116
- expr. span ,
117
- infer:: LateBoundRegionConversionTime :: FnCall ,
118
- & fn_sig. output ( ) ) . 0 ;
119
- self . require_type_is_sized_deferred ( output, expr. span , traits:: SizedReturnType ) ;
120
- }
121
-
122
- // We always require that the type provided as the value for
123
- // a type parameter outlives the moment of instantiation.
124
- let substs = self . tables . borrow ( ) . node_substs ( expr. hir_id ) ;
125
- self . add_wf_bounds ( substs, expr) ;
126
-
127
- ty
70
+ self . check_expr_path ( qpath, expr)
128
71
}
129
72
ExprKind :: InlineAsm ( _, ref outputs, ref inputs) => {
130
73
for expr in outputs. iter ( ) . chain ( inputs. iter ( ) ) {
@@ -722,4 +665,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
722
665
self . tcx . mk_ref ( region, tm)
723
666
}
724
667
}
668
+
669
+ fn check_expr_path ( & self , qpath : & hir:: QPath , expr : & ' tcx hir:: Expr ) -> Ty < ' tcx > {
670
+ let tcx = self . tcx ;
671
+ let ( res, opt_ty, segs) = self . resolve_ty_and_res_ufcs ( qpath, expr. hir_id , expr. span ) ;
672
+ let ty = match res {
673
+ Res :: Err => {
674
+ self . set_tainted_by_errors ( ) ;
675
+ tcx. types . err
676
+ }
677
+ Res :: Def ( DefKind :: Ctor ( _, CtorKind :: Fictive ) , _) => {
678
+ report_unexpected_variant_res ( tcx, res, expr. span , qpath) ;
679
+ tcx. types . err
680
+ }
681
+ _ => self . instantiate_value_path ( segs, opt_ty, res, expr. span , expr. hir_id ) . 0 ,
682
+ } ;
683
+
684
+ if let ty:: FnDef ( ..) = ty. sty {
685
+ let fn_sig = ty. fn_sig ( tcx) ;
686
+ if !tcx. features ( ) . unsized_locals {
687
+ // We want to remove some Sized bounds from std functions,
688
+ // but don't want to expose the removal to stable Rust.
689
+ // i.e., we don't want to allow
690
+ //
691
+ // ```rust
692
+ // drop as fn(str);
693
+ // ```
694
+ //
695
+ // to work in stable even if the Sized bound on `drop` is relaxed.
696
+ for i in 0 ..fn_sig. inputs ( ) . skip_binder ( ) . len ( ) {
697
+ // We just want to check sizedness, so instead of introducing
698
+ // placeholder lifetimes with probing, we just replace higher lifetimes
699
+ // with fresh vars.
700
+ let input = self . replace_bound_vars_with_fresh_vars (
701
+ expr. span ,
702
+ infer:: LateBoundRegionConversionTime :: FnCall ,
703
+ & fn_sig. input ( i) ) . 0 ;
704
+ self . require_type_is_sized_deferred ( input, expr. span ,
705
+ traits:: SizedArgumentType ) ;
706
+ }
707
+ }
708
+ // Here we want to prevent struct constructors from returning unsized types.
709
+ // There were two cases this happened: fn pointer coercion in stable
710
+ // and usual function call in presense of unsized_locals.
711
+ // Also, as we just want to check sizedness, instead of introducing
712
+ // placeholder lifetimes with probing, we just replace higher lifetimes
713
+ // with fresh vars.
714
+ let output = self . replace_bound_vars_with_fresh_vars (
715
+ expr. span ,
716
+ infer:: LateBoundRegionConversionTime :: FnCall ,
717
+ & fn_sig. output ( ) ) . 0 ;
718
+ self . require_type_is_sized_deferred ( output, expr. span , traits:: SizedReturnType ) ;
719
+ }
720
+
721
+ // We always require that the type provided as the value for
722
+ // a type parameter outlives the moment of instantiation.
723
+ let substs = self . tables . borrow ( ) . node_substs ( expr. hir_id ) ;
724
+ self . add_wf_bounds ( substs, expr) ;
725
+
726
+ ty
727
+ }
725
728
}
0 commit comments