@@ -58,7 +58,6 @@ use hir_ty::{
5858 consteval:: {
5959 eval_const, unknown_const_as_generic, ComputedExpr , ConstEvalCtx , ConstEvalError , ConstExt ,
6060 } ,
61- could_unify,
6261 diagnostics:: BodyValidationDiagnostic ,
6362 method_resolution:: { self , TyFingerprint } ,
6463 primitive:: UintTy ,
@@ -85,12 +84,11 @@ use crate::db::{DefDatabase, HirDatabase};
8584pub use crate :: {
8685 attrs:: { HasAttrs , Namespace } ,
8786 diagnostics:: {
88- AddReferenceHere , AnyDiagnostic , BreakOutsideOfLoop , InactiveCode , IncorrectCase ,
89- InvalidDeriveTarget , MacroError , MalformedDerive , MismatchedArgCount , MissingFields ,
90- MissingMatchArms , MissingOkOrSomeInTailExpr , MissingUnsafe , NoSuchField ,
91- RemoveThisSemicolon , ReplaceFilterMapNextWithFindMap , UnimplementedBuiltinMacro ,
92- UnresolvedExternCrate , UnresolvedImport , UnresolvedMacroCall , UnresolvedModule ,
93- UnresolvedProcMacro ,
87+ AnyDiagnostic , BreakOutsideOfLoop , InactiveCode , IncorrectCase , InvalidDeriveTarget ,
88+ MacroError , MalformedDerive , MismatchedArgCount , MissingFields , MissingMatchArms ,
89+ MissingUnsafe , NoSuchField , ReplaceFilterMapNextWithFindMap , TypeMismatch ,
90+ UnimplementedBuiltinMacro , UnresolvedExternCrate , UnresolvedImport , UnresolvedMacroCall ,
91+ UnresolvedModule , UnresolvedProcMacro ,
9492 } ,
9593 has_source:: HasSource ,
9694 semantics:: { PathResolution , Semantics , SemanticsScope , TypeInfo } ,
@@ -1005,6 +1003,24 @@ impl Adt {
10051003 Type :: from_def ( db, id. module ( db. upcast ( ) ) . krate ( ) , id)
10061004 }
10071005
1006+ /// Turns this ADT into a type with the given type parameters. This isn't
1007+ /// the greatest API, FIXME find a better one.
1008+ pub fn ty_with_args ( self , db : & dyn HirDatabase , args : & [ Type ] ) -> Type {
1009+ let id = AdtId :: from ( self ) ;
1010+ let mut it = args. iter ( ) . map ( |t| t. ty . clone ( ) ) ;
1011+ let ty = TyBuilder :: def_ty ( db, id. into ( ) )
1012+ . fill ( |x| {
1013+ let r = it. next ( ) . unwrap_or_else ( || TyKind :: Error . intern ( Interner ) ) ;
1014+ match x {
1015+ ParamKind :: Type => GenericArgData :: Ty ( r) . intern ( Interner ) ,
1016+ ParamKind :: Const ( ty) => unknown_const_as_generic ( ty. clone ( ) ) ,
1017+ }
1018+ } )
1019+ . build ( ) ;
1020+ let krate = id. module ( db. upcast ( ) ) . krate ( ) ;
1021+ Type :: new ( db, krate, id, ty)
1022+ }
1023+
10081024 pub fn module ( self , db : & dyn HirDatabase ) -> Module {
10091025 match self {
10101026 Adt :: Struct ( s) => s. module ( db) ,
@@ -1020,6 +1036,14 @@ impl Adt {
10201036 Adt :: Enum ( e) => e. name ( db) ,
10211037 }
10221038 }
1039+
1040+ pub fn as_enum ( & self ) -> Option < Enum > {
1041+ if let Self :: Enum ( v) = self {
1042+ Some ( * v)
1043+ } else {
1044+ None
1045+ }
1046+ }
10231047}
10241048
10251049impl HasVisibility for Adt {
@@ -1163,6 +1187,30 @@ impl DefWithBody {
11631187 }
11641188 }
11651189 }
1190+ for ( expr, mismatch) in infer. expr_type_mismatches ( ) {
1191+ let expr = match source_map. expr_syntax ( expr) {
1192+ Ok ( expr) => expr,
1193+ Err ( SyntheticSyntax ) => continue ,
1194+ } ;
1195+ acc. push (
1196+ TypeMismatch {
1197+ expr,
1198+ expected : Type :: new (
1199+ db,
1200+ krate,
1201+ DefWithBodyId :: from ( self ) ,
1202+ mismatch. expected . clone ( ) ,
1203+ ) ,
1204+ actual : Type :: new (
1205+ db,
1206+ krate,
1207+ DefWithBodyId :: from ( self ) ,
1208+ mismatch. actual . clone ( ) ,
1209+ ) ,
1210+ }
1211+ . into ( ) ,
1212+ ) ;
1213+ }
11661214
11671215 for expr in hir_ty:: diagnostics:: missing_unsafe ( db, self . into ( ) ) {
11681216 match source_map. expr_syntax ( expr) {
@@ -1259,25 +1307,6 @@ impl DefWithBody {
12591307 Err ( SyntheticSyntax ) => ( ) ,
12601308 }
12611309 }
1262- BodyValidationDiagnostic :: RemoveThisSemicolon { expr } => {
1263- match source_map. expr_syntax ( expr) {
1264- Ok ( expr) => acc. push ( RemoveThisSemicolon { expr } . into ( ) ) ,
1265- Err ( SyntheticSyntax ) => ( ) ,
1266- }
1267- }
1268- BodyValidationDiagnostic :: MissingOkOrSomeInTailExpr { expr, required } => {
1269- match source_map. expr_syntax ( expr) {
1270- Ok ( expr) => acc. push (
1271- MissingOkOrSomeInTailExpr {
1272- expr,
1273- required,
1274- expected : self . body_type ( db) ,
1275- }
1276- . into ( ) ,
1277- ) ,
1278- Err ( SyntheticSyntax ) => ( ) ,
1279- }
1280- }
12811310 BodyValidationDiagnostic :: MissingMatchArms { match_expr } => {
12821311 match source_map. expr_syntax ( match_expr) {
12831312 Ok ( source_ptr) => {
@@ -1299,12 +1328,6 @@ impl DefWithBody {
12991328 Err ( SyntheticSyntax ) => ( ) ,
13001329 }
13011330 }
1302- BodyValidationDiagnostic :: AddReferenceHere { arg_expr, mutability } => {
1303- match source_map. expr_syntax ( arg_expr) {
1304- Ok ( expr) => acc. push ( AddReferenceHere { expr, mutability } . into ( ) ) ,
1305- Err ( SyntheticSyntax ) => ( ) ,
1306- }
1307- }
13081331 }
13091332 }
13101333
@@ -2618,6 +2641,17 @@ impl Type {
26182641 Type { krate, env : environment, ty }
26192642 }
26202643
2644+ pub fn reference ( inner : & Type , m : Mutability ) -> Type {
2645+ inner. derived (
2646+ TyKind :: Ref (
2647+ if m. is_mut ( ) { hir_ty:: Mutability :: Mut } else { hir_ty:: Mutability :: Not } ,
2648+ hir_ty:: static_lifetime ( ) ,
2649+ inner. ty . clone ( ) ,
2650+ )
2651+ . intern ( Interner ) ,
2652+ )
2653+ }
2654+
26212655 fn new ( db : & dyn HirDatabase , krate : CrateId , lexical_env : impl HasResolver , ty : Ty ) -> Type {
26222656 let resolver = lexical_env. resolver ( db. upcast ( ) ) ;
26232657 let environment = resolver
@@ -2659,6 +2693,12 @@ impl Type {
26592693 matches ! ( self . ty. kind( Interner ) , TyKind :: Ref ( ..) )
26602694 }
26612695
2696+ pub fn as_reference ( & self ) -> Option < ( Type , Mutability ) > {
2697+ let ( ty, _lt, m) = self . ty . as_reference ( ) ?;
2698+ let m = Mutability :: from_mutable ( matches ! ( m, hir_ty:: Mutability :: Mut ) ) ;
2699+ Some ( ( self . derived ( ty. clone ( ) ) , m) )
2700+ }
2701+
26622702 pub fn is_slice ( & self ) -> bool {
26632703 matches ! ( self . ty. kind( Interner ) , TyKind :: Slice ( ..) )
26642704 }
@@ -2900,7 +2940,7 @@ impl Type {
29002940 self . autoderef_ ( db) . map ( move |ty| self . derived ( ty) )
29012941 }
29022942
2903- pub fn autoderef_ < ' a > ( & ' a self , db : & ' a dyn HirDatabase ) -> impl Iterator < Item = Ty > + ' a {
2943+ fn autoderef_ < ' a > ( & ' a self , db : & ' a dyn HirDatabase ) -> impl Iterator < Item = Ty > + ' a {
29042944 // There should be no inference vars in types passed here
29052945 let canonical = hir_ty:: replace_errors_with_variables ( & self . ty ) ;
29062946 let environment = self . env . clone ( ) ;
@@ -3238,7 +3278,12 @@ impl Type {
32383278
32393279 pub fn could_unify_with ( & self , db : & dyn HirDatabase , other : & Type ) -> bool {
32403280 let tys = hir_ty:: replace_errors_with_variables ( & ( self . ty . clone ( ) , other. ty . clone ( ) ) ) ;
3241- could_unify ( db, self . env . clone ( ) , & tys)
3281+ hir_ty:: could_unify ( db, self . env . clone ( ) , & tys)
3282+ }
3283+
3284+ pub fn could_coerce_to ( & self , db : & dyn HirDatabase , to : & Type ) -> bool {
3285+ let tys = hir_ty:: replace_errors_with_variables ( & ( self . ty . clone ( ) , to. ty . clone ( ) ) ) ;
3286+ hir_ty:: could_coerce ( db, self . env . clone ( ) , & tys)
32423287 }
32433288}
32443289
0 commit comments