@@ -87,16 +87,15 @@ impl<'a> InferenceContext<'a> {
8787 let expected = & expected. adjust_for_branches ( & mut self . table ) ;
8888 self . infer_expr (
8989 condition,
90- & Expectation :: has_type ( TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) ) ,
90+ & Expectation :: HasType ( self . result . standard_types . bool_ . clone ( ) ) ,
9191 ) ;
9292
9393 let condition_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
9494 let mut both_arms_diverge = Diverges :: Always ;
9595
96- let result_ty = self . table . new_type_var ( ) ;
9796 let then_ty = self . infer_expr_inner ( then_branch, expected) ;
9897 both_arms_diverge &= mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
99- let mut coerce = CoerceMany :: new ( result_ty ) ;
98+ let mut coerce = CoerceMany :: new ( expected . coercion_target_type ( & mut self . table ) ) ;
10099 coerce. coerce ( self , Some ( then_branch) , & then_ty) ;
101100 let else_ty = match else_branch {
102101 Some ( else_branch) => self . infer_expr_inner ( else_branch, expected) ,
@@ -113,7 +112,7 @@ impl<'a> InferenceContext<'a> {
113112 & Expr :: Let { pat, expr } => {
114113 let input_ty = self . infer_expr ( expr, & Expectation :: none ( ) ) ;
115114 self . infer_pat ( pat, & input_ty, BindingMode :: default ( ) ) ;
116- TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner )
115+ self . result . standard_types . bool_ . clone ( )
117116 }
118117 Expr :: Block { statements, tail, label, id : _ } => {
119118 let old_resolver = mem:: replace (
@@ -188,27 +187,29 @@ impl<'a> InferenceContext<'a> {
188187 . intern ( Interner )
189188 }
190189 & Expr :: Loop { body, label } => {
190+ // FIXME: should be:
191+ // let ty = expected.coercion_target_type(&mut self.table);
191192 let ty = self . table . new_type_var ( ) ;
192193 let ( breaks, ( ) ) =
193194 self . with_breakable_ctx ( BreakableKind :: Loop , ty, label, |this| {
194- this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
195+ this. infer_expr ( body, & Expectation :: HasType ( TyBuilder :: unit ( ) ) ) ;
195196 } ) ;
196197
197198 match breaks {
198199 Some ( breaks) => {
199200 self . diverges = Diverges :: Maybe ;
200201 breaks
201202 }
202- None => TyKind :: Never . intern ( Interner ) ,
203+ None => self . result . standard_types . never . clone ( ) ,
203204 }
204205 }
205206 & Expr :: While { condition, body, label } => {
206207 self . with_breakable_ctx ( BreakableKind :: Loop , self . err_ty ( ) , label, |this| {
207208 this. infer_expr (
208209 condition,
209- & Expectation :: has_type ( TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) ) ,
210+ & Expectation :: HasType ( this . result . standard_types . bool_ . clone ( ) ) ,
210211 ) ;
211- this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
212+ this. infer_expr ( body, & Expectation :: HasType ( TyBuilder :: unit ( ) ) ) ;
212213 } ) ;
213214
214215 // the body may not run, so it diverging doesn't mean we diverge
@@ -224,7 +225,7 @@ impl<'a> InferenceContext<'a> {
224225
225226 self . infer_pat ( pat, & pat_ty, BindingMode :: default ( ) ) ;
226227 self . with_breakable_ctx ( BreakableKind :: Loop , self . err_ty ( ) , label, |this| {
227- this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
228+ this. infer_expr ( body, & Expectation :: HasType ( TyBuilder :: unit ( ) ) ) ;
228229 } ) ;
229230
230231 // the body may not run, so it diverging doesn't mean we diverge
@@ -234,7 +235,7 @@ impl<'a> InferenceContext<'a> {
234235 Expr :: Closure { body, args, ret_type, arg_types, closure_kind } => {
235236 assert_eq ! ( args. len( ) , arg_types. len( ) ) ;
236237
237- let mut sig_tys = Vec :: new ( ) ;
238+ let mut sig_tys = Vec :: with_capacity ( arg_types . len ( ) + 1 ) ;
238239
239240 // collect explicitly written argument types
240241 for arg_type in arg_types. iter ( ) {
@@ -255,7 +256,8 @@ impl<'a> InferenceContext<'a> {
255256 num_binders : 0 ,
256257 sig : FnSig { abi : ( ) , safety : chalk_ir:: Safety :: Safe , variadic : false } ,
257258 substitution : FnSubst (
258- Substitution :: from_iter ( Interner , sig_tys. clone ( ) ) . shifted_in ( Interner ) ,
259+ Substitution :: from_iter ( Interner , sig_tys. iter ( ) . cloned ( ) )
260+ . shifted_in ( Interner ) ,
259261 ) ,
260262 } )
261263 . intern ( Interner ) ;
@@ -317,16 +319,16 @@ impl<'a> InferenceContext<'a> {
317319 Expr :: Call { callee, args, .. } => {
318320 let callee_ty = self . infer_expr ( * callee, & Expectation :: none ( ) ) ;
319321 let mut derefs = Autoderef :: new ( & mut self . table , callee_ty. clone ( ) ) ;
320- let mut res = None ;
321- let mut derefed_callee = callee_ty. clone ( ) ;
322- // manual loop to be able to access `derefs.table`
323- while let Some ( ( callee_deref_ty, _) ) = derefs. next ( ) {
324- res = derefs. table . callable_sig ( & callee_deref_ty, args. len ( ) ) ;
325- if res. is_some ( ) {
326- derefed_callee = callee_deref_ty;
327- break ;
322+ let ( res, derefed_callee) = ' b: {
323+ // manual loop to be able to access `derefs.table`
324+ while let Some ( ( callee_deref_ty, _) ) = derefs. next ( ) {
325+ let res = derefs. table . callable_sig ( & callee_deref_ty, args. len ( ) ) ;
326+ if res. is_some ( ) {
327+ break ' b ( res, callee_deref_ty) ;
328+ }
328329 }
329- }
330+ ( None , callee_ty. clone ( ) )
331+ } ;
330332 // if the function is unresolved, we use is_varargs=true to
331333 // suppress the arg count diagnostic here
332334 let is_varargs =
@@ -382,12 +384,9 @@ impl<'a> InferenceContext<'a> {
382384 let expected = expected. adjust_for_branches ( & mut self . table ) ;
383385
384386 let result_ty = if arms. is_empty ( ) {
385- TyKind :: Never . intern ( Interner )
387+ self . result . standard_types . never . clone ( )
386388 } else {
387- match & expected {
388- Expectation :: HasType ( ty) => ty. clone ( ) ,
389- _ => self . table . new_type_var ( ) ,
390- }
389+ expected. coercion_target_type ( & mut self . table )
391390 } ;
392391 let mut coerce = CoerceMany :: new ( result_ty) ;
393392
@@ -400,7 +399,7 @@ impl<'a> InferenceContext<'a> {
400399 if let Some ( guard_expr) = arm. guard {
401400 self . infer_expr (
402401 guard_expr,
403- & Expectation :: has_type ( TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) ) ,
402+ & Expectation :: HasType ( self . result . standard_types . bool_ . clone ( ) ) ,
404403 ) ;
405404 }
406405
@@ -425,7 +424,7 @@ impl<'a> InferenceContext<'a> {
425424 is_break : false ,
426425 } ) ;
427426 } ;
428- TyKind :: Never . intern ( Interner )
427+ self . result . standard_types . never . clone ( )
429428 }
430429 Expr :: Break { expr, label } => {
431430 let val_ty = if let Some ( expr) = * expr {
@@ -439,7 +438,7 @@ impl<'a> InferenceContext<'a> {
439438 // avoiding the borrowck
440439 let mut coerce = mem:: replace (
441440 & mut ctxt. coerce ,
442- CoerceMany :: new ( self . result . standard_types . unknown . clone ( ) ) ,
441+ CoerceMany :: new ( expected . coercion_target_type ( & mut self . table ) ) ,
443442 ) ;
444443
445444 // FIXME: create a synthetic `()` during lowering so we have something to refer to here?
@@ -457,7 +456,7 @@ impl<'a> InferenceContext<'a> {
457456 } ) ;
458457 }
459458 }
460- TyKind :: Never . intern ( Interner )
459+ self . result . standard_types . never . clone ( )
461460 }
462461 Expr :: Return { expr } => {
463462 if let Some ( expr) = expr {
@@ -466,7 +465,7 @@ impl<'a> InferenceContext<'a> {
466465 let unit = TyBuilder :: unit ( ) ;
467466 let _ = self . coerce ( Some ( tgt_expr) , & unit, & self . return_ty . clone ( ) ) ;
468467 }
469- TyKind :: Never . intern ( Interner )
468+ self . result . standard_types . never . clone ( )
470469 }
471470 Expr :: Yield { expr } => {
472471 if let Some ( ( resume_ty, yield_ty) ) = self . resume_yield_tys . clone ( ) {
@@ -479,14 +478,14 @@ impl<'a> InferenceContext<'a> {
479478 resume_ty
480479 } else {
481480 // FIXME: report error (yield expr in non-generator)
482- TyKind :: Error . intern ( Interner )
481+ self . result . standard_types . unknown . clone ( )
483482 }
484483 }
485484 Expr :: Yeet { expr } => {
486485 if let & Some ( expr) = expr {
487486 self . infer_expr_inner ( expr, & Expectation :: None ) ;
488487 }
489- TyKind :: Never . intern ( Interner )
488+ self . result . standard_types . never . clone ( )
490489 }
491490 Expr :: RecordLit { path, fields, spread, .. } => {
492491 let ( ty, def_id) = self . resolve_variant ( path. as_deref ( ) , false ) ;
@@ -611,8 +610,8 @@ impl<'a> InferenceContext<'a> {
611610 }
612611 Expr :: Cast { expr, type_ref } => {
613612 let cast_ty = self . make_ty ( type_ref) ;
614- let _inner_ty =
615- self . infer_expr_inner ( * expr, & Expectation :: Castable ( cast_ty . clone ( ) ) ) ;
613+ // FIXME: propagate the "castable to" expectation
614+ let _inner_ty = self . infer_expr_inner ( * expr, & Expectation :: None ) ;
616615 // FIXME check the cast...
617616 cast_ty
618617 }
@@ -829,7 +828,7 @@ impl<'a> InferenceContext<'a> {
829828 self . infer_expr_coerce ( initializer, & Expectation :: has_type ( elem_ty) ) ;
830829 self . infer_expr (
831830 repeat,
832- & Expectation :: has_type (
831+ & Expectation :: HasType (
833832 TyKind :: Scalar ( Scalar :: Uint ( UintTy :: Usize ) ) . intern ( Interner ) ,
834833 ) ,
835834 ) ;
@@ -852,7 +851,7 @@ impl<'a> InferenceContext<'a> {
852851 TyKind :: Array ( coerce. complete ( ) , len) . intern ( Interner )
853852 }
854853 Expr :: Literal ( lit) => match lit {
855- Literal :: Bool ( ..) => TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) ,
854+ Literal :: Bool ( ..) => self . result . standard_types . bool_ . clone ( ) ,
856855 Literal :: String ( ..) => {
857856 TyKind :: Ref ( Mutability :: Not , static_lifetime ( ) , TyKind :: Str . intern ( Interner ) )
858857 . intern ( Interner )
@@ -1148,7 +1147,7 @@ impl<'a> InferenceContext<'a> {
11481147 if let Some ( expr) = else_branch {
11491148 self . infer_expr_coerce (
11501149 * expr,
1151- & Expectation :: has_type ( Ty :: new ( Interner , TyKind :: Never ) ) ,
1150+ & Expectation :: HasType ( self . result . standard_types . never . clone ( ) ) ,
11521151 ) ;
11531152 }
11541153
0 commit comments