7
7
8
8
use std:: iter;
9
9
10
- use chalk_ir:: { cast:: Cast , BoundVar , Goal , Mutability , TyKind , TyVariableKind } ;
10
+ use chalk_ir:: { cast:: Cast , BoundVar , Mutability , TyKind , TyVariableKind } ;
11
11
use hir_def:: {
12
12
hir:: ExprId ,
13
13
lang_item:: { LangItem , LangItemTarget } ,
@@ -24,8 +24,8 @@ use crate::{
24
24
} ,
25
25
static_lifetime,
26
26
utils:: ClosureSubst ,
27
- Canonical , DomainGoal , FnPointer , FnSig , Guidance , InEnvironment , Interner , Solution ,
28
- Substitution , TraitEnvironment , Ty , TyBuilder , TyExt ,
27
+ Canonical , FnPointer , FnSig , Goal , Guidance , InEnvironment , Interner , Solution , Substitution ,
28
+ TraitEnvironment , Ty , TyBuilder , TyExt ,
29
29
} ;
30
30
31
31
use super :: unify:: InferenceTable ;
@@ -42,11 +42,7 @@ fn simple(kind: Adjust) -> impl FnOnce(Ty) -> Vec<Adjustment> {
42
42
}
43
43
44
44
/// This always returns `Ok(...)`.
45
- fn success (
46
- adj : Vec < Adjustment > ,
47
- target : Ty ,
48
- goals : Vec < InEnvironment < Goal < Interner > > > ,
49
- ) -> CoerceResult {
45
+ fn success ( adj : Vec < Adjustment > , target : Ty , goals : Vec < InEnvironment < Goal > > ) -> CoerceResult {
50
46
Ok ( InferOk { goals, value : ( adj, target) } )
51
47
}
52
48
@@ -229,8 +225,6 @@ impl InferenceContext<'_> {
229
225
from_ty : & Ty ,
230
226
to_ty : & Ty ,
231
227
) -> Result < Ty , TypeError > {
232
- let from_ty = self . resolve_ty_shallow ( from_ty) ;
233
- let to_ty = self . resolve_ty_shallow ( to_ty) ;
234
228
let ( adjustments, ty) = self . table . coerce ( & from_ty, & to_ty) ?;
235
229
if let Some ( expr) = expr {
236
230
self . write_expr_adj ( expr, adjustments) ;
@@ -411,10 +405,10 @@ impl InferenceTable<'_> {
411
405
// mutability [1], since it may be that we are coercing
412
406
// from `&mut T` to `&U`.
413
407
let lt = static_lifetime ( ) ; // FIXME: handle lifetimes correctly, see rustc
414
- let derefd_from_ty = TyKind :: Ref ( to_mt, lt, referent_ty) . intern ( Interner ) ;
415
- match autoderef. table . try_unify ( & derefd_from_ty , to_ty) {
408
+ let derefed_from_ty = TyKind :: Ref ( to_mt, lt, referent_ty) . intern ( Interner ) ;
409
+ match autoderef. table . try_unify ( & derefed_from_ty , to_ty) {
416
410
Ok ( result) => {
417
- found = Some ( result. map ( |( ) | derefd_from_ty ) ) ;
411
+ found = Some ( result. map ( |( ) | derefed_from_ty ) ) ;
418
412
break ;
419
413
}
420
414
Err ( err) => {
@@ -626,6 +620,7 @@ impl InferenceTable<'_> {
626
620
}
627
621
_ => None ,
628
622
} ;
623
+ let must_be_unsized = must_be_coerce_unsized ( from_ty, to_ty) ;
629
624
let coerce_from =
630
625
reborrow. as_ref ( ) . map_or_else ( || from_ty. clone ( ) , |( _, adj) | adj. target . clone ( ) ) ;
631
626
@@ -644,7 +639,7 @@ impl InferenceTable<'_> {
644
639
b. push ( coerce_from) . push ( to_ty. clone ( ) ) . build ( )
645
640
} ;
646
641
647
- let goal: InEnvironment < DomainGoal > =
642
+ let goal: InEnvironment < Goal > =
648
643
InEnvironment :: new ( & self . trait_env . env , coerce_unsized_tref. cast ( Interner ) ) ;
649
644
650
645
let canonicalized = self . canonicalize ( goal) ;
@@ -673,7 +668,9 @@ impl InferenceTable<'_> {
673
668
// FIXME need to record an obligation here
674
669
canonicalized. apply_solution ( self , subst)
675
670
}
676
- // FIXME actually we maybe should also accept unknown guidance here
671
+ Solution :: Ambig ( Guidance :: Unknown ) if must_be_unsized => {
672
+ // FIXME need to record an obligation here too
673
+ }
677
674
_ => return Err ( TypeError ) ,
678
675
} ;
679
676
let unsize =
@@ -715,6 +712,19 @@ fn coerce_mutabilities(from: Mutability, to: Mutability) -> Result<(), TypeError
715
712
}
716
713
}
717
714
715
+ // a temporary workaroud for coerce_unsized
716
+ fn must_be_coerce_unsized ( from_ty : & Ty , to_ty : & Ty ) -> bool {
717
+ // TODO: many other cases
718
+ match ( from_ty. kind ( Interner ) , to_ty. kind ( Interner ) ) {
719
+ ( TyKind :: Ref ( _, _, from_ty) , TyKind :: Ref ( _, _, to_ty) ) => {
720
+ must_be_coerce_unsized ( from_ty, to_ty)
721
+ }
722
+ ( _, TyKind :: Dyn ( _) ) => true ,
723
+ ( TyKind :: Array ( _, _) , TyKind :: Slice ( _) ) => true ,
724
+ ( _, _) => false ,
725
+ }
726
+ }
727
+
718
728
pub ( super ) fn auto_deref_adjust_steps ( autoderef : & Autoderef < ' _ , ' _ > ) -> Vec < Adjustment > {
719
729
let steps = autoderef. steps ( ) ;
720
730
let targets =
0 commit comments