@@ -161,6 +161,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
161
161
& self ,
162
162
expr : & ' tcx hir:: Expr < ' tcx > ,
163
163
expected : Expectation < ' tcx > ,
164
+ ) -> Ty < ' tcx > {
165
+ self . check_expr_with_expectation_and_args ( expr, expected, & [ ] )
166
+ }
167
+
168
+ /// Same as `check_expr_with_expectation`, but allows us to pass in the arguments of a
169
+ /// `ExprKind::Call` when evaluating its callee when it is an `ExprKind::Path`.
170
+ pub ( super ) fn check_expr_with_expectation_and_args (
171
+ & self ,
172
+ expr : & ' tcx hir:: Expr < ' tcx > ,
173
+ expected : Expectation < ' tcx > ,
174
+ args : & ' tcx [ hir:: Expr < ' tcx > ] ,
164
175
) -> Ty < ' tcx > {
165
176
if self . tcx ( ) . sess . verbose ( ) {
166
177
// make this code only run with -Zverbose because it is probably slow
@@ -198,7 +209,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
198
209
let old_diverges = self . diverges . replace ( Diverges :: Maybe ) ;
199
210
let old_has_errors = self . has_errors . replace ( false ) ;
200
211
201
- let ty = ensure_sufficient_stack ( || self . check_expr_kind ( expr, expected) ) ;
212
+ let ty = ensure_sufficient_stack ( || match & expr. kind {
213
+ hir:: ExprKind :: Path (
214
+ qpath @ hir:: QPath :: Resolved ( ..) | qpath @ hir:: QPath :: TypeRelative ( ..) ,
215
+ ) => self . check_expr_path ( qpath, expr, args) ,
216
+ _ => self . check_expr_kind ( expr, expected) ,
217
+ } ) ;
202
218
203
219
// Warn for non-block expressions with diverging children.
204
220
match expr. kind {
@@ -261,7 +277,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
261
277
ExprKind :: Path ( QPath :: LangItem ( lang_item, _) ) => {
262
278
self . check_lang_item_path ( lang_item, expr)
263
279
}
264
- ExprKind :: Path ( ref qpath) => self . check_expr_path ( qpath, expr) ,
280
+ ExprKind :: Path ( ref qpath) => self . check_expr_path ( qpath, expr, & [ ] ) ,
265
281
ExprKind :: InlineAsm ( asm) => self . check_expr_asm ( asm) ,
266
282
ExprKind :: LlvmInlineAsm ( asm) => {
267
283
for expr in asm. outputs_exprs . iter ( ) . chain ( asm. inputs_exprs . iter ( ) ) {
@@ -481,10 +497,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
481
497
self . resolve_lang_item_path ( lang_item, expr. span , expr. hir_id ) . 1
482
498
}
483
499
484
- fn check_expr_path (
500
+ pub ( crate ) fn check_expr_path (
485
501
& self ,
486
502
qpath : & ' tcx hir:: QPath < ' tcx > ,
487
503
expr : & ' tcx hir:: Expr < ' tcx > ,
504
+ args : & ' tcx [ hir:: Expr < ' tcx > ] ,
488
505
) -> Ty < ' tcx > {
489
506
let tcx = self . tcx ;
490
507
let ( res, opt_ty, segs) =
@@ -517,16 +534,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
517
534
// We just want to check sizedness, so instead of introducing
518
535
// placeholder lifetimes with probing, we just replace higher lifetimes
519
536
// with fresh vars.
537
+ let span = args. get ( i) . map ( |a| a. span ) . unwrap_or ( expr. span ) ;
520
538
let input = self
521
539
. replace_bound_vars_with_fresh_vars (
522
- expr . span ,
540
+ span,
523
541
infer:: LateBoundRegionConversionTime :: FnCall ,
524
542
fn_sig. input ( i) ,
525
543
)
526
544
. 0 ;
527
545
self . require_type_is_sized_deferred (
528
546
input,
529
- expr . span ,
547
+ span,
530
548
traits:: SizedArgumentType ( None ) ,
531
549
) ;
532
550
}
0 commit comments