@@ -87,6 +87,28 @@ impl PathResolution {
8787 }
8888}
8989
90+ #[ derive( Debug ) ]
91+ pub struct TypeInfo {
92+ /// The original type of the expression or pattern.
93+ pub ty : Type ,
94+ /// The coerced type, if a coercion happened.
95+ pub coerced : Option < Type > ,
96+ }
97+
98+ impl TypeInfo {
99+ pub fn ty ( self ) -> Type {
100+ self . ty
101+ }
102+
103+ pub fn coerced ( self ) -> Option < Type > {
104+ self . coerced
105+ }
106+
107+ pub fn coerced_or_original ( self ) -> Type {
108+ self . coerced . unwrap_or ( self . ty )
109+ }
110+ }
111+
90112/// Primary API to get semantic information, like types, from syntax trees.
91113pub struct Semantics < ' db , DB > {
92114 pub db : & ' db DB ,
@@ -212,23 +234,14 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
212234 self . imp . resolve_type ( ty)
213235 }
214236
215- pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
237+ pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < TypeInfo > {
216238 self . imp . type_of_expr ( expr)
217239 }
218240
219- /// Returns true in case a coercion happened.
220- pub fn type_of_expr_with_coercion ( & self , expr : & ast:: Expr ) -> Option < ( Type , bool ) > {
221- self . imp . type_of_expr_with_coercion ( expr)
222- }
223-
224- pub fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < Type > {
241+ pub fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < TypeInfo > {
225242 self . imp . type_of_pat ( pat)
226243 }
227244
228- pub fn type_of_pat_with_coercion ( & self , expr : & ast:: Pat ) -> Option < ( Type , bool ) > {
229- self . imp . type_of_pat_with_coercion ( expr)
230- }
231-
232245 pub fn type_of_self ( & self , param : & ast:: SelfParam ) -> Option < Type > {
233246 self . imp . type_of_self ( param)
234247 }
@@ -565,20 +578,16 @@ impl<'db> SemanticsImpl<'db> {
565578 Type :: new_with_resolver ( self . db , & scope. resolver , ty)
566579 }
567580
568- fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
569- self . analyze ( expr. syntax ( ) ) . type_of_expr ( self . db , expr)
570- }
571-
572- fn type_of_expr_with_coercion ( & self , expr : & ast:: Expr ) -> Option < ( Type , bool ) > {
573- self . analyze ( expr. syntax ( ) ) . type_of_expr_with_coercion ( self . db , expr)
574- }
575-
576- fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < Type > {
577- self . analyze ( pat. syntax ( ) ) . type_of_pat ( self . db , pat)
581+ fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < TypeInfo > {
582+ self . analyze ( expr. syntax ( ) )
583+ . type_of_expr ( self . db , expr)
584+ . map ( |( ty, coerced) | TypeInfo { ty, coerced } )
578585 }
579586
580- fn type_of_pat_with_coercion ( & self , pat : & ast:: Pat ) -> Option < ( Type , bool ) > {
581- self . analyze ( pat. syntax ( ) ) . type_of_pat_with_coercion ( self . db , pat)
587+ fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < TypeInfo > {
588+ self . analyze ( pat. syntax ( ) )
589+ . type_of_pat ( self . db , pat)
590+ . map ( |( ty, coerced) | TypeInfo { ty, coerced } )
582591 }
583592
584593 fn type_of_self ( & self , param : & ast:: SelfParam ) -> Option < Type > {
@@ -757,7 +766,7 @@ impl<'db> SemanticsImpl<'db> {
757766 ast:: Expr :: FieldExpr ( field_expr) => field_expr,
758767 _ => return None ,
759768 } ;
760- let ty = self . type_of_expr ( & field_expr. expr ( ) ?) ?;
769+ let ty = self . type_of_expr ( & field_expr. expr ( ) ?) ?. ty ;
761770 if !ty. is_packed ( self . db ) {
762771 return None ;
763772 }
@@ -784,7 +793,7 @@ impl<'db> SemanticsImpl<'db> {
784793 self . type_of_expr ( & expr)
785794 } )
786795 // Binding a reference to a packed type is possibly unsafe.
787- . map ( |ty| ty. is_packed ( self . db ) )
796+ . map ( |ty| ty. ty . is_packed ( self . db ) )
788797 . unwrap_or ( false )
789798
790799 // FIXME This needs layout computation to be correct. It will highlight
@@ -830,7 +839,7 @@ impl<'db> SemanticsImpl<'db> {
830839 }
831840 } )
832841 // Binding a reference to a packed type is possibly unsafe.
833- . map ( |ty| ty. is_packed ( self . db ) )
842+ . map ( |ty| ty. ty . is_packed ( self . db ) )
834843 . unwrap_or ( false )
835844 }
836845}
0 commit comments