13
13
//! to certain types. To record this, we use the union-find implementation from
14
14
//! the `ena` crate, which is extracted from rustc.
15
15
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
+
16
25
use std:: { convert:: identity, ops:: Index } ;
17
26
18
27
use chalk_ir:: {
@@ -60,15 +69,8 @@ pub use coerce::could_coerce;
60
69
#[ allow( unreachable_pub) ]
61
70
pub use unify:: could_unify;
62
71
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 } ;
72
74
73
75
/// The entry point of type inference.
74
76
pub ( crate ) fn infer_query ( db : & dyn HirDatabase , def : DefWithBodyId ) -> Arc < InferenceResult > {
@@ -508,6 +510,8 @@ pub(crate) struct InferenceContext<'a> {
508
510
diverges : Diverges ,
509
511
breakables : Vec < BreakableContext > ,
510
512
513
+ deferred_cast_checks : Vec < CastCheck > ,
514
+
511
515
// fields related to closure capture
512
516
current_captures : Vec < CapturedItemWithoutTy > ,
513
517
current_closure : Option < ClosureId > ,
@@ -582,7 +586,8 @@ impl<'a> InferenceContext<'a> {
582
586
resolver,
583
587
diverges : Diverges :: Maybe ,
584
588
breakables : Vec :: new ( ) ,
585
- current_captures : vec ! [ ] ,
589
+ deferred_cast_checks : Vec :: new ( ) ,
590
+ current_captures : Vec :: new ( ) ,
586
591
current_closure : None ,
587
592
deferred_closures : FxHashMap :: default ( ) ,
588
593
closure_dependencies : FxHashMap :: default ( ) ,
@@ -594,7 +599,7 @@ impl<'a> InferenceContext<'a> {
594
599
// used this function for another workaround, mention it here. If you really need this function and believe that
595
600
// there is no problem in it being `pub(crate)`, remove this comment.
596
601
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 ;
598
603
// Destructure every single field so whenever new fields are added to `InferenceResult` we
599
604
// don't forget to handle them here.
600
605
let InferenceResult {
@@ -622,6 +627,13 @@ impl<'a> InferenceContext<'a> {
622
627
623
628
table. fallback_if_possible ( ) ;
624
629
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
+
625
637
// FIXME resolve obligations as well (use Guidance if necessary)
626
638
table. resolve_obligations_as_possible ( ) ;
627
639
0 commit comments