@@ -55,6 +55,9 @@ use crate::{
5555} ;
5656
5757impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
58+ /// Check an expr with an expectation type, and also demand that the expr's
59+ /// evaluated type is a subtype of the expectation at the end. This is a
60+ /// *hard* requirement.
5861 pub ( crate ) fn check_expr_has_type_or_error (
5962 & self ,
6063 expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -97,6 +100,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
97100 ty
98101 }
99102
103+ /// Check an expr with an expectation type, and also demand that the expr's
104+ /// evaluated type is a coercible to the expectation at the end. This is a
105+ /// *hard* requirement.
100106 pub ( super ) fn check_expr_coercible_to_type (
101107 & self ,
102108 expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -128,6 +134,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
128134 }
129135 }
130136
137+ /// Check an expr with an expectation type. Don't actually enforce that expectation
138+ /// is related to the expr's evaluated type via subtyping or coercion. This is
139+ /// usually called because we want to do that subtype/coerce call manually for better
140+ /// diagnostics.
131141 pub ( super ) fn check_expr_with_hint (
132142 & self ,
133143 expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -136,6 +146,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
136146 self . check_expr_with_expectation ( expr, ExpectHasType ( expected) )
137147 }
138148
149+ /// Check an expr with an expectation type, and also [`Needs`] which will
150+ /// prompt typeck to convert any implicit immutable derefs to mutable derefs.
139151 fn check_expr_with_expectation_and_needs (
140152 & self ,
141153 expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -153,10 +165,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
153165 ty
154166 }
155167
168+ /// Check an expr with no expectations.
156169 pub ( super ) fn check_expr ( & self , expr : & ' tcx hir:: Expr < ' tcx > ) -> Ty < ' tcx > {
157170 self . check_expr_with_expectation ( expr, NoExpectation )
158171 }
159172
173+ /// Check an expr with no expectations, but with [`Needs`] which will
174+ /// prompt typeck to convert any implicit immutable derefs to mutable derefs.
160175 pub ( super ) fn check_expr_with_needs (
161176 & self ,
162177 expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -165,33 +180,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
165180 self . check_expr_with_expectation_and_needs ( expr, NoExpectation , needs)
166181 }
167182
168- /// Invariant:
169- /// If an expression has any sub-expressions that result in a type error,
170- /// inspecting that expression's type with `ty.references_error()` will return
171- /// true. Likewise, if an expression is known to diverge, inspecting its
172- /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
173- /// strict, _|_ can appear in the type of an expression that does not,
174- /// itself, diverge: for example, fn() -> _|_.)
175- /// Note that inspecting a type's structure *directly* may expose the fact
176- /// that there are actually multiple representations for `Error`, so avoid
177- /// that when err needs to be handled differently.
183+ /// Check an expr with an expectation type which may be used to eagerly
184+ /// guide inference when evaluating that expr.
178185 #[ instrument( skip( self , expr) , level = "debug" ) ]
179186 pub ( super ) fn check_expr_with_expectation (
180187 & self ,
181188 expr : & ' tcx hir:: Expr < ' tcx > ,
182189 expected : Expectation < ' tcx > ,
183190 ) -> Ty < ' tcx > {
184- self . check_expr_with_expectation_and_args ( expr, expected, & [ ] , None )
191+ self . check_expr_with_expectation_and_args ( expr, expected, None )
185192 }
186193
187- /// Same as `check_expr_with_expectation`, but allows us to pass in the arguments of a
188- /// `ExprKind::Call` when evaluating its callee when it is an `ExprKind::Path`.
194+ /// Same as [`Self::check_expr_with_expectation`], but allows us to pass in
195+ /// the arguments of a [`ExprKind::Call`] when evaluating its callee that
196+ /// is an [`ExprKind::Path`]. We use this to refine the spans for certain
197+ /// well-formedness guarantees for the path expr.
189198 pub ( super ) fn check_expr_with_expectation_and_args (
190199 & self ,
191200 expr : & ' tcx hir:: Expr < ' tcx > ,
192201 expected : Expectation < ' tcx > ,
193- args : & ' tcx [ hir:: Expr < ' tcx > ] ,
194- call : Option < & ' tcx hir:: Expr < ' tcx > > ,
202+ call_expr_and_args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
195203 ) -> Ty < ' tcx > {
196204 if self . tcx ( ) . sess . verbose_internals ( ) {
197205 // make this code only run with -Zverbose-internals because it is probably slow
@@ -236,9 +244,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
236244 } ;
237245
238246 let ty = ensure_sufficient_stack ( || match & expr. kind {
247+ // Intercept the callee path expr and give it better spans.
239248 hir:: ExprKind :: Path (
240249 qpath @ ( hir:: QPath :: Resolved ( ..) | hir:: QPath :: TypeRelative ( ..) ) ,
241- ) => self . check_expr_path ( qpath, expr, Some ( args ) , call ) ,
250+ ) => self . check_expr_path ( qpath, expr, call_expr_and_args ) ,
242251 _ => self . check_expr_kind ( expr, expected) ,
243252 } ) ;
244253 let ty = self . resolve_vars_if_possible ( ty) ;
@@ -472,28 +481,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
472481
473482 let tcx = self . tcx ;
474483 match expr. kind {
475- ExprKind :: Lit ( ref lit) => self . check_lit ( lit, expected) ,
476- ExprKind :: Binary ( op, lhs, rhs) => self . check_binop ( expr, op, lhs, rhs, expected) ,
484+ ExprKind :: Lit ( ref lit) => self . check_expr_lit ( lit, expected) ,
485+ ExprKind :: Binary ( op, lhs, rhs) => self . check_expr_binop ( expr, op, lhs, rhs, expected) ,
477486 ExprKind :: Assign ( lhs, rhs, span) => {
478487 self . check_expr_assign ( expr, expected, lhs, rhs, span)
479488 }
480489 ExprKind :: AssignOp ( op, lhs, rhs) => {
481- self . check_binop_assign ( expr, op, lhs, rhs, expected)
490+ self . check_expr_binop_assign ( expr, op, lhs, rhs, expected)
482491 }
483- ExprKind :: Unary ( unop, oprnd) => self . check_expr_unary ( unop, oprnd, expected, expr) ,
492+ ExprKind :: Unary ( unop, oprnd) => self . check_expr_unop ( unop, oprnd, expected, expr) ,
484493 ExprKind :: AddrOf ( kind, mutbl, oprnd) => {
485494 self . check_expr_addr_of ( kind, mutbl, oprnd, expected, expr)
486495 }
487496 ExprKind :: Path ( QPath :: LangItem ( lang_item, _) ) => {
488497 self . check_lang_item_path ( lang_item, expr)
489498 }
490- ExprKind :: Path ( ref qpath) => self . check_expr_path ( qpath, expr, None , None ) ,
499+ ExprKind :: Path ( ref qpath) => self . check_expr_path ( qpath, expr, None ) ,
491500 ExprKind :: InlineAsm ( asm) => {
492501 // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
493502 self . deferred_asm_checks . borrow_mut ( ) . push ( ( asm, expr. hir_id ) ) ;
494503 self . check_expr_asm ( asm)
495504 }
496- ExprKind :: OffsetOf ( container, fields) => self . check_offset_of ( container, fields, expr) ,
505+ ExprKind :: OffsetOf ( container, fields) => {
506+ self . check_expr_offset_of ( container, fields, expr)
507+ }
497508 ExprKind :: Break ( destination, ref expr_opt) => {
498509 self . check_expr_break ( destination, expr_opt. as_deref ( ) , expr)
499510 }
@@ -512,13 +523,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
512523 self . check_expr_loop ( body, source, expected, expr)
513524 }
514525 ExprKind :: Match ( discrim, arms, match_src) => {
515- self . check_match ( expr, discrim, arms, expected, match_src)
526+ self . check_expr_match ( expr, discrim, arms, expected, match_src)
516527 }
517528 ExprKind :: Closure ( closure) => self . check_expr_closure ( closure, expr. span , expected) ,
518- ExprKind :: Block ( body, _) => self . check_block_with_expected ( body, expected) ,
519- ExprKind :: Call ( callee, args) => self . check_call ( expr, callee, args, expected) ,
529+ ExprKind :: Block ( body, _) => self . check_expr_block ( body, expected) ,
530+ ExprKind :: Call ( callee, args) => self . check_expr_call ( expr, callee, args, expected) ,
520531 ExprKind :: MethodCall ( segment, receiver, args, _) => {
521- self . check_method_call ( expr, segment, receiver, args, expected)
532+ self . check_expr_method_call ( expr, segment, receiver, args, expected)
522533 }
523534 ExprKind :: Cast ( e, t) => self . check_expr_cast ( e, t, expr) ,
524535 ExprKind :: Type ( e, t) => {
@@ -528,7 +539,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
528539 ascribed_ty
529540 }
530541 ExprKind :: If ( cond, then_expr, opt_else_expr) => {
531- self . check_then_else ( cond, then_expr, opt_else_expr, expr. span , expected)
542+ self . check_expr_if ( cond, then_expr, opt_else_expr, expr. span , expected)
532543 }
533544 ExprKind :: DropTemps ( e) => self . check_expr_with_expectation ( e, expected) ,
534545 ExprKind :: Array ( args) => self . check_expr_array ( args, expected, expr) ,
@@ -540,7 +551,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
540551 ExprKind :: Struct ( qpath, fields, ref base_expr) => {
541552 self . check_expr_struct ( expr, expected, qpath, fields, base_expr)
542553 }
543- ExprKind :: Field ( base, field) => self . check_field ( expr, base, field, expected) ,
554+ ExprKind :: Field ( base, field) => self . check_expr_field ( expr, base, field, expected) ,
544555 ExprKind :: Index ( base, idx, brackets_span) => {
545556 self . check_expr_index ( base, idx, expr, brackets_span)
546557 }
@@ -549,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
549560 }
550561 }
551562
552- fn check_expr_unary (
563+ fn check_expr_unop (
553564 & self ,
554565 unop : hir:: UnOp ,
555566 oprnd : & ' tcx hir:: Expr < ' tcx > ,
@@ -699,8 +710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
699710 & self ,
700711 qpath : & ' tcx hir:: QPath < ' tcx > ,
701712 expr : & ' tcx hir:: Expr < ' tcx > ,
702- args : Option < & ' tcx [ hir:: Expr < ' tcx > ] > ,
703- call : Option < & ' tcx hir:: Expr < ' tcx > > ,
713+ call_expr_and_args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
704714 ) -> Ty < ' tcx > {
705715 let tcx = self . tcx ;
706716 let ( res, opt_ty, segs) =
@@ -730,7 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
730740 segs,
731741 opt_ty,
732742 res,
733- call . map_or ( expr. span , |e | e. span ) ,
743+ call_expr_and_args . map_or ( expr. span , |( e , _ ) | e. span ) ,
734744 expr. span ,
735745 expr. hir_id ,
736746 )
@@ -769,7 +779,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
769779 // We just want to check sizedness, so instead of introducing
770780 // placeholder lifetimes with probing, we just replace higher lifetimes
771781 // with fresh vars.
772- let span = args. and_then ( |args| args. get ( i) ) . map_or ( expr. span , |arg| arg. span ) ;
782+ let span = call_expr_and_args
783+ . and_then ( |( _, args) | args. get ( i) )
784+ . map_or ( expr. span , |arg| arg. span ) ;
773785 let input = self . instantiate_binder_with_fresh_vars (
774786 span,
775787 infer:: BoundRegionConversionTime :: FnCall ,
@@ -795,7 +807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
795807 ) ;
796808 self . require_type_is_sized_deferred (
797809 output,
798- call . map_or ( expr. span , |e | e. span ) ,
810+ call_expr_and_args . map_or ( expr. span , |( e , _ ) | e. span ) ,
799811 ObligationCauseCode :: SizedCallReturnType ,
800812 ) ;
801813 }
@@ -972,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
972984 if self . ret_coercion_span . get ( ) . is_none ( ) {
973985 self . ret_coercion_span . set ( Some ( e. span ) ) ;
974986 }
975- self . check_return_expr ( e, true ) ;
987+ self . check_return_or_body_tail ( e, true ) ;
976988 } else {
977989 let mut coercion = self . ret_coercion . as_ref ( ) . unwrap ( ) . borrow_mut ( ) ;
978990 if self . ret_coercion_span . get ( ) . is_none ( ) {
@@ -1035,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10351047 ///
10361048 /// `explicit_return` is `true` if we're checking an explicit `return expr`,
10371049 /// and `false` if we're checking a trailing expression.
1038- pub ( super ) fn check_return_expr (
1050+ pub ( super ) fn check_return_or_body_tail (
10391051 & self ,
10401052 return_expr : & ' tcx hir:: Expr < ' tcx > ,
10411053 explicit_return : bool ,
@@ -1259,7 +1271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12591271
12601272 // A generic function for checking the 'then' and 'else' clauses in an 'if'
12611273 // or 'if-else' expression.
1262- fn check_then_else (
1274+ fn check_expr_if (
12631275 & self ,
12641276 cond_expr : & ' tcx hir:: Expr < ' tcx > ,
12651277 then_expr : & ' tcx hir:: Expr < ' tcx > ,
@@ -1542,7 +1554,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15421554 }
15431555
15441556 /// Checks a method call.
1545- fn check_method_call (
1557+ fn check_expr_method_call (
15461558 & self ,
15471559 expr : & ' tcx hir:: Expr < ' tcx > ,
15481560 segment : & ' tcx hir:: PathSegment < ' tcx > ,
@@ -2594,7 +2606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
25942606 }
25952607
25962608 // Check field access expressions
2597- fn check_field (
2609+ fn check_expr_field (
25982610 & self ,
25992611 expr : & ' tcx hir:: Expr < ' tcx > ,
26002612 base : & ' tcx hir:: Expr < ' tcx > ,
@@ -3535,8 +3547,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35353547 let previous_diverges = self . diverges . get ( ) ;
35363548
35373549 // The label blocks should have unit return value or diverge.
3538- let ty =
3539- self . check_block_with_expected ( block, ExpectHasType ( self . tcx . types . unit ) ) ;
3550+ let ty = self . check_expr_block ( block, ExpectHasType ( self . tcx . types . unit ) ) ;
35403551 if !ty. is_never ( ) {
35413552 self . demand_suptype ( block. span , self . tcx . types . unit , ty) ;
35423553 diverge = false ;
@@ -3551,7 +3562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35513562 if diverge { self . tcx . types . never } else { self . tcx . types . unit }
35523563 }
35533564
3554- fn check_offset_of (
3565+ fn check_expr_offset_of (
35553566 & self ,
35563567 container : & ' tcx hir:: Ty < ' tcx > ,
35573568 fields : & [ Ident ] ,
0 commit comments