@@ -87,6 +87,29 @@ impl PathResolution {
8787 }
8888}
8989
90+ #[ derive( Debug ) ]
91+ pub struct TypeInfo {
92+ /// The original type of the expression or pattern.
93+ pub original : Type ,
94+ /// The adjusted type, if an adjustment happened.
95+ pub adjusted : Option < Type > ,
96+ }
97+
98+ impl TypeInfo {
99+ pub fn original ( self ) -> Type {
100+ self . original
101+ }
102+
103+ pub fn has_adjustment ( & self ) -> bool {
104+ self . adjusted . is_some ( )
105+ }
106+
107+ /// The adjusted type, or the original in case no adjustments occurred.
108+ pub fn adjusted ( self ) -> Type {
109+ self . adjusted . unwrap_or ( self . original )
110+ }
111+ }
112+
90113/// Primary API to get semantic information, like types, from syntax trees.
91114pub struct Semantics < ' db , DB > {
92115 pub db : & ' db DB ,
@@ -212,23 +235,14 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
212235 self . imp . resolve_type ( ty)
213236 }
214237
215- pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < Type > {
238+ pub fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < TypeInfo > {
216239 self . imp . type_of_expr ( expr)
217240 }
218241
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 > {
242+ pub fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < TypeInfo > {
225243 self . imp . type_of_pat ( pat)
226244 }
227245
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-
232246 pub fn type_of_self ( & self , param : & ast:: SelfParam ) -> Option < Type > {
233247 self . imp . type_of_self ( param)
234248 }
@@ -565,20 +579,16 @@ impl<'db> SemanticsImpl<'db> {
565579 Type :: new_with_resolver ( self . db , & scope. resolver , ty)
566580 }
567581
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)
582+ fn type_of_expr ( & self , expr : & ast:: Expr ) -> Option < TypeInfo > {
583+ self . analyze ( expr. syntax ( ) )
584+ . type_of_expr ( self . db , expr)
585+ . map ( |( ty, coerced) | TypeInfo { original : ty, adjusted : coerced } )
578586 }
579587
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)
588+ fn type_of_pat ( & self , pat : & ast:: Pat ) -> Option < TypeInfo > {
589+ self . analyze ( pat. syntax ( ) )
590+ . type_of_pat ( self . db , pat)
591+ . map ( |( ty, coerced) | TypeInfo { original : ty, adjusted : coerced } )
582592 }
583593
584594 fn type_of_self ( & self , param : & ast:: SelfParam ) -> Option < Type > {
@@ -757,7 +767,7 @@ impl<'db> SemanticsImpl<'db> {
757767 ast:: Expr :: FieldExpr ( field_expr) => field_expr,
758768 _ => return None ,
759769 } ;
760- let ty = self . type_of_expr ( & field_expr. expr ( ) ?) ?;
770+ let ty = self . type_of_expr ( & field_expr. expr ( ) ?) ?. original ;
761771 if !ty. is_packed ( self . db ) {
762772 return None ;
763773 }
@@ -784,7 +794,7 @@ impl<'db> SemanticsImpl<'db> {
784794 self . type_of_expr ( & expr)
785795 } )
786796 // Binding a reference to a packed type is possibly unsafe.
787- . map ( |ty| ty. is_packed ( self . db ) )
797+ . map ( |ty| ty. original . is_packed ( self . db ) )
788798 . unwrap_or ( false )
789799
790800 // FIXME This needs layout computation to be correct. It will highlight
@@ -830,7 +840,7 @@ impl<'db> SemanticsImpl<'db> {
830840 }
831841 } )
832842 // Binding a reference to a packed type is possibly unsafe.
833- . map ( |ty| ty. is_packed ( self . db ) )
843+ . map ( |ty| ty. original . is_packed ( self . db ) )
834844 . unwrap_or ( false )
835845 }
836846}
0 commit comments