66use std:: sync:: Arc ;
77
88use chalk_ir:: cast:: Cast ;
9- use hir_def:: lang_item:: LangItem ;
9+ use hir_def:: {
10+ lang_item:: { LangItem , LangItemTarget } ,
11+ AdtId ,
12+ } ;
1013use hir_expand:: name:: name;
1114use limit:: Limit ;
1215
@@ -76,7 +79,7 @@ pub(crate) fn autoderef_step(
7679 table : & mut InferenceTable < ' _ > ,
7780 ty : Ty ,
7881) -> Option < ( AutoderefKind , Ty ) > {
79- if let Some ( derefed) = builtin_deref ( & ty) {
82+ if let Some ( derefed) = builtin_deref ( table , & ty, false ) {
8083 Some ( ( AutoderefKind :: Builtin , table. resolve_ty_shallow ( derefed) ) )
8184 } else {
8285 Some ( ( AutoderefKind :: Overloaded , deref_by_trait ( table, ty) ?) )
@@ -99,26 +102,41 @@ pub fn autoderef(
99102 v. into_iter ( )
100103}
101104
102- pub ( crate ) fn deref ( table : & mut InferenceTable < ' _ > , ty : Ty ) -> Option < Ty > {
103- let _p = profile:: span ( "deref" ) ;
104- autoderef_step ( table, ty) . map ( |( _, ty) | ty)
105- }
106-
107- fn builtin_deref ( ty : & Ty ) -> Option < & Ty > {
105+ pub ( crate ) fn builtin_deref < ' ty > (
106+ table : & mut InferenceTable < ' _ > ,
107+ ty : & ' ty Ty ,
108+ explicit : bool ,
109+ ) -> Option < & ' ty Ty > {
108110 match ty. kind ( Interner ) {
109- TyKind :: Ref ( .., ty) | TyKind :: Raw ( .., ty) => Some ( ty) ,
111+ TyKind :: Ref ( .., ty) => Some ( ty) ,
112+ // FIXME: Maybe accept this but diagnose if its not explicit?
113+ TyKind :: Raw ( .., ty) if explicit => Some ( ty) ,
114+ & TyKind :: Adt ( chalk_ir:: AdtId ( AdtId :: StructId ( strukt) ) , ref substs) => {
115+ if Some ( strukt)
116+ == table
117+ . db
118+ . lang_item ( table. trait_env . krate , LangItem :: OwnedBox )
119+ . and_then ( LangItemTarget :: as_struct)
120+ {
121+ substs. at ( Interner , 0 ) . ty ( Interner )
122+ } else {
123+ None
124+ }
125+ }
110126 _ => None ,
111127 }
112128}
113129
114- fn deref_by_trait ( table : & mut InferenceTable < ' _ > , ty : Ty ) -> Option < Ty > {
130+ pub ( crate ) fn deref_by_trait (
131+ table @ & mut InferenceTable { db, .. } : & mut InferenceTable < ' _ > ,
132+ ty : Ty ,
133+ ) -> Option < Ty > {
115134 let _p = profile:: span ( "deref_by_trait" ) ;
116135 if table. resolve_ty_shallow ( & ty) . inference_var ( Interner ) . is_some ( ) {
117136 // don't try to deref unknown variables
118137 return None ;
119138 }
120139
121- let db = table. db ;
122140 let deref_trait =
123141 db. lang_item ( table. trait_env . krate , LangItem :: Deref ) . and_then ( |l| l. as_trait ( ) ) ?;
124142 let target = db. trait_data ( deref_trait) . associated_type_by_name ( & name ! [ Target ] ) ?;
0 commit comments