1313//! to certain types. To record this, we use the union-find implementation from
1414//! the `ena` crate, which is extracted from rustc.
1515
16+ mod cast;
17+ pub ( crate ) mod closure;
18+ mod coerce;
19+ mod expr;
20+ mod mutability;
21+ mod pat;
22+ mod path;
23+ pub ( crate ) mod unify;
24+
1625use std:: { convert:: identity, ops:: Index } ;
1726
1827use chalk_ir:: {
@@ -60,15 +69,8 @@ pub use coerce::could_coerce;
6069#[ allow( unreachable_pub) ]
6170pub use unify:: could_unify;
6271
63- pub ( crate ) use self :: closure:: { CaptureKind , CapturedItem , CapturedItemWithoutTy } ;
64-
65- pub ( crate ) mod unify;
66- mod path;
67- mod expr;
68- mod pat;
69- mod coerce;
70- pub ( crate ) mod closure;
71- mod mutability;
72+ use cast:: CastCheck ;
73+ pub ( crate ) use closure:: { CaptureKind , CapturedItem , CapturedItemWithoutTy } ;
7274
7375/// The entry point of type inference.
7476pub ( crate ) fn infer_query ( db : & dyn HirDatabase , def : DefWithBodyId ) -> Arc < InferenceResult > {
@@ -508,6 +510,8 @@ pub(crate) struct InferenceContext<'a> {
508510 diverges : Diverges ,
509511 breakables : Vec < BreakableContext > ,
510512
513+ deferred_cast_checks : Vec < CastCheck > ,
514+
511515 // fields related to closure capture
512516 current_captures : Vec < CapturedItemWithoutTy > ,
513517 current_closure : Option < ClosureId > ,
@@ -582,7 +586,8 @@ impl<'a> InferenceContext<'a> {
582586 resolver,
583587 diverges : Diverges :: Maybe ,
584588 breakables : Vec :: new ( ) ,
585- current_captures : vec ! [ ] ,
589+ deferred_cast_checks : Vec :: new ( ) ,
590+ current_captures : Vec :: new ( ) ,
586591 current_closure : None ,
587592 deferred_closures : FxHashMap :: default ( ) ,
588593 closure_dependencies : FxHashMap :: default ( ) ,
@@ -594,7 +599,7 @@ impl<'a> InferenceContext<'a> {
594599 // used this function for another workaround, mention it here. If you really need this function and believe that
595600 // there is no problem in it being `pub(crate)`, remove this comment.
596601 pub ( crate ) fn resolve_all ( self ) -> InferenceResult {
597- let InferenceContext { mut table, mut result, .. } = self ;
602+ let InferenceContext { mut table, mut result, deferred_cast_checks , .. } = self ;
598603 // Destructure every single field so whenever new fields are added to `InferenceResult` we
599604 // don't forget to handle them here.
600605 let InferenceResult {
@@ -622,6 +627,13 @@ impl<'a> InferenceContext<'a> {
622627
623628 table. fallback_if_possible ( ) ;
624629
630+ // Comment from rustc:
631+ // Even though coercion casts provide type hints, we check casts after fallback for
632+ // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
633+ for cast in deferred_cast_checks {
634+ cast. check ( & mut table) ;
635+ }
636+
625637 // FIXME resolve obligations as well (use Guidance if necessary)
626638 table. resolve_obligations_as_possible ( ) ;
627639
0 commit comments