diff options
Diffstat (limited to 'crates/hir_ty/src')
23 files changed, 1470 insertions, 1346 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index be1fd1f13..56c6b92d4 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -12,9 +12,10 @@ use log::{info, warn}; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | to_assoc_type_id, | ||
15 | traits::{InEnvironment, Solution}, | 16 | traits::{InEnvironment, Solution}, |
16 | utils::generics, | 17 | utils::generics, |
17 | BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty, | 18 | BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substs, TraitRef, Ty, TyKind, |
18 | }; | 19 | }; |
19 | 20 | ||
20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 21 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
@@ -81,8 +82,12 @@ fn deref_by_trait( | |||
81 | 82 | ||
82 | // Now do the assoc type projection | 83 | // Now do the assoc type projection |
83 | let projection = super::traits::ProjectionPredicate { | 84 | let projection = super::traits::ProjectionPredicate { |
84 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), | 85 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) |
85 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, | 86 | .intern(&Interner), |
87 | projection_ty: super::ProjectionTy { | ||
88 | associated_ty_id: to_assoc_type_id(target), | ||
89 | substitution: parameters, | ||
90 | }, | ||
86 | }; | 91 | }; |
87 | 92 | ||
88 | let obligation = super::Obligation::Projection(projection); | 93 | let obligation = super::Obligation::Projection(projection); |
@@ -114,8 +119,8 @@ fn deref_by_trait( | |||
114 | // new variables in that case | 119 | // new variables in that case |
115 | 120 | ||
116 | for i in 1..vars.0.kinds.len() { | 121 | for i in 1..vars.0.kinds.len() { |
117 | if vars.0.value[i - 1] | 122 | if vars.0.value[i - 1].interned(&Interner) |
118 | != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | 123 | != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) |
119 | { | 124 | { |
120 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); | 125 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); |
121 | return None; | 126 | return None; |
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 06714409f..74a048672 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -12,7 +12,7 @@ use la_arena::ArenaMap; | |||
12 | use crate::{ | 12 | use crate::{ |
13 | method_resolution::{InherentImpls, TraitImpls}, | 13 | method_resolution::{InherentImpls, TraitImpls}, |
14 | traits::chalk, | 14 | traits::chalk, |
15 | Binders, CallableDefId, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig, | 15 | Binders, CallableDefId, FnDefId, GenericPredicate, ImplTraitId, InferenceResult, PolyFnSig, |
16 | ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, | 16 | ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, |
17 | }; | 17 | }; |
18 | use hir_expand::name::Name; | 18 | use hir_expand::name::Name; |
@@ -65,6 +65,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
65 | #[salsa::invoke(crate::lower::generic_predicates_query)] | 65 | #[salsa::invoke(crate::lower::generic_predicates_query)] |
66 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; | 66 | fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; |
67 | 67 | ||
68 | #[salsa::invoke(crate::lower::trait_environment_query)] | ||
69 | fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>; | ||
70 | |||
68 | #[salsa::invoke(crate::lower::generic_defaults_query)] | 71 | #[salsa::invoke(crate::lower::generic_defaults_query)] |
69 | fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; | 72 | fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; |
70 | 73 | ||
@@ -81,11 +84,11 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
81 | #[salsa::interned] | 84 | #[salsa::interned] |
82 | fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; | 85 | fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; |
83 | #[salsa::interned] | 86 | #[salsa::interned] |
84 | fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; | 87 | fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId; |
85 | #[salsa::interned] | 88 | #[salsa::interned] |
86 | fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId; | 89 | fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId; |
87 | #[salsa::interned] | 90 | #[salsa::interned] |
88 | fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> ClosureId; | 91 | fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId; |
89 | 92 | ||
90 | #[salsa::invoke(chalk::associated_ty_data_query)] | 93 | #[salsa::invoke(chalk::associated_ty_data_query)] |
91 | fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; | 94 | fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; |
@@ -100,10 +103,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
100 | fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; | 103 | fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; |
101 | 104 | ||
102 | #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] | 105 | #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] |
103 | fn fn_def_datum(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> Arc<chalk::FnDefDatum>; | 106 | fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk::FnDefDatum>; |
104 | 107 | ||
105 | #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] | 108 | #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] |
106 | fn fn_def_variance(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> chalk::Variances; | 109 | fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk::Variances; |
107 | 110 | ||
108 | #[salsa::invoke(crate::traits::chalk::adt_variance_query)] | 111 | #[salsa::invoke(crate::traits::chalk::adt_variance_query)] |
109 | fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; | 112 | fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; |
@@ -149,16 +152,16 @@ fn hir_database_is_object_safe() { | |||
149 | } | 152 | } |
150 | 153 | ||
151 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 154 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
152 | pub struct GlobalTypeParamId(salsa::InternId); | 155 | pub struct InternedTypeParamId(salsa::InternId); |
153 | impl_intern_key!(GlobalTypeParamId); | 156 | impl_intern_key!(InternedTypeParamId); |
154 | 157 | ||
155 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 158 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
156 | pub struct InternedOpaqueTyId(salsa::InternId); | 159 | pub struct InternedOpaqueTyId(salsa::InternId); |
157 | impl_intern_key!(InternedOpaqueTyId); | 160 | impl_intern_key!(InternedOpaqueTyId); |
158 | 161 | ||
159 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 162 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
160 | pub struct ClosureId(salsa::InternId); | 163 | pub struct InternedClosureId(salsa::InternId); |
161 | impl_intern_key!(ClosureId); | 164 | impl_intern_key!(InternedClosureId); |
162 | 165 | ||
163 | /// This exists just for Chalk, because Chalk just has a single `FnDefId` where | 166 | /// This exists just for Chalk, because Chalk just has a single `FnDefId` where |
164 | /// we have different IDs for struct and enum variant constructors. | 167 | /// we have different IDs for struct and enum variant constructors. |
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 2751cd304..b2bfd68d4 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -15,7 +15,7 @@ use crate::{ | |||
15 | MissingPatFields, RemoveThisSemicolon, | 15 | MissingPatFields, RemoveThisSemicolon, |
16 | }, | 16 | }, |
17 | utils::variant_data, | 17 | utils::variant_data, |
18 | AdtId, InferenceResult, Ty, | 18 | AdtId, InferenceResult, Interner, Ty, TyKind, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | pub(crate) use hir_def::{ | 21 | pub(crate) use hir_def::{ |
@@ -289,11 +289,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
289 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = | 289 | let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = |
290 | db.body_with_source_map(self.owner.into()); | 290 | db.body_with_source_map(self.owner.into()); |
291 | 291 | ||
292 | let match_expr_ty = match infer.type_of_expr.get(match_expr) { | 292 | let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() { |
293 | // If we can't resolve the type of the match expression | 293 | return; |
294 | // we cannot perform exhaustiveness checks. | 294 | } else { |
295 | None | Some(Ty::Unknown) => return, | 295 | &infer.type_of_expr[match_expr] |
296 | Some(ty) => ty, | ||
297 | }; | 296 | }; |
298 | 297 | ||
299 | let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db }; | 298 | let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db }; |
@@ -379,14 +378,14 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
379 | _ => return, | 378 | _ => return, |
380 | }; | 379 | }; |
381 | 380 | ||
382 | let (params, required) = match mismatch.expected { | 381 | let (params, required) = match mismatch.expected.interned(&Interner) { |
383 | Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) | 382 | TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) |
384 | if enum_id == core_result_enum => | 383 | if *enum_id == core_result_enum => |
385 | { | 384 | { |
386 | (parameters, "Ok".to_string()) | 385 | (parameters, "Ok".to_string()) |
387 | } | 386 | } |
388 | Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) | 387 | TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) |
389 | if enum_id == core_option_enum => | 388 | if *enum_id == core_option_enum => |
390 | { | 389 | { |
391 | (parameters, "Some".to_string()) | 390 | (parameters, "Some".to_string()) |
392 | } | 391 | } |
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs index 04d39c571..5a5cdcbf3 100644 --- a/crates/hir_ty/src/diagnostics/match_check.rs +++ b/crates/hir_ty/src/diagnostics/match_check.rs | |||
@@ -227,7 +227,7 @@ use hir_def::{ | |||
227 | use la_arena::Idx; | 227 | use la_arena::Idx; |
228 | use smallvec::{smallvec, SmallVec}; | 228 | use smallvec::{smallvec, SmallVec}; |
229 | 229 | ||
230 | use crate::{db::HirDatabase, AdtId, InferenceResult, Ty}; | 230 | use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyKind}; |
231 | 231 | ||
232 | #[derive(Debug, Clone, Copy)] | 232 | #[derive(Debug, Clone, Copy)] |
233 | /// Either a pattern from the source code being analyzed, represented as | 233 | /// Either a pattern from the source code being analyzed, represented as |
@@ -626,13 +626,13 @@ pub(super) fn is_useful( | |||
626 | // - enum with no variants | 626 | // - enum with no variants |
627 | // - `!` type | 627 | // - `!` type |
628 | // In those cases, no match arm is useful. | 628 | // In those cases, no match arm is useful. |
629 | match cx.infer[cx.match_expr].strip_references() { | 629 | match cx.infer[cx.match_expr].strip_references().interned(&Interner) { |
630 | Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { | 630 | TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { |
631 | if cx.db.enum_data(*enum_id).variants.is_empty() { | 631 | if cx.db.enum_data(*enum_id).variants.is_empty() { |
632 | return Ok(Usefulness::NotUseful); | 632 | return Ok(Usefulness::NotUseful); |
633 | } | 633 | } |
634 | } | 634 | } |
635 | Ty::Never => return Ok(Usefulness::NotUseful), | 635 | TyKind::Never => return Ok(Usefulness::NotUseful), |
636 | _ => (), | 636 | _ => (), |
637 | } | 637 | } |
638 | 638 | ||
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index e77a20fea..20bb64827 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs | |||
@@ -11,7 +11,7 @@ use hir_def::{ | |||
11 | }; | 11 | }; |
12 | use hir_expand::diagnostics::DiagnosticSink; | 12 | use hir_expand::diagnostics::DiagnosticSink; |
13 | 13 | ||
14 | use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty}; | 14 | use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyKind}; |
15 | 15 | ||
16 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { | 16 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { |
17 | owner: DefWithBodyId, | 17 | owner: DefWithBodyId, |
@@ -85,7 +85,7 @@ fn walk_unsafe( | |||
85 | let expr = &body.exprs[current]; | 85 | let expr = &body.exprs[current]; |
86 | match expr { | 86 | match expr { |
87 | &Expr::Call { callee, .. } => { | 87 | &Expr::Call { callee, .. } => { |
88 | if let Some(func) = infer[callee].as_fn_def() { | 88 | if let Some(func) = infer[callee].as_fn_def(db) { |
89 | if db.function_data(func).is_unsafe { | 89 | if db.function_data(func).is_unsafe { |
90 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); | 90 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); |
91 | } | 91 | } |
@@ -110,7 +110,7 @@ fn walk_unsafe( | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { | 112 | Expr::UnaryOp { expr, op: UnaryOp::Deref } => { |
113 | if let Ty::Raw(..) = &infer[*expr] { | 113 | if let TyKind::Raw(..) = &infer[*expr].interned(&Interner) { |
114 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); | 114 | unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); |
115 | } | 115 | } |
116 | } | 116 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index ab51cb0a6..c1062387e 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -11,9 +11,10 @@ use hir_def::{ | |||
11 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | db::HirDatabase, primitive, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig, | 14 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, |
15 | GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, | 15 | to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId, |
16 | TraitRef, Ty, | 16 | CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy, |
17 | ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind, | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | pub struct HirFormatter<'a> { | 20 | pub struct HirFormatter<'a> { |
@@ -244,19 +245,19 @@ impl HirDisplay for ProjectionTy { | |||
244 | } | 245 | } |
245 | 246 | ||
246 | let trait_ = f.db.trait_data(self.trait_(f.db)); | 247 | let trait_ = f.db.trait_data(self.trait_(f.db)); |
247 | let first_parameter = self.parameters[0].into_displayable( | 248 | let first_parameter = self.substitution[0].into_displayable( |
248 | f.db, | 249 | f.db, |
249 | f.max_size, | 250 | f.max_size, |
250 | f.omit_verbose_types, | 251 | f.omit_verbose_types, |
251 | f.display_target, | 252 | f.display_target, |
252 | ); | 253 | ); |
253 | write!(f, "<{} as {}", first_parameter, trait_.name)?; | 254 | write!(f, "<{} as {}", first_parameter, trait_.name)?; |
254 | if self.parameters.len() > 1 { | 255 | if self.substitution.len() > 1 { |
255 | write!(f, "<")?; | 256 | write!(f, "<")?; |
256 | f.write_joined(&self.parameters[1..], ", ")?; | 257 | f.write_joined(&self.substitution[1..], ", ")?; |
257 | write!(f, ">")?; | 258 | write!(f, ">")?; |
258 | } | 259 | } |
259 | write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; | 260 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; |
260 | Ok(()) | 261 | Ok(()) |
261 | } | 262 | } |
262 | } | 263 | } |
@@ -267,32 +268,29 @@ impl HirDisplay for Ty { | |||
267 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | 268 | return write!(f, "{}", TYPE_HINT_TRUNCATION); |
268 | } | 269 | } |
269 | 270 | ||
270 | match self { | 271 | match self.interned(&Interner) { |
271 | Ty::Never => write!(f, "!")?, | 272 | TyKind::Never => write!(f, "!")?, |
272 | Ty::Str => write!(f, "str")?, | 273 | TyKind::Str => write!(f, "str")?, |
273 | Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, | 274 | TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?, |
274 | Ty::Scalar(Scalar::Char) => write!(f, "char")?, | 275 | TyKind::Scalar(Scalar::Char) => write!(f, "char")?, |
275 | &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, | 276 | &TyKind::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, |
276 | &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, | 277 | &TyKind::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, |
277 | &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, | 278 | &TyKind::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, |
278 | Ty::Slice(parameters) => { | 279 | TyKind::Slice(t) => { |
279 | let t = parameters.as_single(); | ||
280 | write!(f, "[")?; | 280 | write!(f, "[")?; |
281 | t.hir_fmt(f)?; | 281 | t.hir_fmt(f)?; |
282 | write!(f, "]")?; | 282 | write!(f, "]")?; |
283 | } | 283 | } |
284 | Ty::Array(parameters) => { | 284 | TyKind::Array(t) => { |
285 | let t = parameters.as_single(); | ||
286 | write!(f, "[")?; | 285 | write!(f, "[")?; |
287 | t.hir_fmt(f)?; | 286 | t.hir_fmt(f)?; |
288 | write!(f, "; _]")?; | 287 | write!(f, "; _]")?; |
289 | } | 288 | } |
290 | Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => { | 289 | TyKind::Raw(m, t) | TyKind::Ref(m, t) => { |
291 | let t = parameters.as_single(); | ||
292 | let ty_display = | 290 | let ty_display = |
293 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); | 291 | t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); |
294 | 292 | ||
295 | if matches!(self, Ty::Raw(..)) { | 293 | if matches!(self.interned(&Interner), TyKind::Raw(..)) { |
296 | write!( | 294 | write!( |
297 | f, | 295 | f, |
298 | "*{}", | 296 | "*{}", |
@@ -312,22 +310,29 @@ impl HirDisplay for Ty { | |||
312 | )?; | 310 | )?; |
313 | } | 311 | } |
314 | 312 | ||
313 | // FIXME: all this just to decide whether to use parentheses... | ||
315 | let datas; | 314 | let datas; |
316 | let predicates = match t { | 315 | let predicates = match t.interned(&Interner) { |
317 | Ty::Dyn(predicates) if predicates.len() > 1 => { | 316 | TyKind::Dyn(predicates) if predicates.len() > 1 => { |
318 | Cow::Borrowed(predicates.as_ref()) | 317 | Cow::Borrowed(predicates.as_ref()) |
319 | } | 318 | } |
320 | &Ty::Alias(AliasTy::Opaque(OpaqueTy { | 319 | &TyKind::Alias(AliasTy::Opaque(OpaqueTy { |
321 | opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), | 320 | opaque_ty_id, |
322 | ref parameters, | 321 | substitution: ref parameters, |
323 | })) => { | 322 | })) => { |
324 | datas = | 323 | let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into()); |
325 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 324 | if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id { |
326 | let data = (*datas) | 325 | datas = |
327 | .as_ref() | 326 | f.db.return_type_impl_traits(func) |
328 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 327 | .expect("impl trait id without data"); |
329 | let bounds = data.subst(parameters); | 328 | let data = (*datas) |
330 | Cow::Owned(bounds.value) | 329 | .as_ref() |
330 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | ||
331 | let bounds = data.subst(parameters); | ||
332 | Cow::Owned(bounds.value) | ||
333 | } else { | ||
334 | Cow::Borrowed(&[][..]) | ||
335 | } | ||
331 | } | 336 | } |
332 | _ => Cow::Borrowed(&[][..]), | 337 | _ => Cow::Borrowed(&[][..]), |
333 | }; | 338 | }; |
@@ -347,7 +352,7 @@ impl HirDisplay for Ty { | |||
347 | write!(f, "{}", ty_display)?; | 352 | write!(f, "{}", ty_display)?; |
348 | } | 353 | } |
349 | } | 354 | } |
350 | Ty::Tuple(_, substs) => { | 355 | TyKind::Tuple(_, substs) => { |
351 | if substs.len() == 1 { | 356 | if substs.len() == 1 { |
352 | write!(f, "(")?; | 357 | write!(f, "(")?; |
353 | substs[0].hir_fmt(f)?; | 358 | substs[0].hir_fmt(f)?; |
@@ -358,12 +363,12 @@ impl HirDisplay for Ty { | |||
358 | write!(f, ")")?; | 363 | write!(f, ")")?; |
359 | } | 364 | } |
360 | } | 365 | } |
361 | Ty::Function(fn_ptr) => { | 366 | TyKind::Function(fn_ptr) => { |
362 | let sig = CallableSig::from_fn_ptr(fn_ptr); | 367 | let sig = CallableSig::from_fn_ptr(fn_ptr); |
363 | sig.hir_fmt(f)?; | 368 | sig.hir_fmt(f)?; |
364 | } | 369 | } |
365 | Ty::FnDef(def, parameters) => { | 370 | TyKind::FnDef(def, parameters) => { |
366 | let def = *def; | 371 | let def = from_chalk(f.db, *def); |
367 | let sig = f.db.callable_item_signature(def).subst(parameters); | 372 | let sig = f.db.callable_item_signature(def).subst(parameters); |
368 | match def { | 373 | match def { |
369 | CallableDefId::FunctionId(ff) => { | 374 | CallableDefId::FunctionId(ff) => { |
@@ -401,7 +406,7 @@ impl HirDisplay for Ty { | |||
401 | write!(f, " -> {}", ret_display)?; | 406 | write!(f, " -> {}", ret_display)?; |
402 | } | 407 | } |
403 | } | 408 | } |
404 | Ty::Adt(AdtId(def_id), parameters) => { | 409 | TyKind::Adt(AdtId(def_id), parameters) => { |
405 | match f.display_target { | 410 | match f.display_target { |
406 | DisplayTarget::Diagnostics | DisplayTarget::Test => { | 411 | DisplayTarget::Diagnostics | DisplayTarget::Test => { |
407 | let name = match *def_id { | 412 | let name = match *def_id { |
@@ -427,37 +432,39 @@ impl HirDisplay for Ty { | |||
427 | } | 432 | } |
428 | 433 | ||
429 | if parameters.len() > 0 { | 434 | if parameters.len() > 0 { |
430 | let parameters_to_write = | 435 | let parameters_to_write = if f.display_target.is_source_code() |
431 | if f.display_target.is_source_code() || f.omit_verbose_types() { | 436 | || f.omit_verbose_types() |
432 | match self | 437 | { |
433 | .as_generic_def() | 438 | match self |
434 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 439 | .as_generic_def(f.db) |
435 | .filter(|defaults| !defaults.is_empty()) | 440 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
436 | { | 441 | .filter(|defaults| !defaults.is_empty()) |
437 | None => parameters.0.as_ref(), | 442 | { |
438 | Some(default_parameters) => { | 443 | None => parameters.0.as_ref(), |
439 | let mut default_from = 0; | 444 | Some(default_parameters) => { |
440 | for (i, parameter) in parameters.iter().enumerate() { | 445 | let mut default_from = 0; |
441 | match (parameter, default_parameters.get(i)) { | 446 | for (i, parameter) in parameters.iter().enumerate() { |
442 | (&Ty::Unknown, _) | (_, None) => { | 447 | match (parameter.interned(&Interner), default_parameters.get(i)) |
448 | { | ||
449 | (&TyKind::Unknown, _) | (_, None) => { | ||
450 | default_from = i + 1; | ||
451 | } | ||
452 | (_, Some(default_parameter)) => { | ||
453 | let actual_default = default_parameter | ||
454 | .clone() | ||
455 | .subst(¶meters.prefix(i)); | ||
456 | if parameter != &actual_default { | ||
443 | default_from = i + 1; | 457 | default_from = i + 1; |
444 | } | 458 | } |
445 | (_, Some(default_parameter)) => { | ||
446 | let actual_default = default_parameter | ||
447 | .clone() | ||
448 | .subst(¶meters.prefix(i)); | ||
449 | if parameter != &actual_default { | ||
450 | default_from = i + 1; | ||
451 | } | ||
452 | } | ||
453 | } | 459 | } |
454 | } | 460 | } |
455 | ¶meters.0[0..default_from] | ||
456 | } | 461 | } |
462 | ¶meters.0[0..default_from] | ||
457 | } | 463 | } |
458 | } else { | 464 | } |
459 | parameters.0.as_ref() | 465 | } else { |
460 | }; | 466 | parameters.0.as_ref() |
467 | }; | ||
461 | if !parameters_to_write.is_empty() { | 468 | if !parameters_to_write.is_empty() { |
462 | write!(f, "<")?; | 469 | write!(f, "<")?; |
463 | f.write_joined(parameters_to_write, ", ")?; | 470 | f.write_joined(parameters_to_write, ", ")?; |
@@ -465,13 +472,14 @@ impl HirDisplay for Ty { | |||
465 | } | 472 | } |
466 | } | 473 | } |
467 | } | 474 | } |
468 | Ty::AssociatedType(type_alias, parameters) => { | 475 | TyKind::AssociatedType(assoc_type_id, parameters) => { |
476 | let type_alias = from_assoc_type_id(*assoc_type_id); | ||
469 | let trait_ = match type_alias.lookup(f.db.upcast()).container { | 477 | let trait_ = match type_alias.lookup(f.db.upcast()).container { |
470 | AssocContainerId::TraitId(it) => it, | 478 | AssocContainerId::TraitId(it) => it, |
471 | _ => panic!("not an associated type"), | 479 | _ => panic!("not an associated type"), |
472 | }; | 480 | }; |
473 | let trait_ = f.db.trait_data(trait_); | 481 | let trait_ = f.db.trait_data(trait_); |
474 | let type_alias_data = f.db.type_alias_data(*type_alias); | 482 | let type_alias_data = f.db.type_alias_data(type_alias); |
475 | 483 | ||
476 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) | 484 | // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) |
477 | if f.display_target.is_test() { | 485 | if f.display_target.is_test() { |
@@ -482,19 +490,22 @@ impl HirDisplay for Ty { | |||
482 | write!(f, ">")?; | 490 | write!(f, ">")?; |
483 | } | 491 | } |
484 | } else { | 492 | } else { |
485 | let projection_ty = | 493 | let projection_ty = ProjectionTy { |
486 | ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() }; | 494 | associated_ty_id: to_assoc_type_id(type_alias), |
495 | substitution: parameters.clone(), | ||
496 | }; | ||
487 | 497 | ||
488 | projection_ty.hir_fmt(f)?; | 498 | projection_ty.hir_fmt(f)?; |
489 | } | 499 | } |
490 | } | 500 | } |
491 | Ty::ForeignType(type_alias) => { | 501 | TyKind::ForeignType(type_alias) => { |
492 | let type_alias = f.db.type_alias_data(*type_alias); | 502 | let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias)); |
493 | write!(f, "{}", type_alias.name)?; | 503 | write!(f, "{}", type_alias.name)?; |
494 | } | 504 | } |
495 | Ty::OpaqueType(opaque_ty_id, parameters) => { | 505 | TyKind::OpaqueType(opaque_ty_id, parameters) => { |
496 | match opaque_ty_id { | 506 | let impl_trait_id = f.db.lookup_intern_impl_trait_id((*opaque_ty_id).into()); |
497 | &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 507 | match impl_trait_id { |
508 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
498 | let datas = | 509 | let datas = |
499 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 510 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
500 | let data = (*datas) | 511 | let data = (*datas) |
@@ -504,14 +515,14 @@ impl HirDisplay for Ty { | |||
504 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 515 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; |
505 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution | 516 | // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution |
506 | } | 517 | } |
507 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 518 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
508 | write!(f, "impl Future<Output = ")?; | 519 | write!(f, "impl Future<Output = ")?; |
509 | parameters[0].hir_fmt(f)?; | 520 | parameters[0].hir_fmt(f)?; |
510 | write!(f, ">")?; | 521 | write!(f, ">")?; |
511 | } | 522 | } |
512 | } | 523 | } |
513 | } | 524 | } |
514 | Ty::Closure(.., substs) => { | 525 | TyKind::Closure(.., substs) => { |
515 | let sig = substs[0].callable_sig(f.db); | 526 | let sig = substs[0].callable_sig(f.db); |
516 | if let Some(sig) = sig { | 527 | if let Some(sig) = sig { |
517 | if sig.params().is_empty() { | 528 | if sig.params().is_empty() { |
@@ -535,7 +546,8 @@ impl HirDisplay for Ty { | |||
535 | write!(f, "{{closure}}")?; | 546 | write!(f, "{{closure}}")?; |
536 | } | 547 | } |
537 | } | 548 | } |
538 | Ty::Placeholder(id) => { | 549 | TyKind::Placeholder(idx) => { |
550 | let id = from_placeholder_idx(f.db, *idx); | ||
539 | let generics = generics(f.db.upcast(), id.parent); | 551 | let generics = generics(f.db.upcast(), id.parent); |
540 | let param_data = &generics.params.types[id.local_id]; | 552 | let param_data = &generics.params.types[id.local_id]; |
541 | match param_data.provenance { | 553 | match param_data.provenance { |
@@ -543,8 +555,8 @@ impl HirDisplay for Ty { | |||
543 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? | 555 | write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? |
544 | } | 556 | } |
545 | TypeParamProvenance::ArgumentImplTrait => { | 557 | TypeParamProvenance::ArgumentImplTrait => { |
546 | let bounds = f.db.generic_predicates_for_param(*id); | 558 | let bounds = f.db.generic_predicates_for_param(id); |
547 | let substs = Substs::type_params_for_generics(&generics); | 559 | let substs = Substs::type_params_for_generics(f.db, &generics); |
548 | write_bounds_like_dyn_trait_with_prefix( | 560 | write_bounds_like_dyn_trait_with_prefix( |
549 | "impl", | 561 | "impl", |
550 | &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), | 562 | &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), |
@@ -553,28 +565,29 @@ impl HirDisplay for Ty { | |||
553 | } | 565 | } |
554 | } | 566 | } |
555 | } | 567 | } |
556 | Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, | 568 | TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, |
557 | Ty::Dyn(predicates) => { | 569 | TyKind::Dyn(predicates) => { |
558 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; | 570 | write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; |
559 | } | 571 | } |
560 | Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, | 572 | TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, |
561 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | 573 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
562 | match opaque_ty.opaque_ty_id { | 574 | let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into()); |
563 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 575 | match impl_trait_id { |
576 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
564 | let datas = | 577 | let datas = |
565 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); | 578 | f.db.return_type_impl_traits(func).expect("impl trait id without data"); |
566 | let data = (*datas) | 579 | let data = (*datas) |
567 | .as_ref() | 580 | .as_ref() |
568 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 581 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
569 | let bounds = data.subst(&opaque_ty.parameters); | 582 | let bounds = data.subst(&opaque_ty.substitution); |
570 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; | 583 | write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; |
571 | } | 584 | } |
572 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 585 | ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
573 | write!(f, "{{async block}}")?; | 586 | write!(f, "{{async block}}")?; |
574 | } | 587 | } |
575 | }; | 588 | }; |
576 | } | 589 | } |
577 | Ty::Unknown => { | 590 | TyKind::Unknown => { |
578 | if f.display_target.is_source_code() { | 591 | if f.display_target.is_source_code() { |
579 | return Err(HirDisplayError::DisplaySourceCodeError( | 592 | return Err(HirDisplayError::DisplaySourceCodeError( |
580 | DisplaySourceCodeError::UnknownType, | 593 | DisplaySourceCodeError::UnknownType, |
@@ -582,7 +595,7 @@ impl HirDisplay for Ty { | |||
582 | } | 595 | } |
583 | write!(f, "{{unknown}}")?; | 596 | write!(f, "{{unknown}}")?; |
584 | } | 597 | } |
585 | Ty::InferenceVar(..) => write!(f, "_")?, | 598 | TyKind::InferenceVar(..) => write!(f, "_")?, |
586 | } | 599 | } |
587 | Ok(()) | 600 | Ok(()) |
588 | } | 601 | } |
@@ -695,7 +708,9 @@ fn write_bounds_like_dyn_trait( | |||
695 | write!(f, "<")?; | 708 | write!(f, "<")?; |
696 | angle_open = true; | 709 | angle_open = true; |
697 | } | 710 | } |
698 | let type_alias = f.db.type_alias_data(projection_pred.projection_ty.associated_ty); | 711 | let type_alias = f.db.type_alias_data(from_assoc_type_id( |
712 | projection_pred.projection_ty.associated_ty_id, | ||
713 | )); | ||
699 | write!(f, "{} = ", type_alias.name)?; | 714 | write!(f, "{} = ", type_alias.name)?; |
700 | projection_pred.ty.hir_fmt(f)?; | 715 | projection_pred.ty.hir_fmt(f)?; |
701 | } | 716 | } |
@@ -766,7 +781,10 @@ impl HirDisplay for GenericPredicate { | |||
766 | write!( | 781 | write!( |
767 | f, | 782 | f, |
768 | ">::{} = ", | 783 | ">::{} = ", |
769 | f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, | 784 | f.db.type_alias_data(from_assoc_type_id( |
785 | projection_pred.projection_ty.associated_ty_id | ||
786 | )) | ||
787 | .name, | ||
770 | )?; | 788 | )?; |
771 | projection_pred.ty.hir_fmt(f)?; | 789 | projection_pred.ty.hir_fmt(f)?; |
772 | } | 790 | } |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 4d771a91e..9c385b845 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -41,7 +41,8 @@ use super::{ | |||
41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, | 41 | InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, |
42 | }; | 42 | }; |
43 | use crate::{ | 43 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy, | 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, |
45 | to_assoc_type_id, AliasTy, Interner, TyKind, | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | pub(crate) use unify::unify; | 48 | pub(crate) use unify::unify; |
@@ -107,6 +108,17 @@ pub struct TypeMismatch { | |||
107 | pub actual: Ty, | 108 | pub actual: Ty, |
108 | } | 109 | } |
109 | 110 | ||
111 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
112 | struct InternedStandardTypes { | ||
113 | unknown: Ty, | ||
114 | } | ||
115 | |||
116 | impl Default for InternedStandardTypes { | ||
117 | fn default() -> Self { | ||
118 | InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) } | ||
119 | } | ||
120 | } | ||
121 | |||
110 | /// The result of type inference: A mapping from expressions and patterns to types. | 122 | /// The result of type inference: A mapping from expressions and patterns to types. |
111 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | 123 | #[derive(Clone, PartialEq, Eq, Debug, Default)] |
112 | pub struct InferenceResult { | 124 | pub struct InferenceResult { |
@@ -125,6 +137,8 @@ pub struct InferenceResult { | |||
125 | pub type_of_expr: ArenaMap<ExprId, Ty>, | 137 | pub type_of_expr: ArenaMap<ExprId, Ty>, |
126 | pub type_of_pat: ArenaMap<PatId, Ty>, | 138 | pub type_of_pat: ArenaMap<PatId, Ty>, |
127 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, | 139 | pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, |
140 | /// Interned Unknown to return references to. | ||
141 | standard_types: InternedStandardTypes, | ||
128 | } | 142 | } |
129 | 143 | ||
130 | impl InferenceResult { | 144 | impl InferenceResult { |
@@ -169,7 +183,7 @@ impl Index<ExprId> for InferenceResult { | |||
169 | type Output = Ty; | 183 | type Output = Ty; |
170 | 184 | ||
171 | fn index(&self, expr: ExprId) -> &Ty { | 185 | fn index(&self, expr: ExprId) -> &Ty { |
172 | self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) | 186 | self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown) |
173 | } | 187 | } |
174 | } | 188 | } |
175 | 189 | ||
@@ -177,7 +191,7 @@ impl Index<PatId> for InferenceResult { | |||
177 | type Output = Ty; | 191 | type Output = Ty; |
178 | 192 | ||
179 | fn index(&self, pat: PatId) -> &Ty { | 193 | fn index(&self, pat: PatId) -> &Ty { |
180 | self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) | 194 | self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown) |
181 | } | 195 | } |
182 | } | 196 | } |
183 | 197 | ||
@@ -226,8 +240,10 @@ impl<'a> InferenceContext<'a> { | |||
226 | result: InferenceResult::default(), | 240 | result: InferenceResult::default(), |
227 | table: unify::InferenceTable::new(), | 241 | table: unify::InferenceTable::new(), |
228 | obligations: Vec::default(), | 242 | obligations: Vec::default(), |
229 | return_ty: Ty::Unknown, // set in collect_fn_signature | 243 | return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature |
230 | trait_env: TraitEnvironment::lower(db, &resolver), | 244 | trait_env: owner |
245 | .as_generic_def_id() | ||
246 | .map_or_else(Default::default, |d| db.trait_environment(d)), | ||
231 | db, | 247 | db, |
232 | owner, | 248 | owner, |
233 | body: db.body(owner), | 249 | body: db.body(owner), |
@@ -237,15 +253,19 @@ impl<'a> InferenceContext<'a> { | |||
237 | } | 253 | } |
238 | } | 254 | } |
239 | 255 | ||
256 | fn err_ty(&self) -> Ty { | ||
257 | TyKind::Unknown.intern(&Interner) | ||
258 | } | ||
259 | |||
240 | fn resolve_all(mut self) -> InferenceResult { | 260 | fn resolve_all(mut self) -> InferenceResult { |
241 | // FIXME resolve obligations as well (use Guidance if necessary) | 261 | // FIXME resolve obligations as well (use Guidance if necessary) |
242 | let mut result = std::mem::take(&mut self.result); | 262 | let mut result = std::mem::take(&mut self.result); |
243 | for ty in result.type_of_expr.values_mut() { | 263 | for ty in result.type_of_expr.values_mut() { |
244 | let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); | 264 | let resolved = self.table.resolve_ty_completely(ty.clone()); |
245 | *ty = resolved; | 265 | *ty = resolved; |
246 | } | 266 | } |
247 | for ty in result.type_of_pat.values_mut() { | 267 | for ty in result.type_of_pat.values_mut() { |
248 | let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); | 268 | let resolved = self.table.resolve_ty_completely(ty.clone()); |
249 | *ty = resolved; | 269 | *ty = resolved; |
250 | } | 270 | } |
251 | result | 271 | result |
@@ -287,7 +307,7 @@ impl<'a> InferenceContext<'a> { | |||
287 | // FIXME use right resolver for block | 307 | // FIXME use right resolver for block |
288 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) | 308 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) |
289 | .with_impl_trait_mode(impl_trait_mode); | 309 | .with_impl_trait_mode(impl_trait_mode); |
290 | let ty = Ty::from_hir(&ctx, type_ref); | 310 | let ty = ctx.lower_ty(type_ref); |
291 | let ty = self.insert_type_vars(ty); | 311 | let ty = self.insert_type_vars(ty); |
292 | self.normalize_associated_types_in(ty) | 312 | self.normalize_associated_types_in(ty) |
293 | } | 313 | } |
@@ -298,8 +318,8 @@ impl<'a> InferenceContext<'a> { | |||
298 | 318 | ||
299 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. | 319 | /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. |
300 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { | 320 | fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { |
301 | match ty { | 321 | match ty.interned(&Interner) { |
302 | Ty::Unknown => self.table.new_type_var(), | 322 | TyKind::Unknown => self.table.new_type_var(), |
303 | _ => ty, | 323 | _ => ty, |
304 | } | 324 | } |
305 | } | 325 | } |
@@ -377,13 +397,16 @@ impl<'a> InferenceContext<'a> { | |||
377 | let trait_ref = TraitRef { trait_, substs: substs.clone() }; | 397 | let trait_ref = TraitRef { trait_, substs: substs.clone() }; |
378 | let projection = ProjectionPredicate { | 398 | let projection = ProjectionPredicate { |
379 | ty: ty.clone(), | 399 | ty: ty.clone(), |
380 | projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs }, | 400 | projection_ty: ProjectionTy { |
401 | associated_ty_id: to_assoc_type_id(res_assoc_ty), | ||
402 | substitution: substs, | ||
403 | }, | ||
381 | }; | 404 | }; |
382 | self.obligations.push(Obligation::Trait(trait_ref)); | 405 | self.obligations.push(Obligation::Trait(trait_ref)); |
383 | self.obligations.push(Obligation::Projection(projection)); | 406 | self.obligations.push(Obligation::Projection(projection)); |
384 | self.resolve_ty_as_possible(ty) | 407 | self.resolve_ty_as_possible(ty) |
385 | } | 408 | } |
386 | None => Ty::Unknown, | 409 | None => self.err_ty(), |
387 | } | 410 | } |
388 | } | 411 | } |
389 | 412 | ||
@@ -395,8 +418,10 @@ impl<'a> InferenceContext<'a> { | |||
395 | /// to do it as well. | 418 | /// to do it as well. |
396 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { | 419 | fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { |
397 | let ty = self.resolve_ty_as_possible(ty); | 420 | let ty = self.resolve_ty_as_possible(ty); |
398 | ty.fold(&mut |ty| match ty { | 421 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
399 | Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), | 422 | TyKind::Alias(AliasTy::Projection(proj_ty)) => { |
423 | self.normalize_projection_ty(proj_ty.clone()) | ||
424 | } | ||
400 | _ => ty, | 425 | _ => ty, |
401 | }) | 426 | }) |
402 | } | 427 | } |
@@ -412,7 +437,7 @@ impl<'a> InferenceContext<'a> { | |||
412 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { | 437 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { |
413 | let path = match path { | 438 | let path = match path { |
414 | Some(path) => path, | 439 | Some(path) => path, |
415 | None => return (Ty::Unknown, None), | 440 | None => return (self.err_ty(), None), |
416 | }; | 441 | }; |
417 | let resolver = &self.resolver; | 442 | let resolver = &self.resolver; |
418 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); | 443 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
@@ -421,30 +446,30 @@ impl<'a> InferenceContext<'a> { | |||
421 | let (resolution, unresolved) = | 446 | let (resolution, unresolved) = |
422 | match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { | 447 | match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { |
423 | Some(it) => it, | 448 | Some(it) => it, |
424 | None => return (Ty::Unknown, None), | 449 | None => return (self.err_ty(), None), |
425 | }; | 450 | }; |
426 | return match resolution { | 451 | return match resolution { |
427 | TypeNs::AdtId(AdtId::StructId(strukt)) => { | 452 | TypeNs::AdtId(AdtId::StructId(strukt)) => { |
428 | let substs = Ty::substs_from_path(&ctx, path, strukt.into(), true); | 453 | let substs = ctx.substs_from_path(path, strukt.into(), true); |
429 | let ty = self.db.ty(strukt.into()); | 454 | let ty = self.db.ty(strukt.into()); |
430 | let ty = self.insert_type_vars(ty.subst(&substs)); | 455 | let ty = self.insert_type_vars(ty.subst(&substs)); |
431 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) | 456 | forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) |
432 | } | 457 | } |
433 | TypeNs::AdtId(AdtId::UnionId(u)) => { | 458 | TypeNs::AdtId(AdtId::UnionId(u)) => { |
434 | let substs = Ty::substs_from_path(&ctx, path, u.into(), true); | 459 | let substs = ctx.substs_from_path(path, u.into(), true); |
435 | let ty = self.db.ty(u.into()); | 460 | let ty = self.db.ty(u.into()); |
436 | let ty = self.insert_type_vars(ty.subst(&substs)); | 461 | let ty = self.insert_type_vars(ty.subst(&substs)); |
437 | forbid_unresolved_segments((ty, Some(u.into())), unresolved) | 462 | forbid_unresolved_segments((ty, Some(u.into())), unresolved) |
438 | } | 463 | } |
439 | TypeNs::EnumVariantId(var) => { | 464 | TypeNs::EnumVariantId(var) => { |
440 | let substs = Ty::substs_from_path(&ctx, path, var.into(), true); | 465 | let substs = ctx.substs_from_path(path, var.into(), true); |
441 | let ty = self.db.ty(var.parent.into()); | 466 | let ty = self.db.ty(var.parent.into()); |
442 | let ty = self.insert_type_vars(ty.subst(&substs)); | 467 | let ty = self.insert_type_vars(ty.subst(&substs)); |
443 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) | 468 | forbid_unresolved_segments((ty, Some(var.into())), unresolved) |
444 | } | 469 | } |
445 | TypeNs::SelfType(impl_id) => { | 470 | TypeNs::SelfType(impl_id) => { |
446 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 471 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
447 | let substs = Substs::type_params_for_generics(&generics); | 472 | let substs = Substs::type_params_for_generics(self.db, &generics); |
448 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); | 473 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); |
449 | match unresolved { | 474 | match unresolved { |
450 | None => { | 475 | None => { |
@@ -462,11 +487,11 @@ impl<'a> InferenceContext<'a> { | |||
462 | } | 487 | } |
463 | } | 488 | } |
464 | // FIXME potentially resolve assoc type | 489 | // FIXME potentially resolve assoc type |
465 | (Ty::Unknown, None) | 490 | (self.err_ty(), None) |
466 | } | 491 | } |
467 | Some(_) => { | 492 | Some(_) => { |
468 | // FIXME diagnostic | 493 | // FIXME diagnostic |
469 | (Ty::Unknown, None) | 494 | (self.err_ty(), None) |
470 | } | 495 | } |
471 | } | 496 | } |
472 | } | 497 | } |
@@ -480,15 +505,15 @@ impl<'a> InferenceContext<'a> { | |||
480 | } | 505 | } |
481 | TypeNs::AdtSelfType(_) => { | 506 | TypeNs::AdtSelfType(_) => { |
482 | // FIXME this could happen in array size expressions, once we're checking them | 507 | // FIXME this could happen in array size expressions, once we're checking them |
483 | (Ty::Unknown, None) | 508 | (self.err_ty(), None) |
484 | } | 509 | } |
485 | TypeNs::GenericParam(_) => { | 510 | TypeNs::GenericParam(_) => { |
486 | // FIXME potentially resolve assoc type | 511 | // FIXME potentially resolve assoc type |
487 | (Ty::Unknown, None) | 512 | (self.err_ty(), None) |
488 | } | 513 | } |
489 | TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { | 514 | TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { |
490 | // FIXME diagnostic | 515 | // FIXME diagnostic |
491 | (Ty::Unknown, None) | 516 | (self.err_ty(), None) |
492 | } | 517 | } |
493 | }; | 518 | }; |
494 | 519 | ||
@@ -500,7 +525,7 @@ impl<'a> InferenceContext<'a> { | |||
500 | result | 525 | result |
501 | } else { | 526 | } else { |
502 | // FIXME diagnostic | 527 | // FIXME diagnostic |
503 | (Ty::Unknown, None) | 528 | (TyKind::Unknown.intern(&Interner), None) |
504 | } | 529 | } |
505 | } | 530 | } |
506 | 531 | ||
@@ -529,7 +554,7 @@ impl<'a> InferenceContext<'a> { | |||
529 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) | 554 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) |
530 | .with_impl_trait_mode(ImplTraitLoweringMode::Param); | 555 | .with_impl_trait_mode(ImplTraitLoweringMode::Param); |
531 | let param_tys = | 556 | let param_tys = |
532 | data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>(); | 557 | data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(); |
533 | for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) { | 558 | for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) { |
534 | let ty = self.insert_type_vars(ty); | 559 | let ty = self.insert_type_vars(ty); |
535 | let ty = self.normalize_associated_types_in(ty); | 560 | let ty = self.normalize_associated_types_in(ty); |
@@ -711,14 +736,19 @@ impl Expectation { | |||
711 | 736 | ||
712 | /// This expresses no expectation on the type. | 737 | /// This expresses no expectation on the type. |
713 | fn none() -> Self { | 738 | fn none() -> Self { |
714 | Expectation { ty: Ty::Unknown, rvalue_hint: false } | 739 | Expectation { |
740 | // FIXME | ||
741 | ty: TyKind::Unknown.intern(&Interner), | ||
742 | rvalue_hint: false, | ||
743 | } | ||
715 | } | 744 | } |
716 | 745 | ||
717 | fn coercion_target(&self) -> &Ty { | 746 | fn coercion_target(&self) -> Ty { |
718 | if self.rvalue_hint { | 747 | if self.rvalue_hint { |
719 | &Ty::Unknown | 748 | // FIXME |
749 | TyKind::Unknown.intern(&Interner) | ||
720 | } else { | 750 | } else { |
721 | &self.ty | 751 | self.ty.clone() |
722 | } | 752 | } |
723 | } | 753 | } |
724 | } | 754 | } |
@@ -772,7 +802,7 @@ mod diagnostics { | |||
772 | 802 | ||
773 | #[derive(Debug, PartialEq, Eq, Clone)] | 803 | #[derive(Debug, PartialEq, Eq, Clone)] |
774 | pub(super) enum InferenceDiagnostic { | 804 | pub(super) enum InferenceDiagnostic { |
775 | NoSuchField { expr: ExprId, field: usize }, | 805 | NoSuchField { expr: ExprId }, |
776 | BreakOutsideOfLoop { expr: ExprId }, | 806 | BreakOutsideOfLoop { expr: ExprId }, |
777 | } | 807 | } |
778 | 808 | ||
@@ -784,9 +814,9 @@ mod diagnostics { | |||
784 | sink: &mut DiagnosticSink, | 814 | sink: &mut DiagnosticSink, |
785 | ) { | 815 | ) { |
786 | match self { | 816 | match self { |
787 | InferenceDiagnostic::NoSuchField { expr, field } => { | 817 | InferenceDiagnostic::NoSuchField { expr } => { |
788 | let (_, source_map) = db.body_with_source_map(owner); | 818 | let (_, source_map) = db.body_with_source_map(owner); |
789 | let field = source_map.field_syntax(*expr, *field); | 819 | let field = source_map.field_syntax(*expr); |
790 | sink.push(NoSuchField { file: field.file_id, field: field.value }) | 820 | sink.push(NoSuchField { file: field.file_id, field: field.value }) |
791 | } | 821 | } |
792 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { | 822 | InferenceDiagnostic::BreakOutsideOfLoop { expr } => { |
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 7e8846f27..137419264 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use chalk_ir::{Mutability, TyVariableKind}; | 7 | use chalk_ir::{Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; | 10 | use crate::{autoderef, traits::Solution, Interner, Obligation, Substs, TraitRef, Ty, TyKind}; |
11 | 11 | ||
12 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
13 | 13 | ||
@@ -33,7 +33,9 @@ impl<'a> InferenceContext<'a> { | |||
33 | } else if self.coerce(ty2, ty1) { | 33 | } else if self.coerce(ty2, ty1) { |
34 | ty1.clone() | 34 | ty1.clone() |
35 | } else { | 35 | } else { |
36 | if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { | 36 | if let (TyKind::FnDef(..), TyKind::FnDef(..)) = |
37 | (ty1.interned(&Interner), ty2.interned(&Interner)) | ||
38 | { | ||
37 | cov_mark::hit!(coerce_fn_reification); | 39 | cov_mark::hit!(coerce_fn_reification); |
38 | // Special case: two function types. Try to coerce both to | 40 | // Special case: two function types. Try to coerce both to |
39 | // pointers to have a chance at getting a match. See | 41 | // pointers to have a chance at getting a match. See |
@@ -51,13 +53,13 @@ impl<'a> InferenceContext<'a> { | |||
51 | } | 53 | } |
52 | 54 | ||
53 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { | 55 | fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { |
54 | match (&from_ty, to_ty) { | 56 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
55 | // Never type will make type variable to fallback to Never Type instead of Unknown. | 57 | // Never type will make type variable to fallback to Never Type instead of Unknown. |
56 | (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { | 58 | (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => { |
57 | self.table.type_variable_table.set_diverging(*tv, true); | 59 | self.table.type_variable_table.set_diverging(*tv, true); |
58 | return true; | 60 | return true; |
59 | } | 61 | } |
60 | (Ty::Never, _) => return true, | 62 | (TyKind::Never, _) => return true, |
61 | 63 | ||
62 | // Trivial cases, this should go after `never` check to | 64 | // Trivial cases, this should go after `never` check to |
63 | // avoid infer result type to be never | 65 | // avoid infer result type to be never |
@@ -69,33 +71,33 @@ impl<'a> InferenceContext<'a> { | |||
69 | } | 71 | } |
70 | 72 | ||
71 | // Pointer weakening and function to pointer | 73 | // Pointer weakening and function to pointer |
72 | match (&mut from_ty, to_ty) { | 74 | match (from_ty.interned_mut(), to_ty.interned(&Interner)) { |
73 | // `*mut T` -> `*const T` | 75 | // `*mut T` -> `*const T` |
74 | // `&mut T` -> `&T` | 76 | // `&mut T` -> `&T` |
75 | (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) | 77 | (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) |
76 | | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { | 78 | | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => { |
77 | *m1 = *m2; | 79 | *m1 = *m2; |
78 | } | 80 | } |
79 | // `&T` -> `*const T` | 81 | // `&T` -> `*const T` |
80 | // `&mut T` -> `*mut T`/`*const T` | 82 | // `&mut T` -> `*mut T`/`*const T` |
81 | (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) | 83 | (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..)) |
82 | | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { | 84 | | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => { |
83 | from_ty = Ty::Raw(m2, substs.clone()); | 85 | from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner); |
84 | } | 86 | } |
85 | 87 | ||
86 | // Illegal mutability conversion | 88 | // Illegal mutability conversion |
87 | (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) | 89 | (TyKind::Raw(Mutability::Not, ..), TyKind::Raw(Mutability::Mut, ..)) |
88 | | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, | 90 | | (TyKind::Ref(Mutability::Not, ..), TyKind::Ref(Mutability::Mut, ..)) => return false, |
89 | 91 | ||
90 | // `{function_type}` -> `fn()` | 92 | // `{function_type}` -> `fn()` |
91 | (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { | 93 | (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) { |
92 | None => return false, | 94 | None => return false, |
93 | Some(sig) => { | 95 | Some(sig) => { |
94 | from_ty = Ty::fn_ptr(sig); | 96 | from_ty = Ty::fn_ptr(sig); |
95 | } | 97 | } |
96 | }, | 98 | }, |
97 | 99 | ||
98 | (Ty::Closure(.., substs), Ty::Function { .. }) => { | 100 | (TyKind::Closure(.., substs), TyKind::Function { .. }) => { |
99 | from_ty = substs[0].clone(); | 101 | from_ty = substs[0].clone(); |
100 | } | 102 | } |
101 | 103 | ||
@@ -107,9 +109,9 @@ impl<'a> InferenceContext<'a> { | |||
107 | } | 109 | } |
108 | 110 | ||
109 | // Auto Deref if cannot coerce | 111 | // Auto Deref if cannot coerce |
110 | match (&from_ty, to_ty) { | 112 | match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { |
111 | // FIXME: DerefMut | 113 | // FIXME: DerefMut |
112 | (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), | 114 | (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), |
113 | 115 | ||
114 | // Otherwise, normal unify | 116 | // Otherwise, normal unify |
115 | _ => self.unify(&from_ty, to_ty), | 117 | _ => self.unify(&from_ty, to_ty), |
@@ -174,11 +176,7 @@ impl<'a> InferenceContext<'a> { | |||
174 | // Stop when constructor matches. | 176 | // Stop when constructor matches. |
175 | if from_ty.equals_ctor(&to_ty) { | 177 | if from_ty.equals_ctor(&to_ty) { |
176 | // It will not recurse to `coerce`. | 178 | // It will not recurse to `coerce`. |
177 | return match (from_ty.substs(), to_ty.substs()) { | 179 | return self.table.unify(&from_ty, &to_ty); |
178 | (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), | ||
179 | (None, None) => true, | ||
180 | _ => false, | ||
181 | }; | ||
182 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { | 180 | } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { |
183 | return true; | 181 | return true; |
184 | } | 182 | } |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 262177ffb..f40dec17f 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -18,10 +18,11 @@ use crate::{ | |||
18 | lower::lower_to_chalk_mutability, | 18 | lower::lower_to_chalk_mutability, |
19 | method_resolution, op, | 19 | method_resolution, op, |
20 | primitive::{self, UintTy}, | 20 | primitive::{self, UintTy}, |
21 | traits::{FnTrait, InEnvironment}, | 21 | to_assoc_type_id, |
22 | traits::{chalk::from_chalk, FnTrait, InEnvironment}, | ||
22 | utils::{generics, variant_data, Generics}, | 23 | utils::{generics, variant_data, Generics}, |
23 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, | 24 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, Substs, |
24 | Substs, TraitRef, Ty, | 25 | TraitRef, Ty, TyKind, |
25 | }; | 26 | }; |
26 | 27 | ||
27 | use super::{ | 28 | use super::{ |
@@ -57,7 +58,7 @@ impl<'a> InferenceContext<'a> { | |||
57 | // Return actual type when type mismatch. | 58 | // Return actual type when type mismatch. |
58 | // This is needed for diagnostic when return type mismatch. | 59 | // This is needed for diagnostic when return type mismatch. |
59 | ty | 60 | ty |
60 | } else if expected.coercion_target() == &Ty::Unknown { | 61 | } else if expected.coercion_target().is_unknown() { |
61 | ty | 62 | ty |
62 | } else { | 63 | } else { |
63 | expected.ty.clone() | 64 | expected.ty.clone() |
@@ -84,7 +85,7 @@ impl<'a> InferenceContext<'a> { | |||
84 | arg_tys.push(arg); | 85 | arg_tys.push(arg); |
85 | } | 86 | } |
86 | let parameters = param_builder.build(); | 87 | let parameters = param_builder.build(); |
87 | let arg_ty = Ty::Tuple(num_args, parameters); | 88 | let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner); |
88 | let substs = | 89 | let substs = |
89 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); | 90 | Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); |
90 | 91 | ||
@@ -97,8 +98,10 @@ impl<'a> InferenceContext<'a> { | |||
97 | }); | 98 | }); |
98 | if self.db.trait_solve(krate, goal.value).is_some() { | 99 | if self.db.trait_solve(krate, goal.value).is_some() { |
99 | self.obligations.push(implements_fn_trait); | 100 | self.obligations.push(implements_fn_trait); |
100 | let output_proj_ty = | 101 | let output_proj_ty = crate::ProjectionTy { |
101 | crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs }; | 102 | associated_ty_id: to_assoc_type_id(output_assoc_type), |
103 | substitution: substs, | ||
104 | }; | ||
102 | let return_ty = self.normalize_projection_ty(output_proj_ty); | 105 | let return_ty = self.normalize_projection_ty(output_proj_ty); |
103 | Some((arg_tys, return_ty)) | 106 | Some((arg_tys, return_ty)) |
104 | } else { | 107 | } else { |
@@ -116,10 +119,13 @@ impl<'a> InferenceContext<'a> { | |||
116 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 119 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
117 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 120 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
118 | let ty = match &body[tgt_expr] { | 121 | let ty = match &body[tgt_expr] { |
119 | Expr::Missing => Ty::Unknown, | 122 | Expr::Missing => self.err_ty(), |
120 | Expr::If { condition, then_branch, else_branch } => { | 123 | Expr::If { condition, then_branch, else_branch } => { |
121 | // if let is desugared to match, so this is always simple if | 124 | // if let is desugared to match, so this is always simple if |
122 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 125 | self.infer_expr( |
126 | *condition, | ||
127 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
128 | ); | ||
123 | 129 | ||
124 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); | 130 | let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); |
125 | let mut both_arms_diverge = Diverges::Always; | 131 | let mut both_arms_diverge = Diverges::Always; |
@@ -167,14 +173,15 @@ impl<'a> InferenceContext<'a> { | |||
167 | Expr::TryBlock { body } => { | 173 | Expr::TryBlock { body } => { |
168 | let _inner = self.infer_expr(*body, expected); | 174 | let _inner = self.infer_expr(*body, expected); |
169 | // FIXME should be std::result::Result<{inner}, _> | 175 | // FIXME should be std::result::Result<{inner}, _> |
170 | Ty::Unknown | 176 | self.err_ty() |
171 | } | 177 | } |
172 | Expr::Async { body } => { | 178 | Expr::Async { body } => { |
173 | // Use the first type parameter as the output type of future. | 179 | // Use the first type parameter as the output type of future. |
174 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 180 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
175 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 181 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
176 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 182 | let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body); |
177 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) | 183 | let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); |
184 | TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner) | ||
178 | } | 185 | } |
179 | Expr::Loop { body, label } => { | 186 | Expr::Loop { body, label } => { |
180 | self.breakables.push(BreakableContext { | 187 | self.breakables.push(BreakableContext { |
@@ -192,17 +199,20 @@ impl<'a> InferenceContext<'a> { | |||
192 | if ctxt.may_break { | 199 | if ctxt.may_break { |
193 | ctxt.break_ty | 200 | ctxt.break_ty |
194 | } else { | 201 | } else { |
195 | Ty::Never | 202 | TyKind::Never.intern(&Interner) |
196 | } | 203 | } |
197 | } | 204 | } |
198 | Expr::While { condition, body, label } => { | 205 | Expr::While { condition, body, label } => { |
199 | self.breakables.push(BreakableContext { | 206 | self.breakables.push(BreakableContext { |
200 | may_break: false, | 207 | may_break: false, |
201 | break_ty: Ty::Unknown, | 208 | break_ty: self.err_ty(), |
202 | label: label.map(|label| self.body[label].name.clone()), | 209 | label: label.map(|label| self.body[label].name.clone()), |
203 | }); | 210 | }); |
204 | // while let is desugared to a match loop, so this is always simple while | 211 | // while let is desugared to a match loop, so this is always simple while |
205 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); | 212 | self.infer_expr( |
213 | *condition, | ||
214 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), | ||
215 | ); | ||
206 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 216 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
207 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 217 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
208 | // the body may not run, so it diverging doesn't mean we diverge | 218 | // the body may not run, so it diverging doesn't mean we diverge |
@@ -214,7 +224,7 @@ impl<'a> InferenceContext<'a> { | |||
214 | 224 | ||
215 | self.breakables.push(BreakableContext { | 225 | self.breakables.push(BreakableContext { |
216 | may_break: false, | 226 | may_break: false, |
217 | break_ty: Ty::Unknown, | 227 | break_ty: self.err_ty(), |
218 | label: label.map(|label| self.body[label].name.clone()), | 228 | label: label.map(|label| self.body[label].name.clone()), |
219 | }); | 229 | }); |
220 | let pat_ty = | 230 | let pat_ty = |
@@ -249,12 +259,15 @@ impl<'a> InferenceContext<'a> { | |||
249 | None => self.table.new_type_var(), | 259 | None => self.table.new_type_var(), |
250 | }; | 260 | }; |
251 | sig_tys.push(ret_ty.clone()); | 261 | sig_tys.push(ret_ty.clone()); |
252 | let sig_ty = Ty::Function(FnPointer { | 262 | let sig_ty = TyKind::Function(FnPointer { |
253 | num_args: sig_tys.len() - 1, | 263 | num_args: sig_tys.len() - 1, |
254 | sig: FnSig { variadic: false }, | 264 | sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false }, |
255 | substs: Substs(sig_tys.clone().into()), | 265 | substs: Substs(sig_tys.clone().into()), |
256 | }); | 266 | }) |
257 | let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); | 267 | .intern(&Interner); |
268 | let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into(); | ||
269 | let closure_ty = | ||
270 | TyKind::Closure(closure_id, Substs::single(sig_ty)).intern(&Interner); | ||
258 | 271 | ||
259 | // Eagerly try to relate the closure type with the expected | 272 | // Eagerly try to relate the closure type with the expected |
260 | // type, otherwise we often won't have enough information to | 273 | // type, otherwise we often won't have enough information to |
@@ -295,7 +308,7 @@ impl<'a> InferenceContext<'a> { | |||
295 | args.len(), | 308 | args.len(), |
296 | ) | 309 | ) |
297 | }) | 310 | }) |
298 | .unwrap_or((Vec::new(), Ty::Unknown)); | 311 | .unwrap_or((Vec::new(), self.err_ty())); |
299 | self.register_obligations_for_call(&callee_ty); | 312 | self.register_obligations_for_call(&callee_ty); |
300 | self.check_call_arguments(args, ¶m_tys); | 313 | self.check_call_arguments(args, ¶m_tys); |
301 | self.normalize_associated_types_in(ret_ty) | 314 | self.normalize_associated_types_in(ret_ty) |
@@ -305,8 +318,11 @@ impl<'a> InferenceContext<'a> { | |||
305 | Expr::Match { expr, arms } => { | 318 | Expr::Match { expr, arms } => { |
306 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 319 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
307 | 320 | ||
308 | let mut result_ty = | 321 | let mut result_ty = if arms.is_empty() { |
309 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; | 322 | TyKind::Never.intern(&Interner) |
323 | } else { | ||
324 | self.table.new_type_var() | ||
325 | }; | ||
310 | 326 | ||
311 | let matchee_diverges = self.diverges; | 327 | let matchee_diverges = self.diverges; |
312 | let mut all_arms_diverge = Diverges::Always; | 328 | let mut all_arms_diverge = Diverges::Always; |
@@ -317,7 +333,7 @@ impl<'a> InferenceContext<'a> { | |||
317 | if let Some(guard_expr) = arm.guard { | 333 | if let Some(guard_expr) = arm.guard { |
318 | self.infer_expr( | 334 | self.infer_expr( |
319 | guard_expr, | 335 | guard_expr, |
320 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 336 | &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)), |
321 | ); | 337 | ); |
322 | } | 338 | } |
323 | 339 | ||
@@ -333,9 +349,9 @@ impl<'a> InferenceContext<'a> { | |||
333 | Expr::Path(p) => { | 349 | Expr::Path(p) => { |
334 | // FIXME this could be more efficient... | 350 | // FIXME this could be more efficient... |
335 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); | 351 | let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); |
336 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) | 352 | self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty()) |
337 | } | 353 | } |
338 | Expr::Continue { .. } => Ty::Never, | 354 | Expr::Continue { .. } => TyKind::Never.intern(&Interner), |
339 | Expr::Break { expr, label } => { | 355 | Expr::Break { expr, label } => { |
340 | let val_ty = if let Some(expr) = expr { | 356 | let val_ty = if let Some(expr) = expr { |
341 | self.infer_expr(*expr, &Expectation::none()) | 357 | self.infer_expr(*expr, &Expectation::none()) |
@@ -347,7 +363,7 @@ impl<'a> InferenceContext<'a> { | |||
347 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { | 363 | if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { |
348 | ctxt.break_ty.clone() | 364 | ctxt.break_ty.clone() |
349 | } else { | 365 | } else { |
350 | Ty::Unknown | 366 | self.err_ty() |
351 | }; | 367 | }; |
352 | 368 | ||
353 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); | 369 | let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); |
@@ -360,7 +376,7 @@ impl<'a> InferenceContext<'a> { | |||
360 | expr: tgt_expr, | 376 | expr: tgt_expr, |
361 | }); | 377 | }); |
362 | } | 378 | } |
363 | Ty::Never | 379 | TyKind::Never.intern(&Interner) |
364 | } | 380 | } |
365 | Expr::Return { expr } => { | 381 | Expr::Return { expr } => { |
366 | if let Some(expr) = expr { | 382 | if let Some(expr) = expr { |
@@ -369,14 +385,14 @@ impl<'a> InferenceContext<'a> { | |||
369 | let unit = Ty::unit(); | 385 | let unit = Ty::unit(); |
370 | self.coerce(&unit, &self.return_ty.clone()); | 386 | self.coerce(&unit, &self.return_ty.clone()); |
371 | } | 387 | } |
372 | Ty::Never | 388 | TyKind::Never.intern(&Interner) |
373 | } | 389 | } |
374 | Expr::Yield { expr } => { | 390 | Expr::Yield { expr } => { |
375 | // FIXME: track yield type for coercion | 391 | // FIXME: track yield type for coercion |
376 | if let Some(expr) = expr { | 392 | if let Some(expr) = expr { |
377 | self.infer_expr(*expr, &Expectation::none()); | 393 | self.infer_expr(*expr, &Expectation::none()); |
378 | } | 394 | } |
379 | Ty::Never | 395 | TyKind::Never.intern(&Interner) |
380 | } | 396 | } |
381 | Expr::RecordLit { path, fields, spread } => { | 397 | Expr::RecordLit { path, fields, spread } => { |
382 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 398 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -389,14 +405,13 @@ impl<'a> InferenceContext<'a> { | |||
389 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); | 405 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
390 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 406 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
391 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 407 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
392 | for (field_idx, field) in fields.iter().enumerate() { | 408 | for field in fields.iter() { |
393 | let field_def = | 409 | let field_def = |
394 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { | 410 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { |
395 | Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), | 411 | Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), |
396 | None => { | 412 | None => { |
397 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { | 413 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { |
398 | expr: tgt_expr, | 414 | expr: field.expr, |
399 | field: field_idx, | ||
400 | }); | 415 | }); |
401 | None | 416 | None |
402 | } | 417 | } |
@@ -404,8 +419,9 @@ impl<'a> InferenceContext<'a> { | |||
404 | if let Some(field_def) = field_def { | 419 | if let Some(field_def) = field_def { |
405 | self.result.record_field_resolutions.insert(field.expr, field_def); | 420 | self.result.record_field_resolutions.insert(field.expr, field_def); |
406 | } | 421 | } |
407 | let field_ty = field_def | 422 | let field_ty = field_def.map_or(self.err_ty(), |it| { |
408 | .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); | 423 | field_types[it.local_id].clone().subst(&substs) |
424 | }); | ||
409 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 425 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
410 | } | 426 | } |
411 | if let Some(expr) = spread { | 427 | if let Some(expr) = spread { |
@@ -424,27 +440,33 @@ impl<'a> InferenceContext<'a> { | |||
424 | environment: self.trait_env.clone(), | 440 | environment: self.trait_env.clone(), |
425 | }, | 441 | }, |
426 | ) | 442 | ) |
427 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 443 | .find_map(|derefed_ty| { |
428 | Ty::Tuple(_, substs) => { | 444 | match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) { |
429 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) | 445 | TyKind::Tuple(_, substs) => { |
430 | } | 446 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
431 | Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 447 | } |
432 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 448 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
433 | let field = FieldId { parent: s.into(), local_id }; | 449 | self.db.struct_data(*s).variant_data.field(name).map(|local_id| { |
434 | self.write_field_resolution(tgt_expr, field); | 450 | let field = FieldId { parent: (*s).into(), local_id }; |
435 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) | 451 | self.write_field_resolution(tgt_expr, field); |
436 | }) | 452 | self.db.field_types((*s).into())[field.local_id] |
437 | } | 453 | .clone() |
438 | Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { | 454 | .subst(¶meters) |
439 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 455 | }) |
440 | let field = FieldId { parent: u.into(), local_id }; | 456 | } |
441 | self.write_field_resolution(tgt_expr, field); | 457 | TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { |
442 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) | 458 | self.db.union_data(*u).variant_data.field(name).map(|local_id| { |
443 | }) | 459 | let field = FieldId { parent: (*u).into(), local_id }; |
460 | self.write_field_resolution(tgt_expr, field); | ||
461 | self.db.field_types((*u).into())[field.local_id] | ||
462 | .clone() | ||
463 | .subst(¶meters) | ||
464 | }) | ||
465 | } | ||
466 | _ => None, | ||
444 | } | 467 | } |
445 | _ => None, | ||
446 | }) | 468 | }) |
447 | .unwrap_or(Ty::Unknown); | 469 | .unwrap_or(self.err_ty()); |
448 | let ty = self.insert_type_vars(ty); | 470 | let ty = self.insert_type_vars(ty); |
449 | self.normalize_associated_types_in(ty) | 471 | self.normalize_associated_types_in(ty) |
450 | } | 472 | } |
@@ -481,9 +503,10 @@ impl<'a> InferenceContext<'a> { | |||
481 | }; | 503 | }; |
482 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 504 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
483 | match rawness { | 505 | match rawness { |
484 | Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), | 506 | Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), |
485 | Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), | 507 | Rawness::Ref => TyKind::Ref(mutability, inner_ty), |
486 | } | 508 | } |
509 | .intern(&Interner) | ||
487 | } | 510 | } |
488 | Expr::Box { expr } => { | 511 | Expr::Box { expr } => { |
489 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 512 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
@@ -499,7 +522,7 @@ impl<'a> InferenceContext<'a> { | |||
499 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 522 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
500 | Ty::adt_ty(box_, sb.build()) | 523 | Ty::adt_ty(box_, sb.build()) |
501 | } else { | 524 | } else { |
502 | Ty::Unknown | 525 | self.err_ty() |
503 | } | 526 | } |
504 | } | 527 | } |
505 | Expr::UnaryOp { expr, op } => { | 528 | Expr::UnaryOp { expr, op } => { |
@@ -519,31 +542,31 @@ impl<'a> InferenceContext<'a> { | |||
519 | Some(derefed_ty) => { | 542 | Some(derefed_ty) => { |
520 | canonicalized.decanonicalize_ty(derefed_ty.value) | 543 | canonicalized.decanonicalize_ty(derefed_ty.value) |
521 | } | 544 | } |
522 | None => Ty::Unknown, | 545 | None => self.err_ty(), |
523 | } | 546 | } |
524 | } | 547 | } |
525 | None => Ty::Unknown, | 548 | None => self.err_ty(), |
526 | }, | 549 | }, |
527 | UnaryOp::Neg => { | 550 | UnaryOp::Neg => { |
528 | match &inner_ty { | 551 | match inner_ty.interned(&Interner) { |
529 | // Fast path for builtins | 552 | // Fast path for builtins |
530 | Ty::Scalar(Scalar::Int(_)) | 553 | TyKind::Scalar(Scalar::Int(_)) |
531 | | Ty::Scalar(Scalar::Uint(_)) | 554 | | TyKind::Scalar(Scalar::Uint(_)) |
532 | | Ty::Scalar(Scalar::Float(_)) | 555 | | TyKind::Scalar(Scalar::Float(_)) |
533 | | Ty::InferenceVar(_, TyVariableKind::Integer) | 556 | | TyKind::InferenceVar(_, TyVariableKind::Integer) |
534 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, | 557 | | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
535 | // Otherwise we resolve via the std::ops::Neg trait | 558 | // Otherwise we resolve via the std::ops::Neg trait |
536 | _ => self | 559 | _ => self |
537 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 560 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
538 | } | 561 | } |
539 | } | 562 | } |
540 | UnaryOp::Not => { | 563 | UnaryOp::Not => { |
541 | match &inner_ty { | 564 | match inner_ty.interned(&Interner) { |
542 | // Fast path for builtins | 565 | // Fast path for builtins |
543 | Ty::Scalar(Scalar::Bool) | 566 | TyKind::Scalar(Scalar::Bool) |
544 | | Ty::Scalar(Scalar::Int(_)) | 567 | | TyKind::Scalar(Scalar::Int(_)) |
545 | | Ty::Scalar(Scalar::Uint(_)) | 568 | | TyKind::Scalar(Scalar::Uint(_)) |
546 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | 569 | | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty, |
547 | // Otherwise we resolve via the std::ops::Not trait | 570 | // Otherwise we resolve via the std::ops::Not trait |
548 | _ => self | 571 | _ => self |
549 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 572 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -554,7 +577,9 @@ impl<'a> InferenceContext<'a> { | |||
554 | Expr::BinaryOp { lhs, rhs, op } => match op { | 577 | Expr::BinaryOp { lhs, rhs, op } => match op { |
555 | Some(op) => { | 578 | Some(op) => { |
556 | let lhs_expectation = match op { | 579 | let lhs_expectation = match op { |
557 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), | 580 | BinaryOp::LogicOp(..) => { |
581 | Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)) | ||
582 | } | ||
558 | _ => Expectation::none(), | 583 | _ => Expectation::none(), |
559 | }; | 584 | }; |
560 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 585 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -563,7 +588,7 @@ impl<'a> InferenceContext<'a> { | |||
563 | 588 | ||
564 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); | 589 | let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); |
565 | 590 | ||
566 | if ret == Ty::Unknown { | 591 | if ret.is_unknown() { |
567 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); | 592 | cov_mark::hit!(infer_expr_inner_binary_operator_overload); |
568 | 593 | ||
569 | self.resolve_associated_type_with_params( | 594 | self.resolve_associated_type_with_params( |
@@ -575,7 +600,7 @@ impl<'a> InferenceContext<'a> { | |||
575 | ret | 600 | ret |
576 | } | 601 | } |
577 | } | 602 | } |
578 | _ => Ty::Unknown, | 603 | _ => self.err_ty(), |
579 | }, | 604 | }, |
580 | Expr::Range { lhs, rhs, range_type } => { | 605 | Expr::Range { lhs, rhs, range_type } => { |
581 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); | 606 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); |
@@ -586,33 +611,33 @@ impl<'a> InferenceContext<'a> { | |||
586 | match (range_type, lhs_ty, rhs_ty) { | 611 | match (range_type, lhs_ty, rhs_ty) { |
587 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 612 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
588 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), | 613 | Some(adt) => Ty::adt_ty(adt, Substs::empty()), |
589 | None => Ty::Unknown, | 614 | None => self.err_ty(), |
590 | }, | 615 | }, |
591 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 616 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
592 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 617 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
593 | None => Ty::Unknown, | 618 | None => self.err_ty(), |
594 | }, | 619 | }, |
595 | (RangeOp::Inclusive, None, Some(ty)) => { | 620 | (RangeOp::Inclusive, None, Some(ty)) => { |
596 | match self.resolve_range_to_inclusive() { | 621 | match self.resolve_range_to_inclusive() { |
597 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 622 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
598 | None => Ty::Unknown, | 623 | None => self.err_ty(), |
599 | } | 624 | } |
600 | } | 625 | } |
601 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 626 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
602 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 627 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
603 | None => Ty::Unknown, | 628 | None => self.err_ty(), |
604 | }, | 629 | }, |
605 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 630 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
606 | match self.resolve_range_inclusive() { | 631 | match self.resolve_range_inclusive() { |
607 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 632 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
608 | None => Ty::Unknown, | 633 | None => self.err_ty(), |
609 | } | 634 | } |
610 | } | 635 | } |
611 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 636 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
612 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), | 637 | Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), |
613 | None => Ty::Unknown, | 638 | None => self.err_ty(), |
614 | }, | 639 | }, |
615 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 640 | (RangeOp::Inclusive, _, None) => self.err_ty(), |
616 | } | 641 | } |
617 | } | 642 | } |
618 | Expr::Index { base, index } => { | 643 | Expr::Index { base, index } => { |
@@ -631,19 +656,19 @@ impl<'a> InferenceContext<'a> { | |||
631 | index_trait, | 656 | index_trait, |
632 | ); | 657 | ); |
633 | let self_ty = | 658 | let self_ty = |
634 | self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value)); | 659 | self_ty.map_or(self.err_ty(), |t| canonicalized.decanonicalize_ty(t.value)); |
635 | self.resolve_associated_type_with_params( | 660 | self.resolve_associated_type_with_params( |
636 | self_ty, | 661 | self_ty, |
637 | self.resolve_ops_index_output(), | 662 | self.resolve_ops_index_output(), |
638 | &[index_ty], | 663 | &[index_ty], |
639 | ) | 664 | ) |
640 | } else { | 665 | } else { |
641 | Ty::Unknown | 666 | self.err_ty() |
642 | } | 667 | } |
643 | } | 668 | } |
644 | Expr::Tuple { exprs } => { | 669 | Expr::Tuple { exprs } => { |
645 | let mut tys = match &expected.ty { | 670 | let mut tys = match expected.ty.interned(&Interner) { |
646 | Ty::Tuple(_, substs) => substs | 671 | TyKind::Tuple(_, substs) => substs |
647 | .iter() | 672 | .iter() |
648 | .cloned() | 673 | .cloned() |
649 | .chain(repeat_with(|| self.table.new_type_var())) | 674 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -656,11 +681,11 @@ impl<'a> InferenceContext<'a> { | |||
656 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 681 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
657 | } | 682 | } |
658 | 683 | ||
659 | Ty::Tuple(tys.len(), Substs(tys.into())) | 684 | TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner) |
660 | } | 685 | } |
661 | Expr::Array(array) => { | 686 | Expr::Array(array) => { |
662 | let elem_ty = match &expected.ty { | 687 | let elem_ty = match expected.ty.interned(&Interner) { |
663 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), | 688 | TyKind::Array(st) | TyKind::Slice(st) => st.clone(), |
664 | _ => self.table.new_type_var(), | 689 | _ => self.table.new_type_var(), |
665 | }; | 690 | }; |
666 | 691 | ||
@@ -677,43 +702,50 @@ impl<'a> InferenceContext<'a> { | |||
677 | ); | 702 | ); |
678 | self.infer_expr( | 703 | self.infer_expr( |
679 | *repeat, | 704 | *repeat, |
680 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), | 705 | &Expectation::has_type( |
706 | TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), | ||
707 | ), | ||
681 | ); | 708 | ); |
682 | } | 709 | } |
683 | } | 710 | } |
684 | 711 | ||
685 | Ty::Array(Substs::single(elem_ty)) | 712 | TyKind::Array(elem_ty).intern(&Interner) |
686 | } | 713 | } |
687 | Expr::Literal(lit) => match lit { | 714 | Expr::Literal(lit) => match lit { |
688 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), | 715 | Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
689 | Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), | 716 | Literal::String(..) => { |
717 | TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) | ||
718 | } | ||
690 | Literal::ByteString(..) => { | 719 | Literal::ByteString(..) => { |
691 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); | 720 | let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); |
692 | let array_type = Ty::Array(Substs::single(byte_type)); | 721 | let array_type = TyKind::Array(byte_type).intern(&Interner); |
693 | Ty::Ref(Mutability::Not, Substs::single(array_type)) | 722 | TyKind::Ref(Mutability::Not, array_type).intern(&Interner) |
694 | } | 723 | } |
695 | Literal::Char(..) => Ty::Scalar(Scalar::Char), | 724 | Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), |
696 | Literal::Int(_v, ty) => match ty { | 725 | Literal::Int(_v, ty) => match ty { |
697 | Some(int_ty) => { | 726 | Some(int_ty) => { |
698 | Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) | 727 | TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) |
728 | .intern(&Interner) | ||
699 | } | 729 | } |
700 | None => self.table.new_integer_var(), | 730 | None => self.table.new_integer_var(), |
701 | }, | 731 | }, |
702 | Literal::Uint(_v, ty) => match ty { | 732 | Literal::Uint(_v, ty) => match ty { |
703 | Some(int_ty) => { | 733 | Some(int_ty) => { |
704 | Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) | 734 | TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) |
735 | .intern(&Interner) | ||
705 | } | 736 | } |
706 | None => self.table.new_integer_var(), | 737 | None => self.table.new_integer_var(), |
707 | }, | 738 | }, |
708 | Literal::Float(_v, ty) => match ty { | 739 | Literal::Float(_v, ty) => match ty { |
709 | Some(float_ty) => { | 740 | Some(float_ty) => { |
710 | Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) | 741 | TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) |
742 | .intern(&Interner) | ||
711 | } | 743 | } |
712 | None => self.table.new_float_var(), | 744 | None => self.table.new_float_var(), |
713 | }, | 745 | }, |
714 | }, | 746 | }, |
715 | }; | 747 | }; |
716 | // use a new type variable if we got Ty::Unknown here | 748 | // use a new type variable if we got unknown here |
717 | let ty = self.insert_type_vars_shallow(ty); | 749 | let ty = self.insert_type_vars_shallow(ty); |
718 | let ty = self.resolve_ty_as_possible(ty); | 750 | let ty = self.resolve_ty_as_possible(ty); |
719 | self.write_expr_ty(tgt_expr, ty.clone()); | 751 | self.write_expr_ty(tgt_expr, ty.clone()); |
@@ -730,7 +762,7 @@ impl<'a> InferenceContext<'a> { | |||
730 | match stmt { | 762 | match stmt { |
731 | Statement::Let { pat, type_ref, initializer } => { | 763 | Statement::Let { pat, type_ref, initializer } => { |
732 | let decl_ty = | 764 | let decl_ty = |
733 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); | 765 | type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty()); |
734 | 766 | ||
735 | // Always use the declared type when specified | 767 | // Always use the declared type when specified |
736 | let mut ty = decl_ty.clone(); | 768 | let mut ty = decl_ty.clone(); |
@@ -738,7 +770,7 @@ impl<'a> InferenceContext<'a> { | |||
738 | if let Some(expr) = initializer { | 770 | if let Some(expr) = initializer { |
739 | let actual_ty = | 771 | let actual_ty = |
740 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); | 772 | self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); |
741 | if decl_ty == Ty::Unknown { | 773 | if decl_ty.is_unknown() { |
742 | ty = actual_ty; | 774 | ty = actual_ty; |
743 | } | 775 | } |
744 | } | 776 | } |
@@ -766,7 +798,7 @@ impl<'a> InferenceContext<'a> { | |||
766 | // we don't even make an attempt at coercion | 798 | // we don't even make an attempt at coercion |
767 | self.table.new_maybe_never_var() | 799 | self.table.new_maybe_never_var() |
768 | } else { | 800 | } else { |
769 | self.coerce(&Ty::unit(), expected.coercion_target()); | 801 | self.coerce(&Ty::unit(), &expected.coercion_target()); |
770 | Ty::unit() | 802 | Ty::unit() |
771 | } | 803 | } |
772 | }; | 804 | }; |
@@ -802,7 +834,7 @@ impl<'a> InferenceContext<'a> { | |||
802 | self.write_method_resolution(tgt_expr, func); | 834 | self.write_method_resolution(tgt_expr, func); |
803 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) | 835 | (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) |
804 | } | 836 | } |
805 | None => (receiver_ty, Binders::new(0, Ty::Unknown), None), | 837 | None => (receiver_ty, Binders::new(0, self.err_ty()), None), |
806 | }; | 838 | }; |
807 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); | 839 | let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); |
808 | let method_ty = method_ty.subst(&substs); | 840 | let method_ty = method_ty.subst(&substs); |
@@ -813,15 +845,15 @@ impl<'a> InferenceContext<'a> { | |||
813 | if !sig.params().is_empty() { | 845 | if !sig.params().is_empty() { |
814 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) | 846 | (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) |
815 | } else { | 847 | } else { |
816 | (Ty::Unknown, Vec::new(), sig.ret().clone()) | 848 | (self.err_ty(), Vec::new(), sig.ret().clone()) |
817 | } | 849 | } |
818 | } | 850 | } |
819 | None => (Ty::Unknown, Vec::new(), Ty::Unknown), | 851 | None => (self.err_ty(), Vec::new(), self.err_ty()), |
820 | }; | 852 | }; |
821 | // Apply autoref so the below unification works correctly | 853 | // Apply autoref so the below unification works correctly |
822 | // FIXME: return correct autorefs from lookup_method | 854 | // FIXME: return correct autorefs from lookup_method |
823 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 855 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
824 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), | 856 | Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), |
825 | _ => derefed_receiver_ty, | 857 | _ => derefed_receiver_ty, |
826 | }; | 858 | }; |
827 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 859 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -837,7 +869,7 @@ impl<'a> InferenceContext<'a> { | |||
837 | // that we have more information about the types of arguments when we | 869 | // that we have more information about the types of arguments when we |
838 | // type-check the functions. This isn't really the right way to do this. | 870 | // type-check the functions. This isn't really the right way to do this. |
839 | for &check_closures in &[false, true] { | 871 | for &check_closures in &[false, true] { |
840 | let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown)); | 872 | let param_iter = param_tys.iter().cloned().chain(repeat(self.err_ty())); |
841 | for (&arg, param_ty) in args.iter().zip(param_iter) { | 873 | for (&arg, param_ty) in args.iter().zip(param_iter) { |
842 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); | 874 | let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); |
843 | if is_closure != check_closures { | 875 | if is_closure != check_closures { |
@@ -867,7 +899,7 @@ impl<'a> InferenceContext<'a> { | |||
867 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { | 899 | if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { |
868 | substs.push(receiver_ty.clone()); | 900 | substs.push(receiver_ty.clone()); |
869 | } else { | 901 | } else { |
870 | substs.push(Ty::Unknown); | 902 | substs.push(self.err_ty()); |
871 | } | 903 | } |
872 | } | 904 | } |
873 | } | 905 | } |
@@ -891,14 +923,15 @@ impl<'a> InferenceContext<'a> { | |||
891 | }; | 923 | }; |
892 | let supplied_params = substs.len(); | 924 | let supplied_params = substs.len(); |
893 | for _ in supplied_params..total_len { | 925 | for _ in supplied_params..total_len { |
894 | substs.push(Ty::Unknown); | 926 | substs.push(self.err_ty()); |
895 | } | 927 | } |
896 | assert_eq!(substs.len(), total_len); | 928 | assert_eq!(substs.len(), total_len); |
897 | Substs(substs.into()) | 929 | Substs(substs.into()) |
898 | } | 930 | } |
899 | 931 | ||
900 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 932 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
901 | if let &Ty::FnDef(def, ref parameters) = callable_ty { | 933 | if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) { |
934 | let def: CallableDefId = from_chalk(self.db, *fn_def); | ||
902 | let generic_predicates = self.db.generic_predicates(def.into()); | 935 | let generic_predicates = self.db.generic_predicates(def.into()); |
903 | for predicate in generic_predicates.iter() { | 936 | for predicate in generic_predicates.iter() { |
904 | let predicate = predicate.clone().subst(parameters); | 937 | let predicate = predicate.clone().subst(parameters); |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index a0ac8d80f..9e8ca18ef 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -12,7 +12,7 @@ use hir_def::{ | |||
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | 13 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty}; | 15 | use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substs, Ty, TyKind}; |
16 | 16 | ||
17 | impl<'a> InferenceContext<'a> { | 17 | impl<'a> InferenceContext<'a> { |
18 | fn infer_tuple_struct_pat( | 18 | fn infer_tuple_struct_pat( |
@@ -46,7 +46,7 @@ impl<'a> InferenceContext<'a> { | |||
46 | let expected_ty = var_data | 46 | let expected_ty = var_data |
47 | .as_ref() | 47 | .as_ref() |
48 | .and_then(|d| d.field(&Name::new_tuple_field(i))) | 48 | .and_then(|d| d.field(&Name::new_tuple_field(i))) |
49 | .map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); | 49 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); |
50 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 50 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
51 | self.infer_pat(subpat, &expected_ty, default_bm); | 51 | self.infer_pat(subpat, &expected_ty, default_bm); |
52 | } | 52 | } |
@@ -80,8 +80,8 @@ impl<'a> InferenceContext<'a> { | |||
80 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); | 80 | self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); |
81 | } | 81 | } |
82 | 82 | ||
83 | let expected_ty = | 83 | let expected_ty = matching_field |
84 | matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); | 84 | .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs)); |
85 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 85 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
86 | self.infer_pat(subpat.pat, &expected_ty, default_bm); | 86 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
87 | } | 87 | } |
@@ -129,7 +129,8 @@ impl<'a> InferenceContext<'a> { | |||
129 | None => (&args[..], &[][..]), | 129 | None => (&args[..], &[][..]), |
130 | }; | 130 | }; |
131 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); | 131 | let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); |
132 | let mut expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); | 132 | let err_ty = self.err_ty(); |
133 | let mut expectations_iter = expectations.iter().chain(repeat(&err_ty)); | ||
133 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); | 134 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); |
134 | 135 | ||
135 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); | 136 | let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); |
@@ -137,7 +138,7 @@ impl<'a> InferenceContext<'a> { | |||
137 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); | 138 | inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); |
138 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); | 139 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); |
139 | 140 | ||
140 | Ty::Tuple(inner_tys.len(), Substs(inner_tys.into())) | 141 | TyKind::Tuple(inner_tys.len(), Substs(inner_tys.into())).intern(&Interner) |
141 | } | 142 | } |
142 | Pat::Or(ref pats) => { | 143 | Pat::Or(ref pats) => { |
143 | if let Some((first_pat, rest)) = pats.split_first() { | 144 | if let Some((first_pat, rest)) = pats.split_first() { |
@@ -147,7 +148,7 @@ impl<'a> InferenceContext<'a> { | |||
147 | } | 148 | } |
148 | ty | 149 | ty |
149 | } else { | 150 | } else { |
150 | Ty::Unknown | 151 | self.err_ty() |
151 | } | 152 | } |
152 | } | 153 | } |
153 | Pat::Ref { pat, mutability } => { | 154 | Pat::Ref { pat, mutability } => { |
@@ -157,12 +158,12 @@ impl<'a> InferenceContext<'a> { | |||
157 | if mutability != exp_mut { | 158 | if mutability != exp_mut { |
158 | // FIXME: emit type error? | 159 | // FIXME: emit type error? |
159 | } | 160 | } |
160 | inner_ty | 161 | inner_ty.clone() |
161 | } | 162 | } |
162 | _ => &Ty::Unknown, | 163 | _ => self.result.standard_types.unknown.clone(), |
163 | }; | 164 | }; |
164 | let subty = self.infer_pat(*pat, expectation, default_bm); | 165 | let subty = self.infer_pat(*pat, &expectation, default_bm); |
165 | Ty::Ref(mutability, Substs::single(subty)) | 166 | TyKind::Ref(mutability, subty).intern(&Interner) |
166 | } | 167 | } |
167 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( | 168 | Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( |
168 | p.as_ref(), | 169 | p.as_ref(), |
@@ -178,7 +179,7 @@ impl<'a> InferenceContext<'a> { | |||
178 | Pat::Path(path) => { | 179 | Pat::Path(path) => { |
179 | // FIXME use correct resolver for the surrounding expression | 180 | // FIXME use correct resolver for the surrounding expression |
180 | let resolver = self.resolver.clone(); | 181 | let resolver = self.resolver.clone(); |
181 | self.infer_path(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) | 182 | self.infer_path(&resolver, &path, pat.into()).unwrap_or(self.err_ty()) |
182 | } | 183 | } |
183 | Pat::Bind { mode, name: _, subpat } => { | 184 | Pat::Bind { mode, name: _, subpat } => { |
184 | let mode = if mode == &BindingAnnotation::Unannotated { | 185 | let mode = if mode == &BindingAnnotation::Unannotated { |
@@ -195,7 +196,7 @@ impl<'a> InferenceContext<'a> { | |||
195 | 196 | ||
196 | let bound_ty = match mode { | 197 | let bound_ty = match mode { |
197 | BindingMode::Ref(mutability) => { | 198 | BindingMode::Ref(mutability) => { |
198 | Ty::Ref(mutability, Substs::single(inner_ty.clone())) | 199 | TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) |
199 | } | 200 | } |
200 | BindingMode::Move => inner_ty.clone(), | 201 | BindingMode::Move => inner_ty.clone(), |
201 | }; | 202 | }; |
@@ -204,17 +205,17 @@ impl<'a> InferenceContext<'a> { | |||
204 | return inner_ty; | 205 | return inner_ty; |
205 | } | 206 | } |
206 | Pat::Slice { prefix, slice, suffix } => { | 207 | Pat::Slice { prefix, slice, suffix } => { |
207 | let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected { | 208 | let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { |
208 | Ty::Array(st) => (Ty::Array, st.as_single().clone()), | 209 | TyKind::Array(st) => (TyKind::Array, st.clone()), |
209 | Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), | 210 | TyKind::Slice(st) => (TyKind::Slice, st.clone()), |
210 | _ => (Ty::Slice, Ty::Unknown), | 211 | _ => (TyKind::Slice, self.err_ty()), |
211 | }; | 212 | }; |
212 | 213 | ||
213 | for pat_id in prefix.iter().chain(suffix) { | 214 | for pat_id in prefix.iter().chain(suffix) { |
214 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 215 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
215 | } | 216 | } |
216 | 217 | ||
217 | let pat_ty = container_ty(Substs::single(elem_ty)); | 218 | let pat_ty = container_ty(elem_ty).intern(&Interner); |
218 | if let Some(slice_pat_id) = slice { | 219 | if let Some(slice_pat_id) = slice { |
219 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | 220 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); |
220 | } | 221 | } |
@@ -231,21 +232,21 @@ impl<'a> InferenceContext<'a> { | |||
231 | Pat::Box { inner } => match self.resolve_boxed_box() { | 232 | Pat::Box { inner } => match self.resolve_boxed_box() { |
232 | Some(box_adt) => { | 233 | Some(box_adt) => { |
233 | let inner_expected = match expected.as_adt() { | 234 | let inner_expected = match expected.as_adt() { |
234 | Some((adt, substs)) if adt == box_adt => substs.as_single(), | 235 | Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), |
235 | _ => &Ty::Unknown, | 236 | _ => self.result.standard_types.unknown.clone(), |
236 | }; | 237 | }; |
237 | 238 | ||
238 | let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); | 239 | let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); |
239 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) | 240 | Ty::adt_ty(box_adt, Substs::single(inner_ty)) |
240 | } | 241 | } |
241 | None => Ty::Unknown, | 242 | None => self.err_ty(), |
242 | }, | 243 | }, |
243 | Pat::ConstBlock(expr) => { | 244 | Pat::ConstBlock(expr) => { |
244 | self.infer_expr(*expr, &Expectation::has_type(expected.clone())) | 245 | self.infer_expr(*expr, &Expectation::has_type(expected.clone())) |
245 | } | 246 | } |
246 | Pat::Missing => Ty::Unknown, | 247 | Pat::Missing => self.err_ty(), |
247 | }; | 248 | }; |
248 | // use a new type variable if we got Ty::Unknown here | 249 | // use a new type variable if we got error type here |
249 | let ty = self.insert_type_vars_shallow(ty); | 250 | let ty = self.insert_type_vars_shallow(ty); |
250 | if !self.unify(&ty, expected) { | 251 | if !self.unify(&ty, expected) { |
251 | // FIXME record mismatch, we need to change the type of self.type_mismatches for that | 252 | // FIXME record mismatch, we need to change the type of self.type_mismatches for that |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index ae3554bac..af108fb6c 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -9,7 +9,7 @@ use hir_def::{ | |||
9 | }; | 9 | }; |
10 | use hir_expand::name::Name; | 10 | use hir_expand::name::Name; |
11 | 11 | ||
12 | use crate::{method_resolution, Substs, Ty, ValueTyDefId}; | 12 | use crate::{method_resolution, Interner, Substs, Ty, TyKind, ValueTyDefId}; |
13 | 13 | ||
14 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 14 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
15 | 15 | ||
@@ -40,7 +40,7 @@ impl<'a> InferenceContext<'a> { | |||
40 | let ty = self.make_ty(type_ref); | 40 | let ty = self.make_ty(type_ref); |
41 | let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); | 41 | let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); |
42 | let ctx = crate::lower::TyLoweringContext::new(self.db, &resolver); | 42 | let ctx = crate::lower::TyLoweringContext::new(self.db, &resolver); |
43 | let (ty, _) = Ty::from_type_relative_path(&ctx, ty, None, remaining_segments_for_ty); | 43 | let (ty, _) = ctx.lower_ty_relative_path(ty, None, remaining_segments_for_ty); |
44 | self.resolve_ty_assoc_item( | 44 | self.resolve_ty_assoc_item( |
45 | ty, | 45 | ty, |
46 | &path.segments().last().expect("path had at least one segment").name, | 46 | &path.segments().last().expect("path had at least one segment").name, |
@@ -79,7 +79,7 @@ impl<'a> InferenceContext<'a> { | |||
79 | } | 79 | } |
80 | ValueNs::ImplSelf(impl_id) => { | 80 | ValueNs::ImplSelf(impl_id) => { |
81 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 81 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
82 | let substs = Substs::type_params_for_generics(&generics); | 82 | let substs = Substs::type_params_for_generics(self.db, &generics); |
83 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); | 83 | let ty = self.db.impl_self_ty(impl_id).subst(&substs); |
84 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { | 84 | if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { |
85 | let ty = self.db.value_ty(struct_id.into()).subst(&substs); | 85 | let ty = self.db.value_ty(struct_id.into()).subst(&substs); |
@@ -96,7 +96,7 @@ impl<'a> InferenceContext<'a> { | |||
96 | // self_subst is just for the parent | 96 | // self_subst is just for the parent |
97 | let parent_substs = self_subst.unwrap_or_else(Substs::empty); | 97 | let parent_substs = self_subst.unwrap_or_else(Substs::empty); |
98 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); | 98 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
99 | let substs = Ty::substs_from_path(&ctx, path, typable, true); | 99 | let substs = ctx.substs_from_path(path, typable, true); |
100 | let full_substs = Substs::builder(substs.len()) | 100 | let full_substs = Substs::builder(substs.len()) |
101 | .use_parent_substs(&parent_substs) | 101 | .use_parent_substs(&parent_substs) |
102 | .fill(substs.0[parent_substs.len()..].iter().cloned()) | 102 | .fill(substs.0[parent_substs.len()..].iter().cloned()) |
@@ -126,7 +126,8 @@ impl<'a> InferenceContext<'a> { | |||
126 | let segment = | 126 | let segment = |
127 | remaining_segments.last().expect("there should be at least one segment here"); | 127 | remaining_segments.last().expect("there should be at least one segment here"); |
128 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); | 128 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
129 | let trait_ref = TraitRef::from_resolved_path(&ctx, trait_, resolved_segment, None); | 129 | let trait_ref = |
130 | ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None); | ||
130 | self.resolve_trait_assoc_item(trait_ref, segment, id) | 131 | self.resolve_trait_assoc_item(trait_ref, segment, id) |
131 | } | 132 | } |
132 | (def, _) => { | 133 | (def, _) => { |
@@ -137,14 +138,13 @@ impl<'a> InferenceContext<'a> { | |||
137 | let remaining_segments_for_ty = | 138 | let remaining_segments_for_ty = |
138 | remaining_segments.take(remaining_segments.len() - 1); | 139 | remaining_segments.take(remaining_segments.len() - 1); |
139 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); | 140 | let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); |
140 | let (ty, _) = Ty::from_partly_resolved_hir_path( | 141 | let (ty, _) = ctx.lower_partly_resolved_path( |
141 | &ctx, | ||
142 | def, | 142 | def, |
143 | resolved_segment, | 143 | resolved_segment, |
144 | remaining_segments_for_ty, | 144 | remaining_segments_for_ty, |
145 | true, | 145 | true, |
146 | ); | 146 | ); |
147 | if let Ty::Unknown = ty { | 147 | if let TyKind::Unknown = ty.interned(&Interner) { |
148 | return None; | 148 | return None; |
149 | } | 149 | } |
150 | 150 | ||
@@ -209,7 +209,7 @@ impl<'a> InferenceContext<'a> { | |||
209 | name: &Name, | 209 | name: &Name, |
210 | id: ExprOrPatId, | 210 | id: ExprOrPatId, |
211 | ) -> Option<(ValueNs, Option<Substs>)> { | 211 | ) -> Option<(ValueNs, Option<Substs>)> { |
212 | if let Ty::Unknown = ty { | 212 | if let TyKind::Unknown = ty.interned(&Interner) { |
213 | return None; | 213 | return None; |
214 | } | 214 | } |
215 | 215 | ||
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 54fcfed10..7795f446f 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | |||
7 | 7 | ||
8 | use super::{InferenceContext, Obligation}; | 8 | use super::{InferenceContext, Obligation}; |
9 | use crate::{ | 9 | use crate::{ |
10 | BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, | 10 | BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar, |
11 | Substs, Ty, TypeWalk, | 11 | Interner, Scalar, Substs, Ty, TyKind, TypeWalk, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | impl<'a> InferenceContext<'a> { | 14 | impl<'a> InferenceContext<'a> { |
@@ -49,8 +49,8 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
49 | 49 | ||
50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { | 50 | fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { |
51 | t.fold_binders( | 51 | t.fold_binders( |
52 | &mut |ty, binders| match ty { | 52 | &mut |ty, binders| match ty.interned(&Interner) { |
53 | Ty::InferenceVar(var, kind) => { | 53 | &TyKind::InferenceVar(var, kind) => { |
54 | let inner = var.to_inner(); | 54 | let inner = var.to_inner(); |
55 | if self.var_stack.contains(&inner) { | 55 | if self.var_stack.contains(&inner) { |
56 | // recursive type | 56 | // recursive type |
@@ -66,7 +66,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
66 | } else { | 66 | } else { |
67 | let root = self.ctx.table.var_unification_table.find(inner); | 67 | let root = self.ctx.table.var_unification_table.find(inner); |
68 | let position = self.add(InferenceVar::from_inner(root), kind); | 68 | let position = self.add(InferenceVar::from_inner(root), kind); |
69 | Ty::BoundVar(BoundVar::new(binders, position)) | 69 | TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) |
70 | } | 70 | } |
71 | } | 71 | } |
72 | _ => ty, | 72 | _ => ty, |
@@ -108,10 +108,10 @@ impl<T> Canonicalized<T> { | |||
108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { | 108 | pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { |
109 | ty.walk_mut_binders( | 109 | ty.walk_mut_binders( |
110 | &mut |ty, binders| { | 110 | &mut |ty, binders| { |
111 | if let &mut Ty::BoundVar(bound) = ty { | 111 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { |
112 | if bound.debruijn >= binders { | 112 | if bound.debruijn >= binders { |
113 | let (v, k) = self.free_vars[bound.index]; | 113 | let (v, k) = self.free_vars[bound.index]; |
114 | *ty = Ty::InferenceVar(v, k); | 114 | *ty = TyKind::InferenceVar(v, k).intern(&Interner); |
115 | } | 115 | } |
116 | } | 116 | } |
117 | }, | 117 | }, |
@@ -142,7 +142,7 @@ impl<T> Canonicalized<T> { | |||
142 | // eagerly replace projections in the type; we may be getting types | 142 | // eagerly replace projections in the type; we may be getting types |
143 | // e.g. from where clauses where this hasn't happened yet | 143 | // e.g. from where clauses where this hasn't happened yet |
144 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); | 144 | let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); |
145 | ctx.table.unify(&Ty::InferenceVar(v, k), &ty); | 145 | ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty); |
146 | } | 146 | } |
147 | } | 147 | } |
148 | } | 148 | } |
@@ -166,7 +166,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> { | |||
166 | // (kind of hacky) | 166 | // (kind of hacky) |
167 | for (i, var) in vars.iter().enumerate() { | 167 | for (i, var) in vars.iter().enumerate() { |
168 | if &*table.resolve_ty_shallow(var) == var { | 168 | if &*table.resolve_ty_shallow(var) == var { |
169 | table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i))); | 169 | table.unify( |
170 | var, | ||
171 | &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)).intern(&Interner), | ||
172 | ); | ||
170 | } | 173 | } |
171 | } | 174 | } |
172 | Some( | 175 | Some( |
@@ -196,11 +199,12 @@ impl TypeVariableTable { | |||
196 | 199 | ||
197 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { | 200 | fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { |
198 | match kind { | 201 | match kind { |
199 | _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never, | 202 | _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, |
200 | TyVariableKind::General => Ty::Unknown, | 203 | TyVariableKind::General => TyKind::Unknown, |
201 | TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)), | 204 | TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), |
202 | TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)), | 205 | TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), |
203 | } | 206 | } |
207 | .intern(&Interner) | ||
204 | } | 208 | } |
205 | } | 209 | } |
206 | 210 | ||
@@ -227,7 +231,7 @@ impl InferenceTable { | |||
227 | self.type_variable_table.push(TypeVariableData { diverging }); | 231 | self.type_variable_table.push(TypeVariableData { diverging }); |
228 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); | 232 | let key = self.var_unification_table.new_key(TypeVarValue::Unknown); |
229 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); | 233 | assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); |
230 | Ty::InferenceVar(InferenceVar::from_inner(key), kind) | 234 | TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) |
231 | } | 235 | } |
232 | 236 | ||
233 | pub(crate) fn new_type_var(&mut self) -> Ty { | 237 | pub(crate) fn new_type_var(&mut self) -> Ty { |
@@ -279,10 +283,24 @@ impl InferenceTable { | |||
279 | let ty1 = self.resolve_ty_shallow(ty1); | 283 | let ty1 = self.resolve_ty_shallow(ty1); |
280 | let ty2 = self.resolve_ty_shallow(ty2); | 284 | let ty2 = self.resolve_ty_shallow(ty2); |
281 | if ty1.equals_ctor(&ty2) { | 285 | if ty1.equals_ctor(&ty2) { |
282 | match (ty1.substs(), ty2.substs()) { | 286 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { |
283 | (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1), | 287 | (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) |
284 | (None, None) => true, | 288 | | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) |
285 | _ => false, | 289 | | ( |
290 | TyKind::Function(FnPointer { substs: substs1, .. }), | ||
291 | TyKind::Function(FnPointer { substs: substs2, .. }), | ||
292 | ) | ||
293 | | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) | ||
294 | | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) | ||
295 | | (TyKind::AssociatedType(_, substs1), TyKind::AssociatedType(_, substs2)) | ||
296 | | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { | ||
297 | self.unify_substs(substs1, substs2, depth + 1) | ||
298 | } | ||
299 | (TyKind::Ref(_, ty1), TyKind::Ref(_, ty2)) | ||
300 | | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) | ||
301 | | (TyKind::Array(ty1), TyKind::Array(ty2)) | ||
302 | | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), | ||
303 | _ => true, /* we checked equals_ctor already */ | ||
286 | } | 304 | } |
287 | } else { | 305 | } else { |
288 | self.unify_inner_trivial(&ty1, &ty2, depth) | 306 | self.unify_inner_trivial(&ty1, &ty2, depth) |
@@ -290,12 +308,12 @@ impl InferenceTable { | |||
290 | } | 308 | } |
291 | 309 | ||
292 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | 310 | pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { |
293 | match (ty1, ty2) { | 311 | match (ty1.interned(&Interner), ty2.interned(&Interner)) { |
294 | (Ty::Unknown, _) | (_, Ty::Unknown) => true, | 312 | (TyKind::Unknown, _) | (_, TyKind::Unknown) => true, |
295 | 313 | ||
296 | (Ty::Placeholder(p1), Ty::Placeholder(p2)) if *p1 == *p2 => true, | 314 | (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true, |
297 | 315 | ||
298 | (Ty::Dyn(dyn1), Ty::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { | 316 | (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { |
299 | for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { | 317 | for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { |
300 | if !self.unify_preds(pred1, pred2, depth + 1) { | 318 | if !self.unify_preds(pred1, pred2, depth + 1) { |
301 | return false; | 319 | return false; |
@@ -305,16 +323,16 @@ impl InferenceTable { | |||
305 | } | 323 | } |
306 | 324 | ||
307 | ( | 325 | ( |
308 | Ty::InferenceVar(tv1, TyVariableKind::General), | 326 | TyKind::InferenceVar(tv1, TyVariableKind::General), |
309 | Ty::InferenceVar(tv2, TyVariableKind::General), | 327 | TyKind::InferenceVar(tv2, TyVariableKind::General), |
310 | ) | 328 | ) |
311 | | ( | 329 | | ( |
312 | Ty::InferenceVar(tv1, TyVariableKind::Integer), | 330 | TyKind::InferenceVar(tv1, TyVariableKind::Integer), |
313 | Ty::InferenceVar(tv2, TyVariableKind::Integer), | 331 | TyKind::InferenceVar(tv2, TyVariableKind::Integer), |
314 | ) | 332 | ) |
315 | | ( | 333 | | ( |
316 | Ty::InferenceVar(tv1, TyVariableKind::Float), | 334 | TyKind::InferenceVar(tv1, TyVariableKind::Float), |
317 | Ty::InferenceVar(tv2, TyVariableKind::Float), | 335 | TyKind::InferenceVar(tv2, TyVariableKind::Float), |
318 | ) if self.type_variable_table.is_diverging(*tv1) | 336 | ) if self.type_variable_table.is_diverging(*tv1) |
319 | == self.type_variable_table.is_diverging(*tv2) => | 337 | == self.type_variable_table.is_diverging(*tv2) => |
320 | { | 338 | { |
@@ -326,24 +344,37 @@ impl InferenceTable { | |||
326 | // The order of MaybeNeverTypeVar matters here. | 344 | // The order of MaybeNeverTypeVar matters here. |
327 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. | 345 | // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. |
328 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. | 346 | // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. |
329 | (Ty::InferenceVar(tv, TyVariableKind::General), other) | 347 | (TyKind::InferenceVar(tv, TyVariableKind::General), other) |
330 | | (other, Ty::InferenceVar(tv, TyVariableKind::General)) | 348 | | (other, TyKind::InferenceVar(tv, TyVariableKind::General)) |
331 | | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_))) | ||
332 | | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer)) | ||
333 | | ( | 349 | | ( |
334 | Ty::InferenceVar(tv, TyVariableKind::Integer), | 350 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
335 | other @ Ty::Scalar(Scalar::Uint(_)), | 351 | other @ TyKind::Scalar(Scalar::Int(_)), |
336 | ) | 352 | ) |
337 | | ( | 353 | | ( |
338 | other @ Ty::Scalar(Scalar::Uint(_)), | 354 | other @ TyKind::Scalar(Scalar::Int(_)), |
339 | Ty::InferenceVar(tv, TyVariableKind::Integer), | 355 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
340 | ) | 356 | ) |
341 | | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) | 357 | | ( |
342 | | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => | 358 | TyKind::InferenceVar(tv, TyVariableKind::Integer), |
343 | { | 359 | other @ TyKind::Scalar(Scalar::Uint(_)), |
360 | ) | ||
361 | | ( | ||
362 | other @ TyKind::Scalar(Scalar::Uint(_)), | ||
363 | TyKind::InferenceVar(tv, TyVariableKind::Integer), | ||
364 | ) | ||
365 | | ( | ||
366 | TyKind::InferenceVar(tv, TyVariableKind::Float), | ||
367 | other @ TyKind::Scalar(Scalar::Float(_)), | ||
368 | ) | ||
369 | | ( | ||
370 | other @ TyKind::Scalar(Scalar::Float(_)), | ||
371 | TyKind::InferenceVar(tv, TyVariableKind::Float), | ||
372 | ) => { | ||
344 | // the type var is unknown since we tried to resolve it | 373 | // the type var is unknown since we tried to resolve it |
345 | self.var_unification_table | 374 | self.var_unification_table.union_value( |
346 | .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); | 375 | tv.to_inner(), |
376 | TypeVarValue::Known(other.clone().intern(&Interner)), | ||
377 | ); | ||
347 | true | 378 | true |
348 | } | 379 | } |
349 | 380 | ||
@@ -364,11 +395,11 @@ impl InferenceTable { | |||
364 | self.unify_substs(&tr1.substs, &tr2.substs, depth + 1) | 395 | self.unify_substs(&tr1.substs, &tr2.substs, depth + 1) |
365 | } | 396 | } |
366 | (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2)) | 397 | (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2)) |
367 | if proj1.projection_ty.associated_ty == proj2.projection_ty.associated_ty => | 398 | if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id => |
368 | { | 399 | { |
369 | self.unify_substs( | 400 | self.unify_substs( |
370 | &proj1.projection_ty.parameters, | 401 | &proj1.projection_ty.substitution, |
371 | &proj2.projection_ty.parameters, | 402 | &proj2.projection_ty.substitution, |
372 | depth + 1, | 403 | depth + 1, |
373 | ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1) | 404 | ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1) |
374 | } | 405 | } |
@@ -387,8 +418,8 @@ impl InferenceTable { | |||
387 | if i > 0 { | 418 | if i > 0 { |
388 | cov_mark::hit!(type_var_resolves_to_int_var); | 419 | cov_mark::hit!(type_var_resolves_to_int_var); |
389 | } | 420 | } |
390 | match &*ty { | 421 | match ty.interned(&Interner) { |
391 | Ty::InferenceVar(tv, _) => { | 422 | TyKind::InferenceVar(tv, _) => { |
392 | let inner = tv.to_inner(); | 423 | let inner = tv.to_inner(); |
393 | match self.var_unification_table.inlined_probe_value(inner).known() { | 424 | match self.var_unification_table.inlined_probe_value(inner).known() { |
394 | Some(known_ty) => { | 425 | Some(known_ty) => { |
@@ -410,8 +441,8 @@ impl InferenceTable { | |||
410 | /// be resolved as far as possible, i.e. contain no type variables with | 441 | /// be resolved as far as possible, i.e. contain no type variables with |
411 | /// known type. | 442 | /// known type. |
412 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 443 | fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
413 | ty.fold(&mut |ty| match ty { | 444 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
414 | Ty::InferenceVar(tv, kind) => { | 445 | &TyKind::InferenceVar(tv, kind) => { |
415 | let inner = tv.to_inner(); | 446 | let inner = tv.to_inner(); |
416 | if tv_stack.contains(&inner) { | 447 | if tv_stack.contains(&inner) { |
417 | cov_mark::hit!(type_var_cycles_resolve_as_possible); | 448 | cov_mark::hit!(type_var_cycles_resolve_as_possible); |
@@ -435,10 +466,10 @@ impl InferenceTable { | |||
435 | } | 466 | } |
436 | 467 | ||
437 | /// Resolves the type completely; type variables without known type are | 468 | /// Resolves the type completely; type variables without known type are |
438 | /// replaced by Ty::Unknown. | 469 | /// replaced by TyKind::Unknown. |
439 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { | 470 | fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { |
440 | ty.fold(&mut |ty| match ty { | 471 | ty.fold(&mut |ty| match ty.interned(&Interner) { |
441 | Ty::InferenceVar(tv, kind) => { | 472 | &TyKind::InferenceVar(tv, kind) => { |
442 | let inner = tv.to_inner(); | 473 | let inner = tv.to_inner(); |
443 | if tv_stack.contains(&inner) { | 474 | if tv_stack.contains(&inner) { |
444 | cov_mark::hit!(type_var_cycles_resolve_completely); | 475 | cov_mark::hit!(type_var_cycles_resolve_completely); |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index e77f24e4e..503910dde 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -27,9 +27,8 @@ use std::{iter, mem, ops::Deref, sync::Arc}; | |||
27 | 27 | ||
28 | use base_db::salsa; | 28 | use base_db::salsa; |
29 | use hir_def::{ | 29 | use hir_def::{ |
30 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, DefWithBodyId, | 30 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, |
31 | FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, | 31 | GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, |
32 | TypeParamId, | ||
33 | }; | 32 | }; |
34 | use itertools::Itertools; | 33 | use itertools::Itertools; |
35 | 34 | ||
@@ -47,9 +46,16 @@ pub use lower::{ | |||
47 | }; | 46 | }; |
48 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 47 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
49 | 48 | ||
50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; | 49 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; |
51 | 50 | ||
52 | pub(crate) use crate::traits::chalk::Interner; | 51 | pub use crate::traits::chalk::Interner; |
52 | |||
53 | pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; | ||
54 | pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | ||
55 | pub type FnDefId = chalk_ir::FnDefId<Interner>; | ||
56 | pub type ClosureId = chalk_ir::ClosureId<Interner>; | ||
57 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | ||
58 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | ||
53 | 59 | ||
54 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
55 | pub enum Lifetime { | 61 | pub enum Lifetime { |
@@ -60,7 +66,7 @@ pub enum Lifetime { | |||
60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 66 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
61 | pub struct OpaqueTy { | 67 | pub struct OpaqueTy { |
62 | pub opaque_ty_id: OpaqueTyId, | 68 | pub opaque_ty_id: OpaqueTyId, |
63 | pub parameters: Substs, | 69 | pub substitution: Substs, |
64 | } | 70 | } |
65 | 71 | ||
66 | /// A "projection" type corresponds to an (unnormalized) | 72 | /// A "projection" type corresponds to an (unnormalized) |
@@ -68,17 +74,17 @@ pub struct OpaqueTy { | |||
68 | /// trait and all its parameters are fully known. | 74 | /// trait and all its parameters are fully known. |
69 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 75 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
70 | pub struct ProjectionTy { | 76 | pub struct ProjectionTy { |
71 | pub associated_ty: TypeAliasId, | 77 | pub associated_ty_id: AssocTypeId, |
72 | pub parameters: Substs, | 78 | pub substitution: Substs, |
73 | } | 79 | } |
74 | 80 | ||
75 | impl ProjectionTy { | 81 | impl ProjectionTy { |
76 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { | 82 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { |
77 | TraitRef { trait_: self.trait_(db), substs: self.parameters.clone() } | 83 | TraitRef { trait_: self.trait_(db), substs: self.substitution.clone() } |
78 | } | 84 | } |
79 | 85 | ||
80 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { | 86 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { |
81 | match self.associated_ty.lookup(db.upcast()).container { | 87 | match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { |
82 | AssocContainerId::TraitId(it) => it, | 88 | AssocContainerId::TraitId(it) => it, |
83 | _ => panic!("projection ty without parent trait"), | 89 | _ => panic!("projection ty without parent trait"), |
84 | } | 90 | } |
@@ -87,7 +93,7 @@ impl ProjectionTy { | |||
87 | 93 | ||
88 | impl TypeWalk for ProjectionTy { | 94 | impl TypeWalk for ProjectionTy { |
89 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 95 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
90 | self.parameters.walk(f); | 96 | self.substitution.walk(f); |
91 | } | 97 | } |
92 | 98 | ||
93 | fn walk_mut_binders( | 99 | fn walk_mut_binders( |
@@ -95,14 +101,11 @@ impl TypeWalk for ProjectionTy { | |||
95 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 101 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
96 | binders: DebruijnIndex, | 102 | binders: DebruijnIndex, |
97 | ) { | 103 | ) { |
98 | self.parameters.walk_mut_binders(f, binders); | 104 | self.substitution.walk_mut_binders(f, binders); |
99 | } | 105 | } |
100 | } | 106 | } |
101 | 107 | ||
102 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 108 | pub type FnSig = chalk_ir::FnSig<Interner>; |
103 | pub struct FnSig { | ||
104 | pub variadic: bool, | ||
105 | } | ||
106 | 109 | ||
107 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 110 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
108 | pub struct FnPointer { | 111 | pub struct FnPointer { |
@@ -131,7 +134,7 @@ pub enum AliasTy { | |||
131 | /// | 134 | /// |
132 | /// This should be cheap to clone. | 135 | /// This should be cheap to clone. |
133 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 136 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
134 | pub enum Ty { | 137 | pub enum TyKind { |
135 | /// Structures, enumerations and unions. | 138 | /// Structures, enumerations and unions. |
136 | Adt(AdtId<Interner>, Substs), | 139 | Adt(AdtId<Interner>, Substs), |
137 | 140 | ||
@@ -139,7 +142,7 @@ pub enum Ty { | |||
139 | /// when we have tried to normalize a projection like `T::Item` but | 142 | /// when we have tried to normalize a projection like `T::Item` but |
140 | /// couldn't find a better representation. In that case, we generate | 143 | /// couldn't find a better representation. In that case, we generate |
141 | /// an **application type** like `(Iterator::Item)<T>`. | 144 | /// an **application type** like `(Iterator::Item)<T>`. |
142 | AssociatedType(TypeAliasId, Substs), | 145 | AssociatedType(AssocTypeId, Substs), |
143 | 146 | ||
144 | /// a scalar type like `bool` or `u32` | 147 | /// a scalar type like `bool` or `u32` |
145 | Scalar(Scalar), | 148 | Scalar(Scalar), |
@@ -148,17 +151,17 @@ pub enum Ty { | |||
148 | Tuple(usize, Substs), | 151 | Tuple(usize, Substs), |
149 | 152 | ||
150 | /// An array with the given length. Written as `[T; n]`. | 153 | /// An array with the given length. Written as `[T; n]`. |
151 | Array(Substs), | 154 | Array(Ty), |
152 | 155 | ||
153 | /// The pointee of an array slice. Written as `[T]`. | 156 | /// The pointee of an array slice. Written as `[T]`. |
154 | Slice(Substs), | 157 | Slice(Ty), |
155 | 158 | ||
156 | /// A raw pointer. Written as `*mut T` or `*const T` | 159 | /// A raw pointer. Written as `*mut T` or `*const T` |
157 | Raw(Mutability, Substs), | 160 | Raw(Mutability, Ty), |
158 | 161 | ||
159 | /// A reference; a pointer with an associated lifetime. Written as | 162 | /// A reference; a pointer with an associated lifetime. Written as |
160 | /// `&'a mut T` or `&'a T`. | 163 | /// `&'a mut T` or `&'a T`. |
161 | Ref(Mutability, Substs), | 164 | Ref(Mutability, Ty), |
162 | 165 | ||
163 | /// This represents a placeholder for an opaque type in situations where we | 166 | /// This represents a placeholder for an opaque type in situations where we |
164 | /// don't know the hidden type (i.e. currently almost always). This is | 167 | /// don't know the hidden type (i.e. currently almost always). This is |
@@ -179,7 +182,7 @@ pub enum Ty { | |||
179 | /// fn foo() -> i32 { 1 } | 182 | /// fn foo() -> i32 { 1 } |
180 | /// let bar = foo; // bar: fn() -> i32 {foo} | 183 | /// let bar = foo; // bar: fn() -> i32 {foo} |
181 | /// ``` | 184 | /// ``` |
182 | FnDef(CallableDefId, Substs), | 185 | FnDef(FnDefId, Substs), |
183 | 186 | ||
184 | /// The pointee of a string slice. Written as `str`. | 187 | /// The pointee of a string slice. Written as `str`. |
185 | Str, | 188 | Str, |
@@ -191,10 +194,10 @@ pub enum Ty { | |||
191 | /// | 194 | /// |
192 | /// The closure signature is stored in a `FnPtr` type in the first type | 195 | /// The closure signature is stored in a `FnPtr` type in the first type |
193 | /// parameter. | 196 | /// parameter. |
194 | Closure(DefWithBodyId, ExprId, Substs), | 197 | Closure(ClosureId, Substs), |
195 | 198 | ||
196 | /// Represents a foreign type declared in external blocks. | 199 | /// Represents a foreign type declared in external blocks. |
197 | ForeignType(TypeAliasId), | 200 | ForeignType(ForeignDefId), |
198 | 201 | ||
199 | /// A pointer to a function. Written as `fn() -> i32`. | 202 | /// A pointer to a function. Written as `fn() -> i32`. |
200 | /// | 203 | /// |
@@ -216,7 +219,7 @@ pub enum Ty { | |||
216 | /// {}` when we're type-checking the body of that function. In this | 219 | /// {}` when we're type-checking the body of that function. In this |
217 | /// situation, we know this stands for *some* type, but don't know the exact | 220 | /// situation, we know this stands for *some* type, but don't know the exact |
218 | /// type. | 221 | /// type. |
219 | Placeholder(TypeParamId), | 222 | Placeholder(PlaceholderIndex), |
220 | 223 | ||
221 | /// A bound type variable. This is used in various places: when representing | 224 | /// A bound type variable. This is used in various places: when representing |
222 | /// some polymorphic type like the type of function `fn f<T>`, the type | 225 | /// some polymorphic type like the type of function `fn f<T>`, the type |
@@ -244,6 +247,29 @@ pub enum Ty { | |||
244 | Unknown, | 247 | Unknown, |
245 | } | 248 | } |
246 | 249 | ||
250 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
251 | pub struct Ty(Arc<TyKind>); | ||
252 | |||
253 | impl TyKind { | ||
254 | pub fn intern(self, _interner: &Interner) -> Ty { | ||
255 | Ty(Arc::new(self)) | ||
256 | } | ||
257 | } | ||
258 | |||
259 | impl Ty { | ||
260 | pub fn interned(&self, _interner: &Interner) -> &TyKind { | ||
261 | &self.0 | ||
262 | } | ||
263 | |||
264 | pub fn interned_mut(&mut self) -> &mut TyKind { | ||
265 | Arc::make_mut(&mut self.0) | ||
266 | } | ||
267 | |||
268 | pub fn into_inner(self) -> TyKind { | ||
269 | Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone()) | ||
270 | } | ||
271 | } | ||
272 | |||
247 | /// A list of substitutions for generic parameters. | 273 | /// A list of substitutions for generic parameters. |
248 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 274 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
249 | pub struct Substs(Arc<[Ty]>); | 275 | pub struct Substs(Arc<[Ty]>); |
@@ -291,14 +317,22 @@ impl Substs { | |||
291 | } | 317 | } |
292 | 318 | ||
293 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 319 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
294 | pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs { | 320 | pub(crate) fn type_params_for_generics( |
295 | Substs(generic_params.iter().map(|(id, _)| Ty::Placeholder(id)).collect()) | 321 | db: &dyn HirDatabase, |
322 | generic_params: &Generics, | ||
323 | ) -> Substs { | ||
324 | Substs( | ||
325 | generic_params | ||
326 | .iter() | ||
327 | .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)) | ||
328 | .collect(), | ||
329 | ) | ||
296 | } | 330 | } |
297 | 331 | ||
298 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 332 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
299 | pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { | 333 | pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { |
300 | let params = generics(db.upcast(), def.into()); | 334 | let params = generics(db.upcast(), def.into()); |
301 | Substs::type_params_for_generics(¶ms) | 335 | Substs::type_params_for_generics(db, ¶ms) |
302 | } | 336 | } |
303 | 337 | ||
304 | /// Return Substs that replace each parameter by a bound variable. | 338 | /// Return Substs that replace each parameter by a bound variable. |
@@ -307,7 +341,7 @@ impl Substs { | |||
307 | generic_params | 341 | generic_params |
308 | .iter() | 342 | .iter() |
309 | .enumerate() | 343 | .enumerate() |
310 | .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) | 344 | .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)) |
311 | .collect(), | 345 | .collect(), |
312 | ) | 346 | ) |
313 | } | 347 | } |
@@ -355,11 +389,14 @@ impl SubstsBuilder { | |||
355 | } | 389 | } |
356 | 390 | ||
357 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { | 391 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { |
358 | self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx)))) | 392 | self.fill( |
393 | (starting_from..) | ||
394 | .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), | ||
395 | ) | ||
359 | } | 396 | } |
360 | 397 | ||
361 | pub fn fill_with_unknown(self) -> Self { | 398 | pub fn fill_with_unknown(self) -> Self { |
362 | self.fill(iter::repeat(Ty::Unknown)) | 399 | self.fill(iter::repeat(TyKind::Unknown.intern(&Interner))) |
363 | } | 400 | } |
364 | 401 | ||
365 | pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { | 402 | pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { |
@@ -601,47 +638,50 @@ impl TypeWalk for CallableSig { | |||
601 | 638 | ||
602 | impl Ty { | 639 | impl Ty { |
603 | pub fn unit() -> Self { | 640 | pub fn unit() -> Self { |
604 | Ty::Tuple(0, Substs::empty()) | 641 | TyKind::Tuple(0, Substs::empty()).intern(&Interner) |
605 | } | 642 | } |
606 | 643 | ||
607 | pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { | 644 | pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { |
608 | Ty::Adt(AdtId(adt), substs) | 645 | TyKind::Adt(AdtId(adt), substs).intern(&Interner) |
609 | } | 646 | } |
610 | 647 | ||
611 | pub fn fn_ptr(sig: CallableSig) -> Self { | 648 | pub fn fn_ptr(sig: CallableSig) -> Self { |
612 | Ty::Function(FnPointer { | 649 | TyKind::Function(FnPointer { |
613 | num_args: sig.params().len(), | 650 | num_args: sig.params().len(), |
614 | sig: FnSig { variadic: sig.is_varargs }, | 651 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, |
615 | substs: Substs(sig.params_and_return), | 652 | substs: Substs(sig.params_and_return), |
616 | }) | 653 | }) |
654 | .intern(&Interner) | ||
617 | } | 655 | } |
618 | 656 | ||
619 | pub fn builtin(builtin: BuiltinType) -> Self { | 657 | pub fn builtin(builtin: BuiltinType) -> Self { |
620 | match builtin { | 658 | match builtin { |
621 | BuiltinType::Char => Ty::Scalar(Scalar::Char), | 659 | BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner), |
622 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), | 660 | BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
623 | BuiltinType::Str => Ty::Str, | 661 | BuiltinType::Str => TyKind::Str.intern(&Interner), |
624 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), | 662 | BuiltinType::Int(t) => { |
625 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), | 663 | TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner) |
626 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), | 664 | } |
665 | BuiltinType::Uint(t) => { | ||
666 | TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner) | ||
667 | } | ||
668 | BuiltinType::Float(t) => { | ||
669 | TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner) | ||
670 | } | ||
627 | } | 671 | } |
628 | } | 672 | } |
629 | 673 | ||
630 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 674 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
631 | match self { | 675 | match self.interned(&Interner) { |
632 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), | 676 | TyKind::Ref(mutability, ty) => Some((ty, *mutability)), |
633 | _ => None, | 677 | _ => None, |
634 | } | 678 | } |
635 | } | 679 | } |
636 | 680 | ||
637 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 681 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
638 | match self { | 682 | match self.interned(&Interner) { |
639 | Ty::Ref(mutability, parameters) => { | 683 | TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)), |
640 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 684 | TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)), |
641 | } | ||
642 | Ty::Raw(mutability, parameters) => { | ||
643 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | ||
644 | } | ||
645 | _ => None, | 685 | _ => None, |
646 | } | 686 | } |
647 | } | 687 | } |
@@ -649,73 +689,79 @@ impl Ty { | |||
649 | pub fn strip_references(&self) -> &Ty { | 689 | pub fn strip_references(&self) -> &Ty { |
650 | let mut t: &Ty = self; | 690 | let mut t: &Ty = self; |
651 | 691 | ||
652 | while let Ty::Ref(_mutability, parameters) = t { | 692 | while let TyKind::Ref(_mutability, ty) = t.interned(&Interner) { |
653 | t = parameters.as_single(); | 693 | t = ty; |
654 | } | 694 | } |
655 | 695 | ||
656 | t | 696 | t |
657 | } | 697 | } |
658 | 698 | ||
659 | pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { | 699 | pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { |
660 | match self { | 700 | match self.interned(&Interner) { |
661 | Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), | 701 | TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), |
662 | _ => None, | 702 | _ => None, |
663 | } | 703 | } |
664 | } | 704 | } |
665 | 705 | ||
666 | pub fn as_tuple(&self) -> Option<&Substs> { | 706 | pub fn as_tuple(&self) -> Option<&Substs> { |
667 | match self { | 707 | match self.interned(&Interner) { |
668 | Ty::Tuple(_, substs) => Some(substs), | 708 | TyKind::Tuple(_, substs) => Some(substs), |
669 | _ => None, | 709 | _ => None, |
670 | } | 710 | } |
671 | } | 711 | } |
672 | 712 | ||
673 | pub fn as_generic_def(&self) -> Option<GenericDefId> { | 713 | pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> { |
674 | match *self { | 714 | match *self.interned(&Interner) { |
675 | Ty::Adt(AdtId(adt), ..) => Some(adt.into()), | 715 | TyKind::Adt(AdtId(adt), ..) => Some(adt.into()), |
676 | Ty::FnDef(callable, ..) => Some(callable.into()), | 716 | TyKind::FnDef(callable, ..) => { |
677 | Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), | 717 | Some(db.lookup_intern_callable_def(callable.into()).into()) |
678 | Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), | 718 | } |
719 | TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()), | ||
720 | TyKind::ForeignType(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()), | ||
679 | _ => None, | 721 | _ => None, |
680 | } | 722 | } |
681 | } | 723 | } |
682 | 724 | ||
683 | pub fn is_never(&self) -> bool { | 725 | pub fn is_never(&self) -> bool { |
684 | matches!(self, Ty::Never) | 726 | matches!(self.interned(&Interner), TyKind::Never) |
685 | } | 727 | } |
686 | 728 | ||
687 | pub fn is_unknown(&self) -> bool { | 729 | pub fn is_unknown(&self) -> bool { |
688 | matches!(self, Ty::Unknown) | 730 | matches!(self.interned(&Interner), TyKind::Unknown) |
689 | } | 731 | } |
690 | 732 | ||
691 | pub fn equals_ctor(&self, other: &Ty) -> bool { | 733 | pub fn equals_ctor(&self, other: &Ty) -> bool { |
692 | match (self, other) { | 734 | match (self.interned(&Interner), other.interned(&Interner)) { |
693 | (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, | 735 | (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2, |
694 | (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, | 736 | (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true, |
695 | (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, | 737 | (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2, |
696 | (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, | 738 | (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, |
697 | (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) | 739 | (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => { |
698 | | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | 740 | ty_id == ty_id2 |
699 | (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { | 741 | } |
700 | expr == expr2 && def == def2 | 742 | (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2, |
743 | (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2, | ||
744 | (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..)) | ||
745 | | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => { | ||
746 | mutability == mutability2 | ||
701 | } | 747 | } |
702 | (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) | ||
703 | | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2, | ||
704 | ( | 748 | ( |
705 | Ty::Function(FnPointer { num_args, sig, .. }), | 749 | TyKind::Function(FnPointer { num_args, sig, .. }), |
706 | Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), | 750 | TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), |
707 | ) => num_args == num_args2 && sig == sig2, | 751 | ) => num_args == num_args2 && sig == sig2, |
708 | (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, | 752 | (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => { |
709 | (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, | 753 | cardinality == cardinality2 |
710 | (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, | 754 | } |
755 | (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true, | ||
756 | (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2, | ||
711 | _ => false, | 757 | _ => false, |
712 | } | 758 | } |
713 | } | 759 | } |
714 | 760 | ||
715 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 761 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
716 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 762 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
717 | match self { | 763 | match self.interned(&Interner) { |
718 | Ty::Dyn(bounds) => bounds.get(0).and_then(|b| match b { | 764 | TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { |
719 | GenericPredicate::Implemented(trait_ref) => Some(trait_ref), | 765 | GenericPredicate::Implemented(trait_ref) => Some(trait_ref), |
720 | _ => None, | 766 | _ => None, |
721 | }), | 767 | }), |
@@ -729,28 +775,37 @@ impl Ty { | |||
729 | } | 775 | } |
730 | 776 | ||
731 | fn builtin_deref(&self) -> Option<Ty> { | 777 | fn builtin_deref(&self) -> Option<Ty> { |
732 | match self { | 778 | match self.interned(&Interner) { |
733 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), | 779 | TyKind::Ref(.., ty) => Some(ty.clone()), |
734 | Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), | 780 | TyKind::Raw(.., ty) => Some(ty.clone()), |
735 | _ => None, | 781 | _ => None, |
736 | } | 782 | } |
737 | } | 783 | } |
738 | 784 | ||
739 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 785 | pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> { |
740 | match self { | 786 | match self.interned(&Interner) { |
741 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), | 787 | &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())), |
742 | _ => None, | 788 | _ => None, |
743 | } | 789 | } |
744 | } | 790 | } |
745 | 791 | ||
792 | pub fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> { | ||
793 | if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) { | ||
794 | Some(func) | ||
795 | } else { | ||
796 | None | ||
797 | } | ||
798 | } | ||
799 | |||
746 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { | 800 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { |
747 | match self { | 801 | match self.interned(&Interner) { |
748 | Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), | 802 | TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), |
749 | Ty::FnDef(def, parameters) => { | 803 | TyKind::FnDef(def, parameters) => { |
750 | let sig = db.callable_item_signature(*def); | 804 | let callable_def = db.lookup_intern_callable_def((*def).into()); |
805 | let sig = db.callable_item_signature(callable_def); | ||
751 | Some(sig.subst(¶meters)) | 806 | Some(sig.subst(¶meters)) |
752 | } | 807 | } |
753 | Ty::Closure(.., substs) => { | 808 | TyKind::Closure(.., substs) => { |
754 | let sig_param = &substs[0]; | 809 | let sig_param = &substs[0]; |
755 | sig_param.callable_sig(db) | 810 | sig_param.callable_sig(db) |
756 | } | 811 | } |
@@ -758,72 +813,39 @@ impl Ty { | |||
758 | } | 813 | } |
759 | } | 814 | } |
760 | 815 | ||
761 | /// If this is a type with type parameters (an ADT or function), replaces | ||
762 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | ||
763 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | ||
764 | /// `Option<u32>` afterwards.) | ||
765 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { | ||
766 | match &mut self { | ||
767 | Ty::Adt(_, substs) | ||
768 | | Ty::Slice(substs) | ||
769 | | Ty::Array(substs) | ||
770 | | Ty::Raw(_, substs) | ||
771 | | Ty::Ref(_, substs) | ||
772 | | Ty::FnDef(_, substs) | ||
773 | | Ty::Function(FnPointer { substs, .. }) | ||
774 | | Ty::Tuple(_, substs) | ||
775 | | Ty::OpaqueType(_, substs) | ||
776 | | Ty::AssociatedType(_, substs) | ||
777 | | Ty::Closure(.., substs) => { | ||
778 | assert_eq!(substs.len(), new_substs.len()); | ||
779 | *substs = new_substs; | ||
780 | } | ||
781 | _ => (), | ||
782 | } | ||
783 | self | ||
784 | } | ||
785 | |||
786 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 816 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
787 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 817 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
788 | pub fn substs(&self) -> Option<&Substs> { | 818 | pub fn substs(&self) -> Option<&Substs> { |
789 | match self { | 819 | match self.interned(&Interner) { |
790 | Ty::Adt(_, substs) | 820 | TyKind::Adt(_, substs) |
791 | | Ty::Slice(substs) | 821 | | TyKind::FnDef(_, substs) |
792 | | Ty::Array(substs) | 822 | | TyKind::Function(FnPointer { substs, .. }) |
793 | | Ty::Raw(_, substs) | 823 | | TyKind::Tuple(_, substs) |
794 | | Ty::Ref(_, substs) | 824 | | TyKind::OpaqueType(_, substs) |
795 | | Ty::FnDef(_, substs) | 825 | | TyKind::AssociatedType(_, substs) |
796 | | Ty::Function(FnPointer { substs, .. }) | 826 | | TyKind::Closure(.., substs) => Some(substs), |
797 | | Ty::Tuple(_, substs) | ||
798 | | Ty::OpaqueType(_, substs) | ||
799 | | Ty::AssociatedType(_, substs) | ||
800 | | Ty::Closure(.., substs) => Some(substs), | ||
801 | _ => None, | 827 | _ => None, |
802 | } | 828 | } |
803 | } | 829 | } |
804 | 830 | ||
805 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | 831 | fn substs_mut(&mut self) -> Option<&mut Substs> { |
806 | match self { | 832 | match self.interned_mut() { |
807 | Ty::Adt(_, substs) | 833 | TyKind::Adt(_, substs) |
808 | | Ty::Slice(substs) | 834 | | TyKind::FnDef(_, substs) |
809 | | Ty::Array(substs) | 835 | | TyKind::Function(FnPointer { substs, .. }) |
810 | | Ty::Raw(_, substs) | 836 | | TyKind::Tuple(_, substs) |
811 | | Ty::Ref(_, substs) | 837 | | TyKind::OpaqueType(_, substs) |
812 | | Ty::FnDef(_, substs) | 838 | | TyKind::AssociatedType(_, substs) |
813 | | Ty::Function(FnPointer { substs, .. }) | 839 | | TyKind::Closure(.., substs) => Some(substs), |
814 | | Ty::Tuple(_, substs) | ||
815 | | Ty::OpaqueType(_, substs) | ||
816 | | Ty::AssociatedType(_, substs) | ||
817 | | Ty::Closure(.., substs) => Some(substs), | ||
818 | _ => None, | 840 | _ => None, |
819 | } | 841 | } |
820 | } | 842 | } |
821 | 843 | ||
822 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 844 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
823 | match self { | 845 | match self.interned(&Interner) { |
824 | Ty::OpaqueType(opaque_ty_id, ..) => { | 846 | TyKind::OpaqueType(opaque_ty_id, ..) => { |
825 | match opaque_ty_id { | 847 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { |
826 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 848 | ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { |
827 | let krate = def.module(db.upcast()).krate(); | 849 | let krate = def.module(db.upcast()).krate(); |
828 | if let Some(future_trait) = db | 850 | if let Some(future_trait) = db |
829 | .lang_item(krate, "future_trait".into()) | 851 | .lang_item(krate, "future_trait".into()) |
@@ -841,32 +863,34 @@ impl Ty { | |||
841 | None | 863 | None |
842 | } | 864 | } |
843 | } | 865 | } |
844 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | 866 | ImplTraitId::ReturnTypeImplTrait(..) => None, |
845 | } | 867 | } |
846 | } | 868 | } |
847 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | 869 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
848 | let predicates = match opaque_ty.opaque_ty_id { | 870 | let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into()) |
849 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 871 | { |
872 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
850 | db.return_type_impl_traits(func).map(|it| { | 873 | db.return_type_impl_traits(func).map(|it| { |
851 | let data = (*it) | 874 | let data = (*it) |
852 | .as_ref() | 875 | .as_ref() |
853 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 876 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
854 | data.subst(&opaque_ty.parameters) | 877 | data.subst(&opaque_ty.substitution) |
855 | }) | 878 | }) |
856 | } | 879 | } |
857 | // It always has an parameter for Future::Output type. | 880 | // It always has an parameter for Future::Output type. |
858 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), | 881 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), |
859 | }; | 882 | }; |
860 | 883 | ||
861 | predicates.map(|it| it.value) | 884 | predicates.map(|it| it.value) |
862 | } | 885 | } |
863 | Ty::Placeholder(id) => { | 886 | TyKind::Placeholder(idx) => { |
887 | let id = from_placeholder_idx(db, *idx); | ||
864 | let generic_params = db.generic_params(id.parent); | 888 | let generic_params = db.generic_params(id.parent); |
865 | let param_data = &generic_params.types[id.local_id]; | 889 | let param_data = &generic_params.types[id.local_id]; |
866 | match param_data.provenance { | 890 | match param_data.provenance { |
867 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { | 891 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { |
868 | let predicates = db | 892 | let predicates = db |
869 | .generic_predicates_for_param(*id) | 893 | .generic_predicates_for_param(id) |
870 | .into_iter() | 894 | .into_iter() |
871 | .map(|pred| pred.value.clone()) | 895 | .map(|pred| pred.value.clone()) |
872 | .collect_vec(); | 896 | .collect_vec(); |
@@ -881,15 +905,18 @@ impl Ty { | |||
881 | } | 905 | } |
882 | 906 | ||
883 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | 907 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { |
884 | match self { | 908 | match self.interned(&Interner) { |
885 | Ty::AssociatedType(type_alias_id, ..) => { | 909 | TyKind::AssociatedType(id, ..) => { |
886 | match type_alias_id.lookup(db.upcast()).container { | 910 | match from_assoc_type_id(*id).lookup(db.upcast()).container { |
887 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 911 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
888 | _ => None, | 912 | _ => None, |
889 | } | 913 | } |
890 | } | 914 | } |
891 | Ty::Alias(AliasTy::Projection(projection_ty)) => { | 915 | TyKind::Alias(AliasTy::Projection(projection_ty)) => { |
892 | match projection_ty.associated_ty.lookup(db.upcast()).container { | 916 | match from_assoc_type_id(projection_ty.associated_ty_id) |
917 | .lookup(db.upcast()) | ||
918 | .container | ||
919 | { | ||
893 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 920 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
894 | _ => None, | 921 | _ => None, |
895 | } | 922 | } |
@@ -908,13 +935,13 @@ pub trait TypeWalk { | |||
908 | } | 935 | } |
909 | /// Walk the type, counting entered binders. | 936 | /// Walk the type, counting entered binders. |
910 | /// | 937 | /// |
911 | /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers | 938 | /// `TyKind::Bound` variables use DeBruijn indexing, which means that 0 refers |
912 | /// to the innermost binder, 1 to the next, etc.. So when we want to | 939 | /// to the innermost binder, 1 to the next, etc.. So when we want to |
913 | /// substitute a certain bound variable, we can't just walk the whole type | 940 | /// substitute a certain bound variable, we can't just walk the whole type |
914 | /// and blindly replace each instance of a certain index; when we 'enter' | 941 | /// and blindly replace each instance of a certain index; when we 'enter' |
915 | /// things that introduce new bound variables, we have to keep track of | 942 | /// things that introduce new bound variables, we have to keep track of |
916 | /// that. Currently, the only thing that introduces bound variables on our | 943 | /// that. Currently, the only thing that introduces bound variables on our |
917 | /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound | 944 | /// side are `TyKind::Dyn` and `TyKind::Opaque`, which each introduce a bound |
918 | /// variable for the self type. | 945 | /// variable for the self type. |
919 | fn walk_mut_binders( | 946 | fn walk_mut_binders( |
920 | &mut self, | 947 | &mut self, |
@@ -932,7 +959,7 @@ pub trait TypeWalk { | |||
932 | { | 959 | { |
933 | self.walk_mut_binders( | 960 | self.walk_mut_binders( |
934 | &mut |ty_mut, binders| { | 961 | &mut |ty_mut, binders| { |
935 | let ty = mem::replace(ty_mut, Ty::Unknown); | 962 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
936 | *ty_mut = f(ty, binders); | 963 | *ty_mut = f(ty, binders); |
937 | }, | 964 | }, |
938 | binders, | 965 | binders, |
@@ -945,13 +972,13 @@ pub trait TypeWalk { | |||
945 | Self: Sized, | 972 | Self: Sized, |
946 | { | 973 | { |
947 | self.walk_mut(&mut |ty_mut| { | 974 | self.walk_mut(&mut |ty_mut| { |
948 | let ty = mem::replace(ty_mut, Ty::Unknown); | 975 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
949 | *ty_mut = f(ty); | 976 | *ty_mut = f(ty); |
950 | }); | 977 | }); |
951 | self | 978 | self |
952 | } | 979 | } |
953 | 980 | ||
954 | /// Substitutes `Ty::Bound` vars with the given substitution. | 981 | /// Substitutes `TyKind::Bound` vars with the given substitution. |
955 | fn subst_bound_vars(self, substs: &Substs) -> Self | 982 | fn subst_bound_vars(self, substs: &Substs) -> Self |
956 | where | 983 | where |
957 | Self: Sized, | 984 | Self: Sized, |
@@ -959,14 +986,14 @@ pub trait TypeWalk { | |||
959 | self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) | 986 | self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) |
960 | } | 987 | } |
961 | 988 | ||
962 | /// Substitutes `Ty::Bound` vars with the given substitution. | 989 | /// Substitutes `TyKind::Bound` vars with the given substitution. |
963 | fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self | 990 | fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self |
964 | where | 991 | where |
965 | Self: Sized, | 992 | Self: Sized, |
966 | { | 993 | { |
967 | self.walk_mut_binders( | 994 | self.walk_mut_binders( |
968 | &mut |ty, binders| { | 995 | &mut |ty, binders| { |
969 | if let &mut Ty::BoundVar(bound) = ty { | 996 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { |
970 | if bound.debruijn >= binders { | 997 | if bound.debruijn >= binders { |
971 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); | 998 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
972 | } | 999 | } |
@@ -977,17 +1004,17 @@ pub trait TypeWalk { | |||
977 | self | 1004 | self |
978 | } | 1005 | } |
979 | 1006 | ||
980 | /// Shifts up debruijn indices of `Ty::Bound` vars by `n`. | 1007 | /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`. |
981 | fn shift_bound_vars(self, n: DebruijnIndex) -> Self | 1008 | fn shift_bound_vars(self, n: DebruijnIndex) -> Self |
982 | where | 1009 | where |
983 | Self: Sized, | 1010 | Self: Sized, |
984 | { | 1011 | { |
985 | self.fold_binders( | 1012 | self.fold_binders( |
986 | &mut |ty, binders| match ty { | 1013 | &mut |ty, binders| match ty.interned(&Interner) { |
987 | Ty::BoundVar(bound) if bound.debruijn >= binders => { | 1014 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { |
988 | Ty::BoundVar(bound.shifted_in_from(n)) | 1015 | TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) |
989 | } | 1016 | } |
990 | ty => ty, | 1017 | _ => ty, |
991 | }, | 1018 | }, |
992 | DebruijnIndex::INNERMOST, | 1019 | DebruijnIndex::INNERMOST, |
993 | ) | 1020 | ) |
@@ -996,22 +1023,25 @@ pub trait TypeWalk { | |||
996 | 1023 | ||
997 | impl TypeWalk for Ty { | 1024 | impl TypeWalk for Ty { |
998 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 1025 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
999 | match self { | 1026 | match self.interned(&Interner) { |
1000 | Ty::Alias(AliasTy::Projection(p_ty)) => { | 1027 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1001 | for t in p_ty.parameters.iter() { | 1028 | for t in p_ty.substitution.iter() { |
1002 | t.walk(f); | 1029 | t.walk(f); |
1003 | } | 1030 | } |
1004 | } | 1031 | } |
1005 | Ty::Alias(AliasTy::Opaque(o_ty)) => { | 1032 | TyKind::Alias(AliasTy::Opaque(o_ty)) => { |
1006 | for t in o_ty.parameters.iter() { | 1033 | for t in o_ty.substitution.iter() { |
1007 | t.walk(f); | 1034 | t.walk(f); |
1008 | } | 1035 | } |
1009 | } | 1036 | } |
1010 | Ty::Dyn(predicates) => { | 1037 | TyKind::Dyn(predicates) => { |
1011 | for p in predicates.iter() { | 1038 | for p in predicates.iter() { |
1012 | p.walk(f); | 1039 | p.walk(f); |
1013 | } | 1040 | } |
1014 | } | 1041 | } |
1042 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | ||
1043 | ty.walk(f); | ||
1044 | } | ||
1015 | _ => { | 1045 | _ => { |
1016 | if let Some(substs) = self.substs() { | 1046 | if let Some(substs) = self.substs() { |
1017 | for t in substs.iter() { | 1047 | for t in substs.iter() { |
@@ -1028,17 +1058,20 @@ impl TypeWalk for Ty { | |||
1028 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 1058 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
1029 | binders: DebruijnIndex, | 1059 | binders: DebruijnIndex, |
1030 | ) { | 1060 | ) { |
1031 | match self { | 1061 | match self.interned_mut() { |
1032 | Ty::Alias(AliasTy::Projection(p_ty)) => { | 1062 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1033 | p_ty.parameters.walk_mut_binders(f, binders); | 1063 | p_ty.substitution.walk_mut_binders(f, binders); |
1034 | } | 1064 | } |
1035 | Ty::Dyn(predicates) => { | 1065 | TyKind::Dyn(predicates) => { |
1036 | for p in make_mut_slice(predicates) { | 1066 | for p in make_mut_slice(predicates) { |
1037 | p.walk_mut_binders(f, binders.shifted_in()); | 1067 | p.walk_mut_binders(f, binders.shifted_in()); |
1038 | } | 1068 | } |
1039 | } | 1069 | } |
1040 | Ty::Alias(AliasTy::Opaque(o_ty)) => { | 1070 | TyKind::Alias(AliasTy::Opaque(o_ty)) => { |
1041 | o_ty.parameters.walk_mut_binders(f, binders); | 1071 | o_ty.substitution.walk_mut_binders(f, binders); |
1072 | } | ||
1073 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | ||
1074 | ty.walk_mut_binders(f, binders); | ||
1042 | } | 1075 | } |
1043 | _ => { | 1076 | _ => { |
1044 | if let Some(substs) = self.substs_mut() { | 1077 | if let Some(substs) = self.substs_mut() { |
@@ -1068,7 +1101,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> { | |||
1068 | } | 1101 | } |
1069 | 1102 | ||
1070 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 1103 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
1071 | pub enum OpaqueTyId { | 1104 | pub enum ImplTraitId { |
1072 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | 1105 | ReturnTypeImplTrait(hir_def::FunctionId, u16), |
1073 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), | 1106 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), |
1074 | } | 1107 | } |
@@ -1082,3 +1115,33 @@ pub struct ReturnTypeImplTraits { | |||
1082 | pub(crate) struct ReturnTypeImplTrait { | 1115 | pub(crate) struct ReturnTypeImplTrait { |
1083 | pub(crate) bounds: Binders<Vec<GenericPredicate>>, | 1116 | pub(crate) bounds: Binders<Vec<GenericPredicate>>, |
1084 | } | 1117 | } |
1118 | |||
1119 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | ||
1120 | chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) | ||
1121 | } | ||
1122 | |||
1123 | pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { | ||
1124 | salsa::InternKey::from_intern_id(id.0) | ||
1125 | } | ||
1126 | |||
1127 | pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { | ||
1128 | chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) | ||
1129 | } | ||
1130 | |||
1131 | pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { | ||
1132 | salsa::InternKey::from_intern_id(id.0) | ||
1133 | } | ||
1134 | |||
1135 | pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { | ||
1136 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
1137 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
1138 | db.lookup_intern_type_param_id(interned_id) | ||
1139 | } | ||
1140 | |||
1141 | pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { | ||
1142 | let interned_id = db.intern_type_param_id(id); | ||
1143 | PlaceholderIndex { | ||
1144 | ui: chalk_ir::UniverseIndex::ROOT, | ||
1145 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), | ||
1146 | } | ||
1147 | } | ||
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 5fa83567b..b4c650fa1 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -8,7 +8,7 @@ | |||
8 | use std::{iter, sync::Arc}; | 8 | use std::{iter, sync::Arc}; |
9 | 9 | ||
10 | use base_db::CrateId; | 10 | use base_db::CrateId; |
11 | use chalk_ir::Mutability; | 11 | use chalk_ir::{cast::Cast, Mutability, Safety}; |
12 | use hir_def::{ | 12 | use hir_def::{ |
13 | adt::StructKind, | 13 | adt::StructKind, |
14 | builtin_type::BuiltinType, | 14 | builtin_type::BuiltinType, |
@@ -27,13 +27,15 @@ use stdx::impl_from; | |||
27 | 27 | ||
28 | use crate::{ | 28 | use crate::{ |
29 | db::HirDatabase, | 29 | db::HirDatabase, |
30 | to_assoc_type_id, to_placeholder_idx, | ||
31 | traits::chalk::{Interner, ToChalk}, | ||
30 | utils::{ | 32 | utils::{ |
31 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, | 33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, |
32 | make_mut_slice, variant_data, | 34 | make_mut_slice, variant_data, |
33 | }, | 35 | }, |
34 | AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, | 36 | AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, |
35 | OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, | 37 | ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, |
36 | ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, | 38 | ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, |
37 | }; | 39 | }; |
38 | 40 | ||
39 | #[derive(Debug)] | 41 | #[derive(Debug)] |
@@ -138,69 +140,69 @@ pub enum TypeParamLoweringMode { | |||
138 | Variable, | 140 | Variable, |
139 | } | 141 | } |
140 | 142 | ||
141 | impl Ty { | 143 | impl<'a> TyLoweringContext<'a> { |
142 | pub fn from_hir(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> Self { | 144 | pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty { |
143 | Ty::from_hir_ext(ctx, type_ref).0 | 145 | self.lower_ty_ext(type_ref).0 |
144 | } | 146 | } |
145 | pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { | 147 | |
148 | fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) { | ||
146 | let mut res = None; | 149 | let mut res = None; |
147 | let ty = match type_ref { | 150 | let ty = match type_ref { |
148 | TypeRef::Never => Ty::Never, | 151 | TypeRef::Never => TyKind::Never.intern(&Interner), |
149 | TypeRef::Tuple(inner) => { | 152 | TypeRef::Tuple(inner) => { |
150 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); | 153 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| self.lower_ty(tr)).collect(); |
151 | Ty::Tuple(inner_tys.len(), Substs(inner_tys)) | 154 | TyKind::Tuple(inner_tys.len(), Substs(inner_tys)).intern(&Interner) |
152 | } | 155 | } |
153 | TypeRef::Path(path) => { | 156 | TypeRef::Path(path) => { |
154 | let (ty, res_) = Ty::from_hir_path(ctx, path); | 157 | let (ty, res_) = self.lower_path(path); |
155 | res = res_; | 158 | res = res_; |
156 | ty | 159 | ty |
157 | } | 160 | } |
158 | TypeRef::RawPtr(inner, mutability) => { | 161 | TypeRef::RawPtr(inner, mutability) => { |
159 | let inner_ty = Ty::from_hir(ctx, inner); | 162 | let inner_ty = self.lower_ty(inner); |
160 | Ty::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) | 163 | TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner) |
161 | } | 164 | } |
162 | TypeRef::Array(inner) => { | 165 | TypeRef::Array(inner) => { |
163 | let inner_ty = Ty::from_hir(ctx, inner); | 166 | let inner_ty = self.lower_ty(inner); |
164 | Ty::Array(Substs::single(inner_ty)) | 167 | TyKind::Array(inner_ty).intern(&Interner) |
165 | } | 168 | } |
166 | TypeRef::Slice(inner) => { | 169 | TypeRef::Slice(inner) => { |
167 | let inner_ty = Ty::from_hir(ctx, inner); | 170 | let inner_ty = self.lower_ty(inner); |
168 | Ty::Slice(Substs::single(inner_ty)) | 171 | TyKind::Slice(inner_ty).intern(&Interner) |
169 | } | 172 | } |
170 | TypeRef::Reference(inner, _, mutability) => { | 173 | TypeRef::Reference(inner, _, mutability) => { |
171 | let inner_ty = Ty::from_hir(ctx, inner); | 174 | let inner_ty = self.lower_ty(inner); |
172 | Ty::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) | 175 | TyKind::Ref(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner) |
173 | } | 176 | } |
174 | TypeRef::Placeholder => Ty::Unknown, | 177 | TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), |
175 | TypeRef::Fn(params, is_varargs) => { | 178 | TypeRef::Fn(params, is_varargs) => { |
176 | let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); | 179 | let substs = Substs(params.iter().map(|tr| self.lower_ty(tr)).collect()); |
177 | Ty::Function(FnPointer { | 180 | TyKind::Function(FnPointer { |
178 | num_args: substs.len() - 1, | 181 | num_args: substs.len() - 1, |
179 | sig: FnSig { variadic: *is_varargs }, | 182 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs }, |
180 | substs, | 183 | substs, |
181 | }) | 184 | }) |
185 | .intern(&Interner) | ||
182 | } | 186 | } |
183 | TypeRef::DynTrait(bounds) => { | 187 | TypeRef::DynTrait(bounds) => { |
184 | let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | 188 | let self_ty = |
185 | let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { | 189 | TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); |
186 | bounds | 190 | let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
187 | .iter() | 191 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() |
188 | .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) | ||
189 | .collect() | ||
190 | }); | 192 | }); |
191 | Ty::Dyn(predicates) | 193 | TyKind::Dyn(predicates).intern(&Interner) |
192 | } | 194 | } |
193 | TypeRef::ImplTrait(bounds) => { | 195 | TypeRef::ImplTrait(bounds) => { |
194 | match ctx.impl_trait_mode { | 196 | match self.impl_trait_mode { |
195 | ImplTraitLoweringMode::Opaque => { | 197 | ImplTraitLoweringMode::Opaque => { |
196 | let idx = ctx.impl_trait_counter.get(); | 198 | let idx = self.impl_trait_counter.get(); |
197 | ctx.impl_trait_counter.set(idx + 1); | 199 | self.impl_trait_counter.set(idx + 1); |
198 | 200 | ||
199 | assert!(idx as usize == ctx.opaque_type_data.borrow().len()); | 201 | assert!(idx as usize == self.opaque_type_data.borrow().len()); |
200 | // this dance is to make sure the data is in the right | 202 | // this dance is to make sure the data is in the right |
201 | // place even if we encounter more opaque types while | 203 | // place even if we encounter more opaque types while |
202 | // lowering the bounds | 204 | // lowering the bounds |
203 | ctx.opaque_type_data | 205 | self.opaque_type_data |
204 | .borrow_mut() | 206 | .borrow_mut() |
205 | .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); | 207 | .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); |
206 | // We don't want to lower the bounds inside the binders | 208 | // We don't want to lower the bounds inside the binders |
@@ -212,65 +214,70 @@ impl Ty { | |||
212 | // other, but separately. So if the `T` refers to a type | 214 | // other, but separately. So if the `T` refers to a type |
213 | // parameter of the outer function, it's just one binder | 215 | // parameter of the outer function, it's just one binder |
214 | // away instead of two. | 216 | // away instead of two. |
215 | let actual_opaque_type_data = ctx | 217 | let actual_opaque_type_data = self |
216 | .with_debruijn(DebruijnIndex::INNERMOST, |ctx| { | 218 | .with_debruijn(DebruijnIndex::INNERMOST, |ctx| { |
217 | ReturnTypeImplTrait::from_hir(ctx, &bounds) | 219 | ctx.lower_impl_trait(&bounds) |
218 | }); | 220 | }); |
219 | ctx.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data; | 221 | self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data; |
220 | 222 | ||
221 | let func = match ctx.resolver.generic_def() { | 223 | let func = match self.resolver.generic_def() { |
222 | Some(GenericDefId::FunctionId(f)) => f, | 224 | Some(GenericDefId::FunctionId(f)) => f, |
223 | _ => panic!("opaque impl trait lowering in non-function"), | 225 | _ => panic!("opaque impl trait lowering in non-function"), |
224 | }; | 226 | }; |
225 | let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); | 227 | let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx); |
226 | let generics = generics(ctx.db.upcast(), func.into()); | 228 | let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into(); |
227 | let parameters = Substs::bound_vars(&generics, ctx.in_binders); | 229 | let generics = generics(self.db.upcast(), func.into()); |
228 | Ty::Alias(AliasTy::Opaque(OpaqueTy { | 230 | let parameters = Substs::bound_vars(&generics, self.in_binders); |
229 | opaque_ty_id: impl_trait_id, | 231 | TyKind::Alias(AliasTy::Opaque(OpaqueTy { |
230 | parameters, | 232 | opaque_ty_id, |
233 | substitution: parameters, | ||
231 | })) | 234 | })) |
235 | .intern(&Interner) | ||
232 | } | 236 | } |
233 | ImplTraitLoweringMode::Param => { | 237 | ImplTraitLoweringMode::Param => { |
234 | let idx = ctx.impl_trait_counter.get(); | 238 | let idx = self.impl_trait_counter.get(); |
235 | // FIXME we're probably doing something wrong here | 239 | // FIXME we're probably doing something wrong here |
236 | ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); | 240 | self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); |
237 | if let Some(def) = ctx.resolver.generic_def() { | 241 | if let Some(def) = self.resolver.generic_def() { |
238 | let generics = generics(ctx.db.upcast(), def); | 242 | let generics = generics(self.db.upcast(), def); |
239 | let param = generics | 243 | let param = generics |
240 | .iter() | 244 | .iter() |
241 | .filter(|(_, data)| { | 245 | .filter(|(_, data)| { |
242 | data.provenance == TypeParamProvenance::ArgumentImplTrait | 246 | data.provenance == TypeParamProvenance::ArgumentImplTrait |
243 | }) | 247 | }) |
244 | .nth(idx as usize) | 248 | .nth(idx as usize) |
245 | .map_or(Ty::Unknown, |(id, _)| Ty::Placeholder(id)); | 249 | .map_or(TyKind::Unknown, |(id, _)| { |
246 | param | 250 | TyKind::Placeholder(to_placeholder_idx(self.db, id)) |
251 | }); | ||
252 | param.intern(&Interner) | ||
247 | } else { | 253 | } else { |
248 | Ty::Unknown | 254 | TyKind::Unknown.intern(&Interner) |
249 | } | 255 | } |
250 | } | 256 | } |
251 | ImplTraitLoweringMode::Variable => { | 257 | ImplTraitLoweringMode::Variable => { |
252 | let idx = ctx.impl_trait_counter.get(); | 258 | let idx = self.impl_trait_counter.get(); |
253 | // FIXME we're probably doing something wrong here | 259 | // FIXME we're probably doing something wrong here |
254 | ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); | 260 | self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); |
255 | let (parent_params, self_params, list_params, _impl_trait_params) = | 261 | let (parent_params, self_params, list_params, _impl_trait_params) = |
256 | if let Some(def) = ctx.resolver.generic_def() { | 262 | if let Some(def) = self.resolver.generic_def() { |
257 | let generics = generics(ctx.db.upcast(), def); | 263 | let generics = generics(self.db.upcast(), def); |
258 | generics.provenance_split() | 264 | generics.provenance_split() |
259 | } else { | 265 | } else { |
260 | (0, 0, 0, 0) | 266 | (0, 0, 0, 0) |
261 | }; | 267 | }; |
262 | Ty::BoundVar(BoundVar::new( | 268 | TyKind::BoundVar(BoundVar::new( |
263 | ctx.in_binders, | 269 | self.in_binders, |
264 | idx as usize + parent_params + self_params + list_params, | 270 | idx as usize + parent_params + self_params + list_params, |
265 | )) | 271 | )) |
272 | .intern(&Interner) | ||
266 | } | 273 | } |
267 | ImplTraitLoweringMode::Disallowed => { | 274 | ImplTraitLoweringMode::Disallowed => { |
268 | // FIXME: report error | 275 | // FIXME: report error |
269 | Ty::Unknown | 276 | TyKind::Unknown.intern(&Interner) |
270 | } | 277 | } |
271 | } | 278 | } |
272 | } | 279 | } |
273 | TypeRef::Error => Ty::Unknown, | 280 | TypeRef::Error => TyKind::Unknown.intern(&Interner), |
274 | }; | 281 | }; |
275 | (ty, res) | 282 | (ty, res) |
276 | } | 283 | } |
@@ -278,7 +285,7 @@ impl Ty { | |||
278 | /// This is only for `generic_predicates_for_param`, where we can't just | 285 | /// This is only for `generic_predicates_for_param`, where we can't just |
279 | /// lower the self types of the predicates since that could lead to cycles. | 286 | /// lower the self types of the predicates since that could lead to cycles. |
280 | /// So we just check here if the `type_ref` resolves to a generic param, and which. | 287 | /// So we just check here if the `type_ref` resolves to a generic param, and which. |
281 | fn from_hir_only_param(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> Option<TypeParamId> { | 288 | fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeParamId> { |
282 | let path = match type_ref { | 289 | let path = match type_ref { |
283 | TypeRef::Path(path) => path, | 290 | TypeRef::Path(path) => path, |
284 | _ => return None, | 291 | _ => return None, |
@@ -290,7 +297,7 @@ impl Ty { | |||
290 | return None; | 297 | return None; |
291 | } | 298 | } |
292 | let resolution = | 299 | let resolution = |
293 | match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) { | 300 | match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { |
294 | Some((it, None)) => it, | 301 | Some((it, None)) => it, |
295 | _ => return None, | 302 | _ => return None, |
296 | }; | 303 | }; |
@@ -301,8 +308,8 @@ impl Ty { | |||
301 | } | 308 | } |
302 | } | 309 | } |
303 | 310 | ||
304 | pub(crate) fn from_type_relative_path( | 311 | pub(crate) fn lower_ty_relative_path( |
305 | ctx: &TyLoweringContext<'_>, | 312 | &self, |
306 | ty: Ty, | 313 | ty: Ty, |
307 | // We need the original resolution to lower `Self::AssocTy` correctly | 314 | // We need the original resolution to lower `Self::AssocTy` correctly |
308 | res: Option<TypeNs>, | 315 | res: Option<TypeNs>, |
@@ -311,17 +318,17 @@ impl Ty { | |||
311 | if remaining_segments.len() == 1 { | 318 | if remaining_segments.len() == 1 { |
312 | // resolve unselected assoc types | 319 | // resolve unselected assoc types |
313 | let segment = remaining_segments.first().unwrap(); | 320 | let segment = remaining_segments.first().unwrap(); |
314 | (Ty::select_associated_type(ctx, res, segment), None) | 321 | (self.select_associated_type(res, segment), None) |
315 | } else if remaining_segments.len() > 1 { | 322 | } else if remaining_segments.len() > 1 { |
316 | // FIXME report error (ambiguous associated type) | 323 | // FIXME report error (ambiguous associated type) |
317 | (Ty::Unknown, None) | 324 | (TyKind::Unknown.intern(&Interner), None) |
318 | } else { | 325 | } else { |
319 | (ty, res) | 326 | (ty, res) |
320 | } | 327 | } |
321 | } | 328 | } |
322 | 329 | ||
323 | pub(crate) fn from_partly_resolved_hir_path( | 330 | pub(crate) fn lower_partly_resolved_path( |
324 | ctx: &TyLoweringContext<'_>, | 331 | &self, |
325 | resolution: TypeNs, | 332 | resolution: TypeNs, |
326 | resolved_segment: PathSegment<'_>, | 333 | resolved_segment: PathSegment<'_>, |
327 | remaining_segments: PathSegments<'_>, | 334 | remaining_segments: PathSegments<'_>, |
@@ -331,103 +338,109 @@ impl Ty { | |||
331 | TypeNs::TraitId(trait_) => { | 338 | TypeNs::TraitId(trait_) => { |
332 | // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there | 339 | // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there |
333 | let self_ty = if remaining_segments.len() == 0 { | 340 | let self_ty = if remaining_segments.len() == 0 { |
334 | Some(Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))) | 341 | Some( |
342 | TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) | ||
343 | .intern(&Interner), | ||
344 | ) | ||
335 | } else { | 345 | } else { |
336 | None | 346 | None |
337 | }; | 347 | }; |
338 | let trait_ref = | 348 | let trait_ref = |
339 | TraitRef::from_resolved_path(ctx, trait_, resolved_segment, self_ty); | 349 | self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty); |
340 | let ty = if remaining_segments.len() == 1 { | 350 | let ty = if remaining_segments.len() == 1 { |
341 | let segment = remaining_segments.first().unwrap(); | 351 | let segment = remaining_segments.first().unwrap(); |
342 | let found = associated_type_by_name_including_super_traits( | 352 | let found = associated_type_by_name_including_super_traits( |
343 | ctx.db, | 353 | self.db, |
344 | trait_ref, | 354 | trait_ref, |
345 | &segment.name, | 355 | &segment.name, |
346 | ); | 356 | ); |
347 | match found { | 357 | match found { |
348 | Some((super_trait_ref, associated_ty)) => { | 358 | Some((super_trait_ref, associated_ty)) => { |
349 | // FIXME handle type parameters on the segment | 359 | // FIXME handle type parameters on the segment |
350 | Ty::Alias(AliasTy::Projection(ProjectionTy { | 360 | TyKind::Alias(AliasTy::Projection(ProjectionTy { |
351 | associated_ty, | 361 | associated_ty_id: to_assoc_type_id(associated_ty), |
352 | parameters: super_trait_ref.substs, | 362 | substitution: super_trait_ref.substs, |
353 | })) | 363 | })) |
364 | .intern(&Interner) | ||
354 | } | 365 | } |
355 | None => { | 366 | None => { |
356 | // FIXME: report error (associated type not found) | 367 | // FIXME: report error (associated type not found) |
357 | Ty::Unknown | 368 | TyKind::Unknown.intern(&Interner) |
358 | } | 369 | } |
359 | } | 370 | } |
360 | } else if remaining_segments.len() > 1 { | 371 | } else if remaining_segments.len() > 1 { |
361 | // FIXME report error (ambiguous associated type) | 372 | // FIXME report error (ambiguous associated type) |
362 | Ty::Unknown | 373 | TyKind::Unknown.intern(&Interner) |
363 | } else { | 374 | } else { |
364 | Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) | 375 | TyKind::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) |
376 | .intern(&Interner) | ||
365 | }; | 377 | }; |
366 | return (ty, None); | 378 | return (ty, None); |
367 | } | 379 | } |
368 | TypeNs::GenericParam(param_id) => { | 380 | TypeNs::GenericParam(param_id) => { |
369 | let generics = generics( | 381 | let generics = generics( |
370 | ctx.db.upcast(), | 382 | self.db.upcast(), |
371 | ctx.resolver.generic_def().expect("generics in scope"), | 383 | self.resolver.generic_def().expect("generics in scope"), |
372 | ); | 384 | ); |
373 | match ctx.type_param_mode { | 385 | match self.type_param_mode { |
374 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), | 386 | TypeParamLoweringMode::Placeholder => { |
387 | TyKind::Placeholder(to_placeholder_idx(self.db, param_id)) | ||
388 | } | ||
375 | TypeParamLoweringMode::Variable => { | 389 | TypeParamLoweringMode::Variable => { |
376 | let idx = generics.param_idx(param_id).expect("matching generics"); | 390 | let idx = generics.param_idx(param_id).expect("matching generics"); |
377 | Ty::BoundVar(BoundVar::new(ctx.in_binders, idx)) | 391 | TyKind::BoundVar(BoundVar::new(self.in_binders, idx)) |
378 | } | 392 | } |
379 | } | 393 | } |
394 | .intern(&Interner) | ||
380 | } | 395 | } |
381 | TypeNs::SelfType(impl_id) => { | 396 | TypeNs::SelfType(impl_id) => { |
382 | let generics = generics(ctx.db.upcast(), impl_id.into()); | 397 | let generics = generics(self.db.upcast(), impl_id.into()); |
383 | let substs = match ctx.type_param_mode { | 398 | let substs = match self.type_param_mode { |
384 | TypeParamLoweringMode::Placeholder => { | 399 | TypeParamLoweringMode::Placeholder => { |
385 | Substs::type_params_for_generics(&generics) | 400 | Substs::type_params_for_generics(self.db, &generics) |
386 | } | 401 | } |
387 | TypeParamLoweringMode::Variable => { | 402 | TypeParamLoweringMode::Variable => { |
388 | Substs::bound_vars(&generics, ctx.in_binders) | 403 | Substs::bound_vars(&generics, self.in_binders) |
389 | } | 404 | } |
390 | }; | 405 | }; |
391 | ctx.db.impl_self_ty(impl_id).subst(&substs) | 406 | self.db.impl_self_ty(impl_id).subst(&substs) |
392 | } | 407 | } |
393 | TypeNs::AdtSelfType(adt) => { | 408 | TypeNs::AdtSelfType(adt) => { |
394 | let generics = generics(ctx.db.upcast(), adt.into()); | 409 | let generics = generics(self.db.upcast(), adt.into()); |
395 | let substs = match ctx.type_param_mode { | 410 | let substs = match self.type_param_mode { |
396 | TypeParamLoweringMode::Placeholder => { | 411 | TypeParamLoweringMode::Placeholder => { |
397 | Substs::type_params_for_generics(&generics) | 412 | Substs::type_params_for_generics(self.db, &generics) |
398 | } | 413 | } |
399 | TypeParamLoweringMode::Variable => { | 414 | TypeParamLoweringMode::Variable => { |
400 | Substs::bound_vars(&generics, ctx.in_binders) | 415 | Substs::bound_vars(&generics, self.in_binders) |
401 | } | 416 | } |
402 | }; | 417 | }; |
403 | ctx.db.ty(adt.into()).subst(&substs) | 418 | self.db.ty(adt.into()).subst(&substs) |
404 | } | 419 | } |
405 | 420 | ||
406 | TypeNs::AdtId(it) => { | 421 | TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args), |
407 | Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) | ||
408 | } | ||
409 | TypeNs::BuiltinType(it) => { | 422 | TypeNs::BuiltinType(it) => { |
410 | Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) | 423 | self.lower_path_inner(resolved_segment, it.into(), infer_args) |
411 | } | 424 | } |
412 | TypeNs::TypeAliasId(it) => { | 425 | TypeNs::TypeAliasId(it) => { |
413 | Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) | 426 | self.lower_path_inner(resolved_segment, it.into(), infer_args) |
414 | } | 427 | } |
415 | // FIXME: report error | 428 | // FIXME: report error |
416 | TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), | 429 | TypeNs::EnumVariantId(_) => return (TyKind::Unknown.intern(&Interner), None), |
417 | }; | 430 | }; |
418 | Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) | 431 | self.lower_ty_relative_path(ty, Some(resolution), remaining_segments) |
419 | } | 432 | } |
420 | 433 | ||
421 | pub(crate) fn from_hir_path(ctx: &TyLoweringContext<'_>, path: &Path) -> (Ty, Option<TypeNs>) { | 434 | pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) { |
422 | // Resolve the path (in type namespace) | 435 | // Resolve the path (in type namespace) |
423 | if let Some(type_ref) = path.type_anchor() { | 436 | if let Some(type_ref) = path.type_anchor() { |
424 | let (ty, res) = Ty::from_hir_ext(ctx, &type_ref); | 437 | let (ty, res) = self.lower_ty_ext(&type_ref); |
425 | return Ty::from_type_relative_path(ctx, ty, res, path.segments()); | 438 | return self.lower_ty_relative_path(ty, res, path.segments()); |
426 | } | 439 | } |
427 | let (resolution, remaining_index) = | 440 | let (resolution, remaining_index) = |
428 | match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) { | 441 | match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { |
429 | Some(it) => it, | 442 | Some(it) => it, |
430 | None => return (Ty::Unknown, None), | 443 | None => return (TyKind::Unknown.intern(&Interner), None), |
431 | }; | 444 | }; |
432 | let (resolved_segment, remaining_segments) = match remaining_index { | 445 | let (resolved_segment, remaining_segments) = match remaining_index { |
433 | None => ( | 446 | None => ( |
@@ -436,31 +449,23 @@ impl Ty { | |||
436 | ), | 449 | ), |
437 | Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), | 450 | Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), |
438 | }; | 451 | }; |
439 | Ty::from_partly_resolved_hir_path( | 452 | self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false) |
440 | ctx, | ||
441 | resolution, | ||
442 | resolved_segment, | ||
443 | remaining_segments, | ||
444 | false, | ||
445 | ) | ||
446 | } | 453 | } |
447 | 454 | ||
448 | fn select_associated_type( | 455 | fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty { |
449 | ctx: &TyLoweringContext<'_>, | ||
450 | res: Option<TypeNs>, | ||
451 | segment: PathSegment<'_>, | ||
452 | ) -> Ty { | ||
453 | if let Some(res) = res { | 456 | if let Some(res) = res { |
454 | let ty = | 457 | let ty = associated_type_shorthand_candidates( |
455 | associated_type_shorthand_candidates(ctx.db, res, move |name, t, associated_ty| { | 458 | self.db, |
459 | res, | ||
460 | move |name, t, associated_ty| { | ||
456 | if name == segment.name { | 461 | if name == segment.name { |
457 | let substs = match ctx.type_param_mode { | 462 | let substs = match self.type_param_mode { |
458 | TypeParamLoweringMode::Placeholder => { | 463 | TypeParamLoweringMode::Placeholder => { |
459 | // if we're lowering to placeholders, we have to put | 464 | // if we're lowering to placeholders, we have to put |
460 | // them in now | 465 | // them in now |
461 | let s = Substs::type_params( | 466 | let s = Substs::type_params( |
462 | ctx.db, | 467 | self.db, |
463 | ctx.resolver.generic_def().expect( | 468 | self.resolver.generic_def().expect( |
464 | "there should be generics if there's a generic param", | 469 | "there should be generics if there's a generic param", |
465 | ), | 470 | ), |
466 | ); | 471 | ); |
@@ -470,25 +475,29 @@ impl Ty { | |||
470 | }; | 475 | }; |
471 | // We need to shift in the bound vars, since | 476 | // We need to shift in the bound vars, since |
472 | // associated_type_shorthand_candidates does not do that | 477 | // associated_type_shorthand_candidates does not do that |
473 | let substs = substs.shift_bound_vars(ctx.in_binders); | 478 | let substs = substs.shift_bound_vars(self.in_binders); |
474 | // FIXME handle type parameters on the segment | 479 | // FIXME handle type parameters on the segment |
475 | return Some(Ty::Alias(AliasTy::Projection(ProjectionTy { | 480 | return Some( |
476 | associated_ty, | 481 | TyKind::Alias(AliasTy::Projection(ProjectionTy { |
477 | parameters: substs, | 482 | associated_ty_id: to_assoc_type_id(associated_ty), |
478 | }))); | 483 | substitution: substs, |
484 | })) | ||
485 | .intern(&Interner), | ||
486 | ); | ||
479 | } | 487 | } |
480 | 488 | ||
481 | None | 489 | None |
482 | }); | 490 | }, |
491 | ); | ||
483 | 492 | ||
484 | ty.unwrap_or(Ty::Unknown) | 493 | ty.unwrap_or(TyKind::Unknown.intern(&Interner)) |
485 | } else { | 494 | } else { |
486 | Ty::Unknown | 495 | TyKind::Unknown.intern(&Interner) |
487 | } | 496 | } |
488 | } | 497 | } |
489 | 498 | ||
490 | fn from_hir_path_inner( | 499 | fn lower_path_inner( |
491 | ctx: &TyLoweringContext<'_>, | 500 | &self, |
492 | segment: PathSegment<'_>, | 501 | segment: PathSegment<'_>, |
493 | typeable: TyDefId, | 502 | typeable: TyDefId, |
494 | infer_args: bool, | 503 | infer_args: bool, |
@@ -498,14 +507,14 @@ impl Ty { | |||
498 | TyDefId::AdtId(it) => Some(it.into()), | 507 | TyDefId::AdtId(it) => Some(it.into()), |
499 | TyDefId::TypeAliasId(it) => Some(it.into()), | 508 | TyDefId::TypeAliasId(it) => Some(it.into()), |
500 | }; | 509 | }; |
501 | let substs = substs_from_path_segment(ctx, segment, generic_def, infer_args); | 510 | let substs = self.substs_from_path_segment(segment, generic_def, infer_args); |
502 | ctx.db.ty(typeable).subst(&substs) | 511 | self.db.ty(typeable).subst(&substs) |
503 | } | 512 | } |
504 | 513 | ||
505 | /// Collect generic arguments from a path into a `Substs`. See also | 514 | /// Collect generic arguments from a path into a `Substs`. See also |
506 | /// `create_substs_for_ast_path` and `def_to_ty` in rustc. | 515 | /// `create_substs_for_ast_path` and `def_to_ty` in rustc. |
507 | pub(super) fn substs_from_path( | 516 | pub(super) fn substs_from_path( |
508 | ctx: &TyLoweringContext<'_>, | 517 | &self, |
509 | path: &Path, | 518 | path: &Path, |
510 | // Note that we don't call `db.value_type(resolved)` here, | 519 | // Note that we don't call `db.value_type(resolved)` here, |
511 | // `ValueTyDefId` is just a convenient way to pass generics and | 520 | // `ValueTyDefId` is just a convenient way to pass generics and |
@@ -535,169 +544,161 @@ impl Ty { | |||
535 | (segment, Some(var.parent.into())) | 544 | (segment, Some(var.parent.into())) |
536 | } | 545 | } |
537 | }; | 546 | }; |
538 | substs_from_path_segment(ctx, segment, generic_def, infer_args) | 547 | self.substs_from_path_segment(segment, generic_def, infer_args) |
539 | } | 548 | } |
540 | } | ||
541 | 549 | ||
542 | fn substs_from_path_segment( | 550 | fn substs_from_path_segment( |
543 | ctx: &TyLoweringContext<'_>, | 551 | &self, |
544 | segment: PathSegment<'_>, | 552 | segment: PathSegment<'_>, |
545 | def_generic: Option<GenericDefId>, | 553 | def_generic: Option<GenericDefId>, |
546 | infer_args: bool, | 554 | infer_args: bool, |
547 | ) -> Substs { | 555 | ) -> Substs { |
548 | let mut substs = Vec::new(); | 556 | let mut substs = Vec::new(); |
549 | let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def)); | 557 | let def_generics = def_generic.map(|def| generics(self.db.upcast(), def)); |
550 | 558 | ||
551 | let (parent_params, self_params, type_params, impl_trait_params) = | 559 | let (parent_params, self_params, type_params, impl_trait_params) = |
552 | def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); | 560 | def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); |
553 | let total_len = parent_params + self_params + type_params + impl_trait_params; | 561 | let total_len = parent_params + self_params + type_params + impl_trait_params; |
554 | 562 | ||
555 | substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); | 563 | substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params)); |
556 | 564 | ||
557 | let mut had_explicit_type_args = false; | 565 | let mut had_explicit_type_args = false; |
558 | 566 | ||
559 | if let Some(generic_args) = &segment.args_and_bindings { | 567 | if let Some(generic_args) = &segment.args_and_bindings { |
560 | if !generic_args.has_self_type { | 568 | if !generic_args.has_self_type { |
561 | substs.extend(iter::repeat(Ty::Unknown).take(self_params)); | 569 | substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params)); |
562 | } | 570 | } |
563 | let expected_num = | 571 | let expected_num = |
564 | if generic_args.has_self_type { self_params + type_params } else { type_params }; | 572 | if generic_args.has_self_type { self_params + type_params } else { type_params }; |
565 | let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 }; | 573 | let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 }; |
566 | // if args are provided, it should be all of them, but we can't rely on that | 574 | // if args are provided, it should be all of them, but we can't rely on that |
567 | for arg in generic_args | 575 | for arg in generic_args |
568 | .args | 576 | .args |
569 | .iter() | 577 | .iter() |
570 | .filter(|arg| matches!(arg, GenericArg::Type(_))) | 578 | .filter(|arg| matches!(arg, GenericArg::Type(_))) |
571 | .skip(skip) | 579 | .skip(skip) |
572 | .take(expected_num) | 580 | .take(expected_num) |
573 | { | 581 | { |
574 | match arg { | 582 | match arg { |
575 | GenericArg::Type(type_ref) => { | 583 | GenericArg::Type(type_ref) => { |
576 | had_explicit_type_args = true; | 584 | had_explicit_type_args = true; |
577 | let ty = Ty::from_hir(ctx, type_ref); | 585 | let ty = self.lower_ty(type_ref); |
578 | substs.push(ty); | 586 | substs.push(ty); |
587 | } | ||
588 | GenericArg::Lifetime(_) => {} | ||
579 | } | 589 | } |
580 | GenericArg::Lifetime(_) => {} | ||
581 | } | 590 | } |
582 | } | 591 | } |
583 | } | ||
584 | 592 | ||
585 | // handle defaults. In expression or pattern path segments without | 593 | // handle defaults. In expression or pattern path segments without |
586 | // explicitly specified type arguments, missing type arguments are inferred | 594 | // explicitly specified type arguments, missing type arguments are inferred |
587 | // (i.e. defaults aren't used). | 595 | // (i.e. defaults aren't used). |
588 | if !infer_args || had_explicit_type_args { | 596 | if !infer_args || had_explicit_type_args { |
589 | if let Some(def_generic) = def_generic { | 597 | if let Some(def_generic) = def_generic { |
590 | let defaults = ctx.db.generic_defaults(def_generic); | 598 | let defaults = self.db.generic_defaults(def_generic); |
591 | assert_eq!(total_len, defaults.len()); | 599 | assert_eq!(total_len, defaults.len()); |
592 | 600 | ||
593 | for default_ty in defaults.iter().skip(substs.len()) { | 601 | for default_ty in defaults.iter().skip(substs.len()) { |
594 | // each default can depend on the previous parameters | 602 | // each default can depend on the previous parameters |
595 | let substs_so_far = Substs(substs.clone().into()); | 603 | let substs_so_far = Substs(substs.clone().into()); |
596 | substs.push(default_ty.clone().subst(&substs_so_far)); | 604 | substs.push(default_ty.clone().subst(&substs_so_far)); |
605 | } | ||
597 | } | 606 | } |
598 | } | 607 | } |
599 | } | ||
600 | 608 | ||
601 | // add placeholders for args that were not provided | 609 | // add placeholders for args that were not provided |
602 | // FIXME: emit diagnostics in contexts where this is not allowed | 610 | // FIXME: emit diagnostics in contexts where this is not allowed |
603 | for _ in substs.len()..total_len { | 611 | for _ in substs.len()..total_len { |
604 | substs.push(Ty::Unknown); | 612 | substs.push(TyKind::Unknown.intern(&Interner)); |
605 | } | 613 | } |
606 | assert_eq!(substs.len(), total_len); | 614 | assert_eq!(substs.len(), total_len); |
607 | 615 | ||
608 | Substs(substs.into()) | 616 | Substs(substs.into()) |
609 | } | 617 | } |
610 | 618 | ||
611 | impl TraitRef { | 619 | fn lower_trait_ref_from_path( |
612 | fn from_path( | 620 | &self, |
613 | ctx: &TyLoweringContext<'_>, | ||
614 | path: &Path, | 621 | path: &Path, |
615 | explicit_self_ty: Option<Ty>, | 622 | explicit_self_ty: Option<Ty>, |
616 | ) -> Option<Self> { | 623 | ) -> Option<TraitRef> { |
617 | let resolved = | 624 | let resolved = |
618 | match ctx.resolver.resolve_path_in_type_ns_fully(ctx.db.upcast(), path.mod_path())? { | 625 | match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? { |
619 | TypeNs::TraitId(tr) => tr, | 626 | TypeNs::TraitId(tr) => tr, |
620 | _ => return None, | 627 | _ => return None, |
621 | }; | 628 | }; |
622 | let segment = path.segments().last().expect("path should have at least one segment"); | 629 | let segment = path.segments().last().expect("path should have at least one segment"); |
623 | Some(TraitRef::from_resolved_path(ctx, resolved, segment, explicit_self_ty)) | 630 | Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty)) |
624 | } | 631 | } |
625 | 632 | ||
626 | pub(crate) fn from_resolved_path( | 633 | pub(crate) fn lower_trait_ref_from_resolved_path( |
627 | ctx: &TyLoweringContext<'_>, | 634 | &self, |
628 | resolved: TraitId, | 635 | resolved: TraitId, |
629 | segment: PathSegment<'_>, | 636 | segment: PathSegment<'_>, |
630 | explicit_self_ty: Option<Ty>, | 637 | explicit_self_ty: Option<Ty>, |
631 | ) -> Self { | 638 | ) -> TraitRef { |
632 | let mut substs = TraitRef::substs_from_path(ctx, segment, resolved); | 639 | let mut substs = self.trait_ref_substs_from_path(segment, resolved); |
633 | if let Some(self_ty) = explicit_self_ty { | 640 | if let Some(self_ty) = explicit_self_ty { |
634 | make_mut_slice(&mut substs.0)[0] = self_ty; | 641 | make_mut_slice(&mut substs.0)[0] = self_ty; |
635 | } | 642 | } |
636 | TraitRef { trait_: resolved, substs } | 643 | TraitRef { trait_: resolved, substs } |
637 | } | 644 | } |
638 | 645 | ||
639 | fn from_hir( | 646 | fn lower_trait_ref( |
640 | ctx: &TyLoweringContext<'_>, | 647 | &self, |
641 | type_ref: &TypeRef, | 648 | type_ref: &TypeRef, |
642 | explicit_self_ty: Option<Ty>, | 649 | explicit_self_ty: Option<Ty>, |
643 | ) -> Option<Self> { | 650 | ) -> Option<TraitRef> { |
644 | let path = match type_ref { | 651 | let path = match type_ref { |
645 | TypeRef::Path(path) => path, | 652 | TypeRef::Path(path) => path, |
646 | _ => return None, | 653 | _ => return None, |
647 | }; | 654 | }; |
648 | TraitRef::from_path(ctx, path, explicit_self_ty) | 655 | self.lower_trait_ref_from_path(path, explicit_self_ty) |
649 | } | 656 | } |
650 | 657 | ||
651 | fn substs_from_path( | 658 | fn trait_ref_substs_from_path(&self, segment: PathSegment<'_>, resolved: TraitId) -> Substs { |
652 | ctx: &TyLoweringContext<'_>, | 659 | self.substs_from_path_segment(segment, Some(resolved.into()), false) |
653 | segment: PathSegment<'_>, | ||
654 | resolved: TraitId, | ||
655 | ) -> Substs { | ||
656 | substs_from_path_segment(ctx, segment, Some(resolved.into()), false) | ||
657 | } | 660 | } |
658 | } | ||
659 | 661 | ||
660 | impl GenericPredicate { | 662 | pub(crate) fn lower_where_predicate( |
661 | pub(crate) fn from_where_predicate<'a>( | 663 | &'a self, |
662 | ctx: &'a TyLoweringContext<'a>, | ||
663 | where_predicate: &'a WherePredicate, | 664 | where_predicate: &'a WherePredicate, |
664 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 665 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
665 | match where_predicate { | 666 | match where_predicate { |
666 | WherePredicate::ForLifetime { target, bound, .. } | 667 | WherePredicate::ForLifetime { target, bound, .. } |
667 | | WherePredicate::TypeBound { target, bound } => { | 668 | | WherePredicate::TypeBound { target, bound } => { |
668 | let self_ty = match target { | 669 | let self_ty = match target { |
669 | WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), | 670 | WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref), |
670 | WherePredicateTypeTarget::TypeParam(param_id) => { | 671 | WherePredicateTypeTarget::TypeParam(param_id) => { |
671 | let generic_def = ctx.resolver.generic_def().expect("generics in scope"); | 672 | let generic_def = self.resolver.generic_def().expect("generics in scope"); |
672 | let generics = generics(ctx.db.upcast(), generic_def); | 673 | let generics = generics(self.db.upcast(), generic_def); |
673 | let param_id = | 674 | let param_id = |
674 | hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; | 675 | hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; |
675 | match ctx.type_param_mode { | 676 | let placeholder = to_placeholder_idx(self.db, param_id); |
676 | TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), | 677 | match self.type_param_mode { |
678 | TypeParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder), | ||
677 | TypeParamLoweringMode::Variable => { | 679 | TypeParamLoweringMode::Variable => { |
678 | let idx = generics.param_idx(param_id).expect("matching generics"); | 680 | let idx = generics.param_idx(param_id).expect("matching generics"); |
679 | Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) | 681 | TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) |
680 | } | 682 | } |
681 | } | 683 | } |
684 | .intern(&Interner) | ||
682 | } | 685 | } |
683 | }; | 686 | }; |
684 | GenericPredicate::from_type_bound(ctx, bound, self_ty) | 687 | self.lower_type_bound(bound, self_ty).collect::<Vec<_>>().into_iter() |
685 | .collect::<Vec<_>>() | ||
686 | .into_iter() | ||
687 | } | 688 | } |
688 | WherePredicate::Lifetime { .. } => vec![].into_iter(), | 689 | WherePredicate::Lifetime { .. } => vec![].into_iter(), |
689 | } | 690 | } |
690 | } | 691 | } |
691 | 692 | ||
692 | pub(crate) fn from_type_bound<'a>( | 693 | pub(crate) fn lower_type_bound( |
693 | ctx: &'a TyLoweringContext<'a>, | 694 | &'a self, |
694 | bound: &'a TypeBound, | 695 | bound: &'a TypeBound, |
695 | self_ty: Ty, | 696 | self_ty: Ty, |
696 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 697 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
697 | let mut bindings = None; | 698 | let mut bindings = None; |
698 | let trait_ref = match bound { | 699 | let trait_ref = match bound { |
699 | TypeBound::Path(path) => { | 700 | TypeBound::Path(path) => { |
700 | bindings = TraitRef::from_path(ctx, path, Some(self_ty)); | 701 | bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); |
701 | Some( | 702 | Some( |
702 | bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented), | 703 | bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented), |
703 | ) | 704 | ) |
@@ -708,64 +709,62 @@ impl GenericPredicate { | |||
708 | trait_ref.into_iter().chain( | 709 | trait_ref.into_iter().chain( |
709 | bindings | 710 | bindings |
710 | .into_iter() | 711 | .into_iter() |
711 | .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)), | 712 | .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)), |
712 | ) | 713 | ) |
713 | } | 714 | } |
714 | } | ||
715 | 715 | ||
716 | fn assoc_type_bindings_from_type_bound<'a>( | 716 | fn assoc_type_bindings_from_type_bound( |
717 | ctx: &'a TyLoweringContext<'a>, | 717 | &'a self, |
718 | bound: &'a TypeBound, | 718 | bound: &'a TypeBound, |
719 | trait_ref: TraitRef, | 719 | trait_ref: TraitRef, |
720 | ) -> impl Iterator<Item = GenericPredicate> + 'a { | 720 | ) -> impl Iterator<Item = GenericPredicate> + 'a { |
721 | let last_segment = match bound { | 721 | let last_segment = match bound { |
722 | TypeBound::Path(path) => path.segments().last(), | 722 | TypeBound::Path(path) => path.segments().last(), |
723 | TypeBound::Error | TypeBound::Lifetime(_) => None, | 723 | TypeBound::Error | TypeBound::Lifetime(_) => None, |
724 | }; | 724 | }; |
725 | last_segment | 725 | last_segment |
726 | .into_iter() | 726 | .into_iter() |
727 | .flat_map(|segment| segment.args_and_bindings.into_iter()) | 727 | .flat_map(|segment| segment.args_and_bindings.into_iter()) |
728 | .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) | 728 | .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) |
729 | .flat_map(move |binding| { | 729 | .flat_map(move |binding| { |
730 | let found = associated_type_by_name_including_super_traits( | 730 | let found = associated_type_by_name_including_super_traits( |
731 | ctx.db, | 731 | self.db, |
732 | trait_ref.clone(), | 732 | trait_ref.clone(), |
733 | &binding.name, | 733 | &binding.name, |
734 | ); | 734 | ); |
735 | let (super_trait_ref, associated_ty) = match found { | 735 | let (super_trait_ref, associated_ty) = match found { |
736 | None => return SmallVec::<[GenericPredicate; 1]>::new(), | 736 | None => return SmallVec::<[GenericPredicate; 1]>::new(), |
737 | Some(t) => t, | 737 | Some(t) => t, |
738 | }; | 738 | }; |
739 | let projection_ty = ProjectionTy { associated_ty, parameters: super_trait_ref.substs }; | 739 | let projection_ty = ProjectionTy { |
740 | let mut preds = SmallVec::with_capacity( | 740 | associated_ty_id: to_assoc_type_id(associated_ty), |
741 | binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), | 741 | substitution: super_trait_ref.substs, |
742 | ); | 742 | }; |
743 | if let Some(type_ref) = &binding.type_ref { | 743 | let mut preds = SmallVec::with_capacity( |
744 | let ty = Ty::from_hir(ctx, type_ref); | 744 | binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), |
745 | let projection_predicate = | 745 | ); |
746 | ProjectionPredicate { projection_ty: projection_ty.clone(), ty }; | 746 | if let Some(type_ref) = &binding.type_ref { |
747 | preds.push(GenericPredicate::Projection(projection_predicate)); | 747 | let ty = self.lower_ty(type_ref); |
748 | } | 748 | let projection_predicate = |
749 | for bound in &binding.bounds { | 749 | ProjectionPredicate { projection_ty: projection_ty.clone(), ty }; |
750 | preds.extend(GenericPredicate::from_type_bound( | 750 | preds.push(GenericPredicate::Projection(projection_predicate)); |
751 | ctx, | 751 | } |
752 | bound, | 752 | for bound in &binding.bounds { |
753 | Ty::Alias(AliasTy::Projection(projection_ty.clone())), | 753 | preds.extend(self.lower_type_bound( |
754 | )); | 754 | bound, |
755 | } | 755 | TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner), |
756 | preds | 756 | )); |
757 | }) | 757 | } |
758 | } | 758 | preds |
759 | }) | ||
760 | } | ||
759 | 761 | ||
760 | impl ReturnTypeImplTrait { | 762 | fn lower_impl_trait(&self, bounds: &[TypeBound]) -> ReturnTypeImplTrait { |
761 | fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self { | ||
762 | cov_mark::hit!(lower_rpit); | 763 | cov_mark::hit!(lower_rpit); |
763 | let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | 764 | let self_ty = |
764 | let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { | 765 | TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner); |
765 | bounds | 766 | let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { |
766 | .iter() | 767 | bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect() |
767 | .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) | ||
768 | .collect() | ||
769 | }); | 768 | }); |
770 | ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } | 769 | ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } |
771 | } | 770 | } |
@@ -861,7 +860,7 @@ pub(crate) fn field_types_query( | |||
861 | let ctx = | 860 | let ctx = |
862 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 861 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
863 | for (field_id, field_data) in var_data.fields().iter() { | 862 | for (field_id, field_data) in var_data.fields().iter() { |
864 | res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref))) | 863 | res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref))) |
865 | } | 864 | } |
866 | Arc::new(res) | 865 | Arc::new(res) |
867 | } | 866 | } |
@@ -889,16 +888,13 @@ pub(crate) fn generic_predicates_for_param_query( | |||
889 | WherePredicate::ForLifetime { target, .. } | 888 | WherePredicate::ForLifetime { target, .. } |
890 | | WherePredicate::TypeBound { target, .. } => match target { | 889 | | WherePredicate::TypeBound { target, .. } => match target { |
891 | WherePredicateTypeTarget::TypeRef(type_ref) => { | 890 | WherePredicateTypeTarget::TypeRef(type_ref) => { |
892 | Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) | 891 | ctx.lower_ty_only_param(type_ref) == Some(param_id) |
893 | } | 892 | } |
894 | WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id, | 893 | WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id, |
895 | }, | 894 | }, |
896 | WherePredicate::Lifetime { .. } => false, | 895 | WherePredicate::Lifetime { .. } => false, |
897 | }) | 896 | }) |
898 | .flat_map(|pred| { | 897 | .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) |
899 | GenericPredicate::from_where_predicate(&ctx, pred) | ||
900 | .map(|p| Binders::new(generics.len(), p)) | ||
901 | }) | ||
902 | .collect() | 898 | .collect() |
903 | } | 899 | } |
904 | 900 | ||
@@ -910,41 +906,55 @@ pub(crate) fn generic_predicates_for_param_recover( | |||
910 | Arc::new([]) | 906 | Arc::new([]) |
911 | } | 907 | } |
912 | 908 | ||
913 | impl TraitEnvironment { | 909 | pub(crate) fn trait_environment_query( |
914 | pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { | 910 | db: &dyn HirDatabase, |
915 | let ctx = TyLoweringContext::new(db, &resolver) | 911 | def: GenericDefId, |
916 | .with_type_param_mode(TypeParamLoweringMode::Placeholder); | 912 | ) -> Arc<TraitEnvironment> { |
917 | let mut predicates = resolver | 913 | let resolver = def.resolver(db.upcast()); |
918 | .where_predicates_in_scope() | 914 | let ctx = TyLoweringContext::new(db, &resolver) |
919 | .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) | 915 | .with_type_param_mode(TypeParamLoweringMode::Placeholder); |
920 | .collect::<Vec<_>>(); | 916 | let mut traits_in_scope = Vec::new(); |
921 | 917 | let mut clauses = Vec::new(); | |
922 | if let Some(def) = resolver.generic_def() { | 918 | for pred in resolver.where_predicates_in_scope() { |
923 | let container: Option<AssocContainerId> = match def { | 919 | for pred in ctx.lower_where_predicate(pred) { |
924 | // FIXME: is there a function for this? | 920 | if pred.is_error() { |
925 | GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), | 921 | continue; |
926 | GenericDefId::AdtId(_) => None, | ||
927 | GenericDefId::TraitId(_) => None, | ||
928 | GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container), | ||
929 | GenericDefId::ImplId(_) => None, | ||
930 | GenericDefId::EnumVariantId(_) => None, | ||
931 | GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container), | ||
932 | }; | ||
933 | if let Some(AssocContainerId::TraitId(trait_id)) = container { | ||
934 | // add `Self: Trait<T1, T2, ...>` to the environment in trait | ||
935 | // function default implementations (and hypothetical code | ||
936 | // inside consts or type aliases) | ||
937 | cov_mark::hit!(trait_self_implements_self); | ||
938 | let substs = Substs::type_params(db, trait_id); | ||
939 | let trait_ref = TraitRef { trait_: trait_id, substs }; | ||
940 | let pred = GenericPredicate::Implemented(trait_ref); | ||
941 | |||
942 | predicates.push(pred); | ||
943 | } | 922 | } |
923 | if let GenericPredicate::Implemented(tr) = &pred { | ||
924 | traits_in_scope.push((tr.self_ty().clone(), tr.trait_)); | ||
925 | } | ||
926 | let program_clause: chalk_ir::ProgramClause<Interner> = | ||
927 | pred.clone().to_chalk(db).cast(&Interner); | ||
928 | clauses.push(program_clause.into_from_env_clause(&Interner)); | ||
944 | } | 929 | } |
930 | } | ||
945 | 931 | ||
946 | Arc::new(TraitEnvironment { predicates }) | 932 | let container: Option<AssocContainerId> = match def { |
933 | // FIXME: is there a function for this? | ||
934 | GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), | ||
935 | GenericDefId::AdtId(_) => None, | ||
936 | GenericDefId::TraitId(_) => None, | ||
937 | GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container), | ||
938 | GenericDefId::ImplId(_) => None, | ||
939 | GenericDefId::EnumVariantId(_) => None, | ||
940 | GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container), | ||
941 | }; | ||
942 | if let Some(AssocContainerId::TraitId(trait_id)) = container { | ||
943 | // add `Self: Trait<T1, T2, ...>` to the environment in trait | ||
944 | // function default implementations (and hypothetical code | ||
945 | // inside consts or type aliases) | ||
946 | cov_mark::hit!(trait_self_implements_self); | ||
947 | let substs = Substs::type_params(db, trait_id); | ||
948 | let trait_ref = TraitRef { trait_: trait_id, substs }; | ||
949 | let pred = GenericPredicate::Implemented(trait_ref); | ||
950 | let program_clause: chalk_ir::ProgramClause<Interner> = | ||
951 | pred.clone().to_chalk(db).cast(&Interner); | ||
952 | clauses.push(program_clause.into_from_env_clause(&Interner)); | ||
947 | } | 953 | } |
954 | |||
955 | let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses); | ||
956 | |||
957 | Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env }) | ||
948 | } | 958 | } |
949 | 959 | ||
950 | /// Resolve the where clause(s) of an item with generics. | 960 | /// Resolve the where clause(s) of an item with generics. |
@@ -958,10 +968,7 @@ pub(crate) fn generic_predicates_query( | |||
958 | let generics = generics(db.upcast(), def); | 968 | let generics = generics(db.upcast(), def); |
959 | resolver | 969 | resolver |
960 | .where_predicates_in_scope() | 970 | .where_predicates_in_scope() |
961 | .flat_map(|pred| { | 971 | .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p))) |
962 | GenericPredicate::from_where_predicate(&ctx, pred) | ||
963 | .map(|p| Binders::new(generics.len(), p)) | ||
964 | }) | ||
965 | .collect() | 972 | .collect() |
966 | } | 973 | } |
967 | 974 | ||
@@ -979,17 +986,18 @@ pub(crate) fn generic_defaults_query( | |||
979 | .iter() | 986 | .iter() |
980 | .enumerate() | 987 | .enumerate() |
981 | .map(|(idx, (_, p))| { | 988 | .map(|(idx, (_, p))| { |
982 | let mut ty = p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t)); | 989 | let mut ty = |
990 | p.default.as_ref().map_or(TyKind::Unknown.intern(&Interner), |t| ctx.lower_ty(t)); | ||
983 | 991 | ||
984 | // Each default can only refer to previous parameters. | 992 | // Each default can only refer to previous parameters. |
985 | ty.walk_mut_binders( | 993 | ty.walk_mut_binders( |
986 | &mut |ty, binders| match ty { | 994 | &mut |ty, binders| match ty.interned_mut() { |
987 | Ty::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { | 995 | TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { |
988 | if *index >= idx { | 996 | if *index >= idx { |
989 | // type variable default referring to parameter coming | 997 | // type variable default referring to parameter coming |
990 | // after it. This is forbidden (FIXME: report | 998 | // after it. This is forbidden (FIXME: report |
991 | // diagnostic) | 999 | // diagnostic) |
992 | *ty = Ty::Unknown; | 1000 | *ty = TyKind::Unknown.intern(&Interner); |
993 | } | 1001 | } |
994 | } | 1002 | } |
995 | _ => {} | 1003 | _ => {} |
@@ -1010,11 +1018,11 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1010 | let ctx_params = TyLoweringContext::new(db, &resolver) | 1018 | let ctx_params = TyLoweringContext::new(db, &resolver) |
1011 | .with_impl_trait_mode(ImplTraitLoweringMode::Variable) | 1019 | .with_impl_trait_mode(ImplTraitLoweringMode::Variable) |
1012 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1020 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1013 | let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); | 1021 | let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>(); |
1014 | let ctx_ret = TyLoweringContext::new(db, &resolver) | 1022 | let ctx_ret = TyLoweringContext::new(db, &resolver) |
1015 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) | 1023 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) |
1016 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1024 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1017 | let ret = Ty::from_hir(&ctx_ret, &data.ret_type); | 1025 | let ret = (&ctx_ret).lower_ty(&data.ret_type); |
1018 | let generics = generics(db.upcast(), def.into()); | 1026 | let generics = generics(db.upcast(), def.into()); |
1019 | let num_binders = generics.len(); | 1027 | let num_binders = generics.len(); |
1020 | Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) | 1028 | Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) |
@@ -1025,7 +1033,10 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig { | |||
1025 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { | 1033 | fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { |
1026 | let generics = generics(db.upcast(), def.into()); | 1034 | let generics = generics(db.upcast(), def.into()); |
1027 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1035 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1028 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) | 1036 | Binders::new( |
1037 | substs.len(), | ||
1038 | TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner), | ||
1039 | ) | ||
1029 | } | 1040 | } |
1030 | 1041 | ||
1031 | /// Build the declared type of a const. | 1042 | /// Build the declared type of a const. |
@@ -1036,7 +1047,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> { | |||
1036 | let ctx = | 1047 | let ctx = |
1037 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1048 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1038 | 1049 | ||
1039 | Binders::new(generics.len(), Ty::from_hir(&ctx, &data.type_ref)) | 1050 | Binders::new(generics.len(), ctx.lower_ty(&data.type_ref)) |
1040 | } | 1051 | } |
1041 | 1052 | ||
1042 | /// Build the declared type of a static. | 1053 | /// Build the declared type of a static. |
@@ -1045,7 +1056,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> { | |||
1045 | let resolver = def.resolver(db.upcast()); | 1056 | let resolver = def.resolver(db.upcast()); |
1046 | let ctx = TyLoweringContext::new(db, &resolver); | 1057 | let ctx = TyLoweringContext::new(db, &resolver); |
1047 | 1058 | ||
1048 | Binders::new(0, Ty::from_hir(&ctx, &data.type_ref)) | 1059 | Binders::new(0, ctx.lower_ty(&data.type_ref)) |
1049 | } | 1060 | } |
1050 | 1061 | ||
1051 | fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { | 1062 | fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { |
@@ -1054,8 +1065,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS | |||
1054 | let resolver = def.resolver(db.upcast()); | 1065 | let resolver = def.resolver(db.upcast()); |
1055 | let ctx = | 1066 | let ctx = |
1056 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1067 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1057 | let params = | 1068 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); |
1058 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | ||
1059 | let ret = type_for_adt(db, def.into()); | 1069 | let ret = type_for_adt(db, def.into()); |
1060 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) | 1070 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) |
1061 | } | 1071 | } |
@@ -1068,7 +1078,10 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T | |||
1068 | } | 1078 | } |
1069 | let generics = generics(db.upcast(), def.into()); | 1079 | let generics = generics(db.upcast(), def.into()); |
1070 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1080 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1071 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) | 1081 | Binders::new( |
1082 | substs.len(), | ||
1083 | TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner), | ||
1084 | ) | ||
1072 | } | 1085 | } |
1073 | 1086 | ||
1074 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { | 1087 | fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { |
@@ -1078,8 +1091,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) | |||
1078 | let resolver = def.parent.resolver(db.upcast()); | 1091 | let resolver = def.parent.resolver(db.upcast()); |
1079 | let ctx = | 1092 | let ctx = |
1080 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1093 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1081 | let params = | 1094 | let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>(); |
1082 | fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); | ||
1083 | let ret = type_for_adt(db, def.parent.into()); | 1095 | let ret = type_for_adt(db, def.parent.into()); |
1084 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) | 1096 | Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) |
1085 | } | 1097 | } |
@@ -1093,7 +1105,10 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) - | |||
1093 | } | 1105 | } |
1094 | let generics = generics(db.upcast(), def.parent.into()); | 1106 | let generics = generics(db.upcast(), def.parent.into()); |
1095 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1107 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1096 | Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) | 1108 | Binders::new( |
1109 | substs.len(), | ||
1110 | TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner), | ||
1111 | ) | ||
1097 | } | 1112 | } |
1098 | 1113 | ||
1099 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { | 1114 | fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { |
@@ -1108,11 +1123,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { | |||
1108 | let ctx = | 1123 | let ctx = |
1109 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1124 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1110 | if db.type_alias_data(t).is_extern { | 1125 | if db.type_alias_data(t).is_extern { |
1111 | Binders::new(0, Ty::ForeignType(t)) | 1126 | Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner)) |
1112 | } else { | 1127 | } else { |
1113 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); | 1128 | let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); |
1114 | let type_ref = &db.type_alias_data(t).type_ref; | 1129 | let type_ref = &db.type_alias_data(t).type_ref; |
1115 | let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); | 1130 | let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error)); |
1116 | Binders::new(substs.len(), inner) | 1131 | Binders::new(substs.len(), inner) |
1117 | } | 1132 | } |
1118 | } | 1133 | } |
@@ -1184,7 +1199,7 @@ pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId) | |||
1184 | TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), | 1199 | TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), |
1185 | TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), | 1200 | TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), |
1186 | }; | 1201 | }; |
1187 | Binders::new(num_binders, Ty::Unknown) | 1202 | Binders::new(num_binders, TyKind::Unknown.intern(&Interner)) |
1188 | } | 1203 | } |
1189 | 1204 | ||
1190 | pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { | 1205 | pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { |
@@ -1204,7 +1219,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde | |||
1204 | let generics = generics(db.upcast(), impl_id.into()); | 1219 | let generics = generics(db.upcast(), impl_id.into()); |
1205 | let ctx = | 1220 | let ctx = |
1206 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1221 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1207 | Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type)) | 1222 | Binders::new(generics.len(), ctx.lower_ty(&impl_data.target_type)) |
1208 | } | 1223 | } |
1209 | 1224 | ||
1210 | pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { | 1225 | pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { |
@@ -1213,7 +1228,7 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T | |||
1213 | let resolver = def.parent.resolver(db.upcast()); | 1228 | let resolver = def.parent.resolver(db.upcast()); |
1214 | let ctx = TyLoweringContext::new(db, &resolver); | 1229 | let ctx = TyLoweringContext::new(db, &resolver); |
1215 | 1230 | ||
1216 | Ty::from_hir(&ctx, &data.ty) | 1231 | ctx.lower_ty(&data.ty) |
1217 | } | 1232 | } |
1218 | 1233 | ||
1219 | pub(crate) fn impl_self_ty_recover( | 1234 | pub(crate) fn impl_self_ty_recover( |
@@ -1222,7 +1237,7 @@ pub(crate) fn impl_self_ty_recover( | |||
1222 | impl_id: &ImplId, | 1237 | impl_id: &ImplId, |
1223 | ) -> Binders<Ty> { | 1238 | ) -> Binders<Ty> { |
1224 | let generics = generics(db.upcast(), (*impl_id).into()); | 1239 | let generics = generics(db.upcast(), (*impl_id).into()); |
1225 | Binders::new(generics.len(), Ty::Unknown) | 1240 | Binders::new(generics.len(), TyKind::Unknown.intern(&Interner)) |
1226 | } | 1241 | } |
1227 | 1242 | ||
1228 | pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { | 1243 | pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { |
@@ -1232,10 +1247,7 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option< | |||
1232 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); | 1247 | TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); |
1233 | let self_ty = db.impl_self_ty(impl_id); | 1248 | let self_ty = db.impl_self_ty(impl_id); |
1234 | let target_trait = impl_data.target_trait.as_ref()?; | 1249 | let target_trait = impl_data.target_trait.as_ref()?; |
1235 | Some(Binders::new( | 1250 | Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?)) |
1236 | self_ty.num_binders, | ||
1237 | TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value))?, | ||
1238 | )) | ||
1239 | } | 1251 | } |
1240 | 1252 | ||
1241 | pub(crate) fn return_type_impl_traits( | 1253 | pub(crate) fn return_type_impl_traits( |
@@ -1248,7 +1260,7 @@ pub(crate) fn return_type_impl_traits( | |||
1248 | let ctx_ret = TyLoweringContext::new(db, &resolver) | 1260 | let ctx_ret = TyLoweringContext::new(db, &resolver) |
1249 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) | 1261 | .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) |
1250 | .with_type_param_mode(TypeParamLoweringMode::Variable); | 1262 | .with_type_param_mode(TypeParamLoweringMode::Variable); |
1251 | let _ret = Ty::from_hir(&ctx_ret, &data.ret_type); | 1263 | let _ret = (&ctx_ret).lower_ty(&data.ret_type); |
1252 | let generics = generics(db.upcast(), def.into()); | 1264 | let generics = generics(db.upcast(), def.into()); |
1253 | let num_binders = generics.len(); | 1265 | let num_binders = generics.len(); |
1254 | let return_type_impl_traits = | 1266 | let return_type_impl_traits = |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index ccc12c075..be72c4a1c 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -9,7 +9,7 @@ use base_db::CrateId; | |||
9 | use chalk_ir::Mutability; | 9 | use chalk_ir::Mutability; |
10 | use hir_def::{ | 10 | use hir_def::{ |
11 | lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, | 11 | lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, |
12 | ImplId, Lookup, ModuleId, TraitId, TypeAliasId, | 12 | ImplId, Lookup, ModuleId, TraitId, |
13 | }; | 13 | }; |
14 | use hir_expand::name::Name; | 14 | use hir_expand::name::Name; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -17,10 +17,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
17 | use crate::{ | 17 | use crate::{ |
18 | autoderef, | 18 | autoderef, |
19 | db::HirDatabase, | 19 | db::HirDatabase, |
20 | from_foreign_def_id, | ||
20 | primitive::{self, FloatTy, IntTy, UintTy}, | 21 | primitive::{self, FloatTy, IntTy, UintTy}, |
21 | utils::all_super_traits, | 22 | utils::all_super_traits, |
22 | AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, | 23 | AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, |
23 | TraitEnvironment, TraitRef, Ty, TypeWalk, | 24 | Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, |
24 | }; | 25 | }; |
25 | 26 | ||
26 | /// This is used as a key for indexing impls. | 27 | /// This is used as a key for indexing impls. |
@@ -35,7 +36,7 @@ pub enum TyFingerprint { | |||
35 | Adt(hir_def::AdtId), | 36 | Adt(hir_def::AdtId), |
36 | Dyn(TraitId), | 37 | Dyn(TraitId), |
37 | Tuple(usize), | 38 | Tuple(usize), |
38 | ForeignType(TypeAliasId), | 39 | ForeignType(ForeignDefId), |
39 | FnPtr(usize, FnSig), | 40 | FnPtr(usize, FnSig), |
40 | } | 41 | } |
41 | 42 | ||
@@ -43,19 +44,21 @@ impl TyFingerprint { | |||
43 | /// Creates a TyFingerprint for looking up an impl. Only certain types can | 44 | /// Creates a TyFingerprint for looking up an impl. Only certain types can |
44 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not | 45 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not |
45 | /// `impl &S`. Hence, this will return `None` for reference types and such. | 46 | /// `impl &S`. Hence, this will return `None` for reference types and such. |
46 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 47 | pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> { |
47 | let fp = match ty { | 48 | let fp = match *ty.interned(&Interner) { |
48 | &Ty::Str => TyFingerprint::Str, | 49 | TyKind::Str => TyFingerprint::Str, |
49 | &Ty::Never => TyFingerprint::Never, | 50 | TyKind::Never => TyFingerprint::Never, |
50 | &Ty::Slice(..) => TyFingerprint::Slice, | 51 | TyKind::Slice(..) => TyFingerprint::Slice, |
51 | &Ty::Array(..) => TyFingerprint::Array, | 52 | TyKind::Array(..) => TyFingerprint::Array, |
52 | &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar), | 53 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), |
53 | &Ty::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), | 54 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), |
54 | &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), | 55 | TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), |
55 | &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), | 56 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), |
56 | &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), | 57 | TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), |
57 | &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig), | 58 | TyKind::Function(FnPointer { num_args, sig, .. }) => { |
58 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | 59 | TyFingerprint::FnPtr(num_args, sig) |
60 | } | ||
61 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
59 | _ => return None, | 62 | _ => return None, |
60 | }; | 63 | }; |
61 | Some(fp) | 64 | Some(fp) |
@@ -138,6 +141,14 @@ impl TraitImpls { | |||
138 | } | 141 | } |
139 | } | 142 | } |
140 | 143 | ||
144 | /// Queries all trait impls for the given type. | ||
145 | pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ { | ||
146 | self.map | ||
147 | .values() | ||
148 | .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp)))) | ||
149 | .flat_map(|it| it.iter().copied()) | ||
150 | } | ||
151 | |||
141 | /// Queries all impls of the given trait. | 152 | /// Queries all impls of the given trait. |
142 | pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ { | 153 | pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ { |
143 | self.map | 154 | self.map |
@@ -230,31 +241,33 @@ impl Ty { | |||
230 | 241 | ||
231 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 242 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
232 | 243 | ||
233 | let lang_item_targets = match self { | 244 | let lang_item_targets = match self.interned(&Interner) { |
234 | Ty::Adt(AdtId(def_id), _) => { | 245 | TyKind::Adt(AdtId(def_id), _) => { |
235 | return mod_to_crate_ids(def_id.module(db.upcast())); | 246 | return mod_to_crate_ids(def_id.module(db.upcast())); |
236 | } | 247 | } |
237 | Ty::ForeignType(type_alias_id) => { | 248 | TyKind::ForeignType(id) => { |
238 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); | 249 | return mod_to_crate_ids( |
250 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), | ||
251 | ); | ||
239 | } | 252 | } |
240 | Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 253 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
241 | Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), | 254 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), |
242 | Ty::Scalar(Scalar::Float(f)) => match f { | 255 | TyKind::Scalar(Scalar::Float(f)) => match f { |
243 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 256 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
244 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 257 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
245 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), | 258 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
246 | }, | 259 | }, |
247 | &Ty::Scalar(Scalar::Int(t)) => { | 260 | &TyKind::Scalar(Scalar::Int(t)) => { |
248 | lang_item_crate!(primitive::int_ty_to_string(t)) | 261 | lang_item_crate!(primitive::int_ty_to_string(t)) |
249 | } | 262 | } |
250 | &Ty::Scalar(Scalar::Uint(t)) => { | 263 | &TyKind::Scalar(Scalar::Uint(t)) => { |
251 | lang_item_crate!(primitive::uint_ty_to_string(t)) | 264 | lang_item_crate!(primitive::uint_ty_to_string(t)) |
252 | } | 265 | } |
253 | Ty::Str => lang_item_crate!("str_alloc", "str"), | 266 | TyKind::Str => lang_item_crate!("str_alloc", "str"), |
254 | Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | 267 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), |
255 | Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), | 268 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), |
256 | Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | 269 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), |
257 | Ty::Dyn(_) => { | 270 | TyKind::Dyn(_) => { |
258 | return self.dyn_trait().and_then(|trait_| { | 271 | return self.dyn_trait().and_then(|trait_| { |
259 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 272 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
260 | }); | 273 | }); |
@@ -430,7 +443,7 @@ fn iterate_method_candidates_with_autoref( | |||
430 | } | 443 | } |
431 | let refed = Canonical { | 444 | let refed = Canonical { |
432 | kinds: deref_chain[0].kinds.clone(), | 445 | kinds: deref_chain[0].kinds.clone(), |
433 | value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())), | 446 | value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), |
434 | }; | 447 | }; |
435 | if iterate_method_candidates_by_receiver( | 448 | if iterate_method_candidates_by_receiver( |
436 | &refed, | 449 | &refed, |
@@ -446,7 +459,7 @@ fn iterate_method_candidates_with_autoref( | |||
446 | } | 459 | } |
447 | let ref_muted = Canonical { | 460 | let ref_muted = Canonical { |
448 | kinds: deref_chain[0].kinds.clone(), | 461 | kinds: deref_chain[0].kinds.clone(), |
449 | value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), | 462 | value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), |
450 | }; | 463 | }; |
451 | if iterate_method_candidates_by_receiver( | 464 | if iterate_method_candidates_by_receiver( |
452 | &ref_muted, | 465 | &ref_muted, |
@@ -526,10 +539,9 @@ fn iterate_trait_method_candidates( | |||
526 | // if ty is `dyn Trait`, the trait doesn't need to be in scope | 539 | // if ty is `dyn Trait`, the trait doesn't need to be in scope |
527 | let inherent_trait = | 540 | let inherent_trait = |
528 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); | 541 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); |
529 | let env_traits = if let Ty::Placeholder(_) = self_ty.value { | 542 | let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { |
530 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope | 543 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope |
531 | env.trait_predicates_for_self_ty(&self_ty.value) | 544 | env.traits_in_scope_from_clauses(&self_ty.value) |
532 | .map(|tr| tr.trait_) | ||
533 | .flat_map(|t| all_super_traits(db.upcast(), t)) | 545 | .flat_map(|t| all_super_traits(db.upcast(), t)) |
534 | .collect() | 546 | .collect() |
535 | } else { | 547 | } else { |
@@ -680,13 +692,13 @@ pub(crate) fn inherent_impl_substs( | |||
680 | } | 692 | } |
681 | 693 | ||
682 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | 694 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past |
683 | /// num_vars_to_keep) by `Ty::Unknown`. | 695 | /// num_vars_to_keep) by `TyKind::Unknown`. |
684 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { | 696 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { |
685 | s.fold_binders( | 697 | s.fold_binders( |
686 | &mut |ty, binders| { | 698 | &mut |ty, binders| { |
687 | if let Ty::BoundVar(bound) = &ty { | 699 | if let TyKind::BoundVar(bound) = ty.interned(&Interner) { |
688 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { | 700 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { |
689 | Ty::Unknown | 701 | TyKind::Unknown.intern(&Interner) |
690 | } else { | 702 | } else { |
691 | ty | 703 | ty |
692 | } | 704 | } |
@@ -773,9 +785,11 @@ fn autoderef_method_receiver( | |||
773 | ) -> Vec<Canonical<Ty>> { | 785 | ) -> Vec<Canonical<Ty>> { |
774 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 786 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); |
775 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) | 787 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) |
776 | if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) { | 788 | if let Some(TyKind::Array(parameters)) = |
789 | deref_chain.last().map(|ty| ty.value.interned(&Interner)) | ||
790 | { | ||
777 | let kinds = deref_chain.last().unwrap().kinds.clone(); | 791 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
778 | let unsized_ty = Ty::Slice(parameters.clone()); | 792 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); |
779 | deref_chain.push(Canonical { value: unsized_ty, kinds }) | 793 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
780 | } | 794 | } |
781 | deref_chain | 795 | deref_chain |
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs index bb9b8bbfc..527c5cbbd 100644 --- a/crates/hir_ty/src/op.rs +++ b/crates/hir_ty/src/op.rs | |||
@@ -2,51 +2,55 @@ | |||
2 | use chalk_ir::TyVariableKind; | 2 | use chalk_ir::TyVariableKind; |
3 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; | 3 | use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; |
4 | 4 | ||
5 | use crate::{Scalar, Ty}; | 5 | use crate::{Interner, Scalar, Ty, TyKind}; |
6 | 6 | ||
7 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { | 7 | pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { |
8 | match op { | 8 | match op { |
9 | BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::Scalar(Scalar::Bool), | 9 | BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
10 | BinaryOp::Assignment { .. } => Ty::unit(), | 10 | BinaryOp::Assignment { .. } => Ty::unit(), |
11 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { | 11 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { |
12 | Ty::Scalar(Scalar::Int(_)) | 12 | match lhs_ty.interned(&Interner) { |
13 | | Ty::Scalar(Scalar::Uint(_)) | 13 | TyKind::Scalar(Scalar::Int(_)) |
14 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, | 14 | | TyKind::Scalar(Scalar::Uint(_)) |
15 | Ty::InferenceVar(_, TyVariableKind::Integer) | 15 | | TyKind::Scalar(Scalar::Float(_)) => lhs_ty, |
16 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, | 16 | TyKind::InferenceVar(_, TyVariableKind::Integer) |
17 | _ => Ty::Unknown, | 17 | | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty, |
18 | }, | 18 | _ => TyKind::Unknown.intern(&Interner), |
19 | BinaryOp::ArithOp(_) => match rhs_ty { | 19 | } |
20 | Ty::Scalar(Scalar::Int(_)) | 20 | } |
21 | | Ty::Scalar(Scalar::Uint(_)) | 21 | BinaryOp::ArithOp(_) => match rhs_ty.interned(&Interner) { |
22 | | Ty::Scalar(Scalar::Float(_)) => rhs_ty, | 22 | TyKind::Scalar(Scalar::Int(_)) |
23 | Ty::InferenceVar(_, TyVariableKind::Integer) | 23 | | TyKind::Scalar(Scalar::Uint(_)) |
24 | | Ty::InferenceVar(_, TyVariableKind::Float) => rhs_ty, | 24 | | TyKind::Scalar(Scalar::Float(_)) => rhs_ty, |
25 | _ => Ty::Unknown, | 25 | TyKind::InferenceVar(_, TyVariableKind::Integer) |
26 | | TyKind::InferenceVar(_, TyVariableKind::Float) => rhs_ty, | ||
27 | _ => TyKind::Unknown.intern(&Interner), | ||
26 | }, | 28 | }, |
27 | } | 29 | } |
28 | } | 30 | } |
29 | 31 | ||
30 | pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | 32 | pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { |
31 | match op { | 33 | match op { |
32 | BinaryOp::LogicOp(..) => Ty::Scalar(Scalar::Bool), | 34 | BinaryOp::LogicOp(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
33 | BinaryOp::Assignment { op: None } => lhs_ty, | 35 | BinaryOp::Assignment { op: None } => lhs_ty, |
34 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { | 36 | BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.interned(&Interner) { |
35 | Ty::Scalar(_) | Ty::Str => lhs_ty, | 37 | TyKind::Scalar(_) | TyKind::Str => lhs_ty, |
36 | Ty::InferenceVar(_, TyVariableKind::Integer) | 38 | TyKind::InferenceVar(_, TyVariableKind::Integer) |
37 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, | 39 | | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty, |
38 | _ => Ty::Unknown, | 40 | _ => TyKind::Unknown.intern(&Interner), |
39 | }, | 41 | }, |
40 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, | 42 | BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => { |
43 | TyKind::Unknown.intern(&Interner) | ||
44 | } | ||
41 | BinaryOp::CmpOp(CmpOp::Ord { .. }) | 45 | BinaryOp::CmpOp(CmpOp::Ord { .. }) |
42 | | BinaryOp::Assignment { op: Some(_) } | 46 | | BinaryOp::Assignment { op: Some(_) } |
43 | | BinaryOp::ArithOp(_) => match lhs_ty { | 47 | | BinaryOp::ArithOp(_) => match lhs_ty.interned(&Interner) { |
44 | Ty::Scalar(Scalar::Int(_)) | 48 | TyKind::Scalar(Scalar::Int(_)) |
45 | | Ty::Scalar(Scalar::Uint(_)) | 49 | | TyKind::Scalar(Scalar::Uint(_)) |
46 | | Ty::Scalar(Scalar::Float(_)) => lhs_ty, | 50 | | TyKind::Scalar(Scalar::Float(_)) => lhs_ty, |
47 | Ty::InferenceVar(_, TyVariableKind::Integer) | 51 | TyKind::InferenceVar(_, TyVariableKind::Integer) |
48 | | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, | 52 | | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty, |
49 | _ => Ty::Unknown, | 53 | _ => TyKind::Unknown.intern(&Interner), |
50 | }, | 54 | }, |
51 | } | 55 | } |
52 | } | 56 | } |
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index fc770ea60..0a4141e69 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs | |||
@@ -19,6 +19,7 @@ use hir_def::{ | |||
19 | item_scope::ItemScope, | 19 | item_scope::ItemScope, |
20 | keys, | 20 | keys, |
21 | nameres::DefMap, | 21 | nameres::DefMap, |
22 | src::HasSource, | ||
22 | AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, | 23 | AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, |
23 | }; | 24 | }; |
24 | use hir_expand::{db::AstDatabase, InFile}; | 25 | use hir_expand::{db::AstDatabase, InFile}; |
@@ -195,18 +196,15 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { | |||
195 | defs.sort_by_key(|def| match def { | 196 | defs.sort_by_key(|def| match def { |
196 | DefWithBodyId::FunctionId(it) => { | 197 | DefWithBodyId::FunctionId(it) => { |
197 | let loc = it.lookup(&db); | 198 | let loc = it.lookup(&db); |
198 | let tree = db.item_tree(loc.id.file_id); | 199 | loc.source(&db).value.syntax().text_range().start() |
199 | tree.source(&db, loc.id).syntax().text_range().start() | ||
200 | } | 200 | } |
201 | DefWithBodyId::ConstId(it) => { | 201 | DefWithBodyId::ConstId(it) => { |
202 | let loc = it.lookup(&db); | 202 | let loc = it.lookup(&db); |
203 | let tree = db.item_tree(loc.id.file_id); | 203 | loc.source(&db).value.syntax().text_range().start() |
204 | tree.source(&db, loc.id).syntax().text_range().start() | ||
205 | } | 204 | } |
206 | DefWithBodyId::StaticId(it) => { | 205 | DefWithBodyId::StaticId(it) => { |
207 | let loc = it.lookup(&db); | 206 | let loc = it.lookup(&db); |
208 | let tree = db.item_tree(loc.id.file_id); | 207 | loc.source(&db).value.syntax().text_range().start() |
209 | tree.source(&db, loc.id).syntax().text_range().start() | ||
210 | } | 208 | } |
211 | }); | 209 | }); |
212 | for def in defs { | 210 | for def in defs { |
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index e185b1c0a..93d3ad020 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs | |||
@@ -1699,7 +1699,7 @@ fn super_trait_assoc_type_bounds() { | |||
1699 | 1699 | ||
1700 | #[test] | 1700 | #[test] |
1701 | fn fn_trait() { | 1701 | fn fn_trait() { |
1702 | check_infer( | 1702 | check_infer_with_mismatches( |
1703 | r#" | 1703 | r#" |
1704 | trait FnOnce<Args> { | 1704 | trait FnOnce<Args> { |
1705 | type Output; | 1705 | type Output; |
@@ -1727,7 +1727,7 @@ fn fn_trait() { | |||
1727 | 1727 | ||
1728 | #[test] | 1728 | #[test] |
1729 | fn fn_ptr_and_item() { | 1729 | fn fn_ptr_and_item() { |
1730 | check_infer( | 1730 | check_infer_with_mismatches( |
1731 | r#" | 1731 | r#" |
1732 | #[lang="fn_once"] | 1732 | #[lang="fn_once"] |
1733 | trait FnOnce<Args> { | 1733 | trait FnOnce<Args> { |
@@ -1743,12 +1743,12 @@ fn fn_ptr_and_item() { | |||
1743 | struct Bar<T>(T); | 1743 | struct Bar<T>(T); |
1744 | 1744 | ||
1745 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { | 1745 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { |
1746 | fn foo(&self) -> (A1, R) {} | 1746 | fn foo(&self) -> (A1, R) { loop {} } |
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | enum Opt<T> { None, Some(T) } | 1749 | enum Opt<T> { None, Some(T) } |
1750 | impl<T> Opt<T> { | 1750 | impl<T> Opt<T> { |
1751 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} | 1751 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> { loop {} } |
1752 | } | 1752 | } |
1753 | 1753 | ||
1754 | fn test() { | 1754 | fn test() { |
@@ -1765,19 +1765,23 @@ fn fn_ptr_and_item() { | |||
1765 | 80..84 'args': Args | 1765 | 80..84 'args': Args |
1766 | 139..143 'self': &Self | 1766 | 139..143 'self': &Self |
1767 | 243..247 'self': &Bar<F> | 1767 | 243..247 'self': &Bar<F> |
1768 | 260..262 '{}': () | 1768 | 260..271 '{ loop {} }': (A1, R) |
1769 | 346..350 'self': Opt<T> | 1769 | 262..269 'loop {}': ! |
1770 | 352..353 'f': F | 1770 | 267..269 '{}': () |
1771 | 368..370 '{}': () | 1771 | 355..359 'self': Opt<T> |
1772 | 384..500 '{ ...(f); }': () | 1772 | 361..362 'f': F |
1773 | 394..397 'bar': Bar<fn(u8) -> u32> | 1773 | 377..388 '{ loop {} }': Opt<U> |
1774 | 423..426 'bar': Bar<fn(u8) -> u32> | 1774 | 379..386 'loop {}': ! |
1775 | 423..432 'bar.foo()': (u8, u32) | 1775 | 384..386 '{}': () |
1776 | 443..446 'opt': Opt<u8> | 1776 | 402..518 '{ ...(f); }': () |
1777 | 465..466 'f': fn(u8) -> u32 | 1777 | 412..415 'bar': Bar<fn(u8) -> u32> |
1778 | 487..490 'opt': Opt<u8> | 1778 | 441..444 'bar': Bar<fn(u8) -> u32> |
1779 | 487..497 'opt.map(f)': Opt<u32> | 1779 | 441..450 'bar.foo()': (u8, u32) |
1780 | 495..496 'f': fn(u8) -> u32 | 1780 | 461..464 'opt': Opt<u8> |
1781 | 483..484 'f': fn(u8) -> u32 | ||
1782 | 505..508 'opt': Opt<u8> | ||
1783 | 505..515 'opt.map(f)': Opt<u32> | ||
1784 | 513..514 'f': fn(u8) -> u32 | ||
1781 | "#]], | 1785 | "#]], |
1782 | ); | 1786 | ); |
1783 | } | 1787 | } |
@@ -1859,7 +1863,7 @@ fn fn_trait_deref_with_ty_default() { | |||
1859 | 1863 | ||
1860 | #[test] | 1864 | #[test] |
1861 | fn closure_1() { | 1865 | fn closure_1() { |
1862 | check_infer( | 1866 | check_infer_with_mismatches( |
1863 | r#" | 1867 | r#" |
1864 | #[lang = "fn_once"] | 1868 | #[lang = "fn_once"] |
1865 | trait FnOnce<Args> { | 1869 | trait FnOnce<Args> { |
@@ -1868,7 +1872,7 @@ fn closure_1() { | |||
1868 | 1872 | ||
1869 | enum Option<T> { Some(T), None } | 1873 | enum Option<T> { Some(T), None } |
1870 | impl<T> Option<T> { | 1874 | impl<T> Option<T> { |
1871 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} | 1875 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} } |
1872 | } | 1876 | } |
1873 | 1877 | ||
1874 | fn test() { | 1878 | fn test() { |
@@ -1881,37 +1885,39 @@ fn closure_1() { | |||
1881 | expect![[r#" | 1885 | expect![[r#" |
1882 | 147..151 'self': Option<T> | 1886 | 147..151 'self': Option<T> |
1883 | 153..154 'f': F | 1887 | 153..154 'f': F |
1884 | 172..174 '{}': () | 1888 | 172..183 '{ loop {} }': Option<U> |
1885 | 188..307 '{ ... 1); }': () | 1889 | 174..181 'loop {}': ! |
1886 | 198..199 'x': Option<u32> | 1890 | 179..181 '{}': () |
1887 | 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> | 1891 | 197..316 '{ ... 1); }': () |
1888 | 202..220 'Option...(1u32)': Option<u32> | 1892 | 207..208 'x': Option<u32> |
1889 | 215..219 '1u32': u32 | 1893 | 211..223 'Option::Some': Some<u32>(u32) -> Option<u32> |
1890 | 226..227 'x': Option<u32> | 1894 | 211..229 'Option...(1u32)': Option<u32> |
1891 | 226..242 'x.map(...v + 1)': Option<u32> | 1895 | 224..228 '1u32': u32 |
1892 | 232..241 '|v| v + 1': |u32| -> u32 | 1896 | 235..236 'x': Option<u32> |
1893 | 233..234 'v': u32 | 1897 | 235..251 'x.map(...v + 1)': Option<u32> |
1894 | 236..237 'v': u32 | 1898 | 241..250 '|v| v + 1': |u32| -> u32 |
1895 | 236..241 'v + 1': u32 | 1899 | 242..243 'v': u32 |
1896 | 240..241 '1': u32 | 1900 | 245..246 'v': u32 |
1897 | 248..249 'x': Option<u32> | 1901 | 245..250 'v + 1': u32 |
1898 | 248..264 'x.map(... 1u64)': Option<u64> | 1902 | 249..250 '1': u32 |
1899 | 254..263 '|_v| 1u64': |u32| -> u64 | 1903 | 257..258 'x': Option<u32> |
1900 | 255..257 '_v': u32 | 1904 | 257..273 'x.map(... 1u64)': Option<u64> |
1901 | 259..263 '1u64': u64 | 1905 | 263..272 '|_v| 1u64': |u32| -> u64 |
1902 | 274..275 'y': Option<i64> | 1906 | 264..266 '_v': u32 |
1903 | 291..292 'x': Option<u32> | 1907 | 268..272 '1u64': u64 |
1904 | 291..304 'x.map(|_v| 1)': Option<i64> | 1908 | 283..284 'y': Option<i64> |
1905 | 297..303 '|_v| 1': |u32| -> i64 | 1909 | 300..301 'x': Option<u32> |
1906 | 298..300 '_v': u32 | 1910 | 300..313 'x.map(|_v| 1)': Option<i64> |
1907 | 302..303 '1': i64 | 1911 | 306..312 '|_v| 1': |u32| -> i64 |
1912 | 307..309 '_v': u32 | ||
1913 | 311..312 '1': i64 | ||
1908 | "#]], | 1914 | "#]], |
1909 | ); | 1915 | ); |
1910 | } | 1916 | } |
1911 | 1917 | ||
1912 | #[test] | 1918 | #[test] |
1913 | fn closure_2() { | 1919 | fn closure_2() { |
1914 | check_infer( | 1920 | check_infer_with_mismatches( |
1915 | r#" | 1921 | r#" |
1916 | trait FnOnce<Args> { | 1922 | trait FnOnce<Args> { |
1917 | type Output; | 1923 | type Output; |
@@ -1951,22 +1957,22 @@ fn closure_2() { | |||
1951 | 1957 | ||
1952 | #[test] | 1958 | #[test] |
1953 | fn closure_as_argument_inference_order() { | 1959 | fn closure_as_argument_inference_order() { |
1954 | check_infer( | 1960 | check_infer_with_mismatches( |
1955 | r#" | 1961 | r#" |
1956 | #[lang = "fn_once"] | 1962 | #[lang = "fn_once"] |
1957 | trait FnOnce<Args> { | 1963 | trait FnOnce<Args> { |
1958 | type Output; | 1964 | type Output; |
1959 | } | 1965 | } |
1960 | 1966 | ||
1961 | fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} | 1967 | fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} } |
1962 | fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} | 1968 | fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} } |
1963 | 1969 | ||
1964 | struct S; | 1970 | struct S; |
1965 | impl S { | 1971 | impl S { |
1966 | fn method(self) -> u64; | 1972 | fn method(self) -> u64; |
1967 | 1973 | ||
1968 | fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} | 1974 | fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U { loop {} } |
1969 | fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} | 1975 | fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} } |
1970 | } | 1976 | } |
1971 | 1977 | ||
1972 | fn test() { | 1978 | fn test() { |
@@ -1979,52 +1985,60 @@ fn closure_as_argument_inference_order() { | |||
1979 | expect![[r#" | 1985 | expect![[r#" |
1980 | 94..95 'x': T | 1986 | 94..95 'x': T |
1981 | 100..101 'f': F | 1987 | 100..101 'f': F |
1982 | 111..113 '{}': () | 1988 | 111..122 '{ loop {} }': U |
1983 | 147..148 'f': F | 1989 | 113..120 'loop {}': ! |
1984 | 153..154 'x': T | 1990 | 118..120 '{}': () |
1985 | 164..166 '{}': () | 1991 | 156..157 'f': F |
1986 | 201..205 'self': S | 1992 | 162..163 'x': T |
1987 | 253..257 'self': S | 1993 | 173..184 '{ loop {} }': U |
1988 | 259..260 'x': T | 1994 | 175..182 'loop {}': ! |
1989 | 265..266 'f': F | 1995 | 180..182 '{}': () |
1990 | 276..278 '{}': () | 1996 | 219..223 'self': S |
1991 | 316..320 'self': S | 1997 | 271..275 'self': S |
1992 | 322..323 'f': F | 1998 | 277..278 'x': T |
1993 | 328..329 'x': T | 1999 | 283..284 'f': F |
1994 | 339..341 '{}': () | 2000 | 294..305 '{ loop {} }': U |
1995 | 355..514 '{ ... S); }': () | 2001 | 296..303 'loop {}': ! |
1996 | 365..367 'x1': u64 | 2002 | 301..303 '{}': () |
1997 | 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 | 2003 | 343..347 'self': S |
1998 | 370..393 'foo1(S...hod())': u64 | 2004 | 349..350 'f': F |
1999 | 375..376 'S': S | 2005 | 355..356 'x': T |
2000 | 378..392 '|s| s.method()': |S| -> u64 | 2006 | 366..377 '{ loop {} }': U |
2001 | 379..380 's': S | 2007 | 368..375 'loop {}': ! |
2002 | 382..383 's': S | 2008 | 373..375 '{}': () |
2003 | 382..392 's.method()': u64 | 2009 | 391..550 '{ ... S); }': () |
2004 | 403..405 'x2': u64 | 2010 | 401..403 'x1': u64 |
2005 | 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 | 2011 | 406..410 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 |
2006 | 408..431 'foo2(|...(), S)': u64 | 2012 | 406..429 'foo1(S...hod())': u64 |
2007 | 413..427 '|s| s.method()': |S| -> u64 | 2013 | 411..412 'S': S |
2008 | 414..415 's': S | 2014 | 414..428 '|s| s.method()': |S| -> u64 |
2009 | 417..418 's': S | 2015 | 415..416 's': S |
2010 | 417..427 's.method()': u64 | 2016 | 418..419 's': S |
2011 | 429..430 'S': S | 2017 | 418..428 's.method()': u64 |
2012 | 441..443 'x3': u64 | 2018 | 439..441 'x2': u64 |
2013 | 446..447 'S': S | 2019 | 444..448 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 |
2014 | 446..471 'S.foo1...hod())': u64 | 2020 | 444..467 'foo2(|...(), S)': u64 |
2015 | 453..454 'S': S | 2021 | 449..463 '|s| s.method()': |S| -> u64 |
2016 | 456..470 '|s| s.method()': |S| -> u64 | 2022 | 450..451 's': S |
2017 | 457..458 's': S | 2023 | 453..454 's': S |
2018 | 460..461 's': S | 2024 | 453..463 's.method()': u64 |
2019 | 460..470 's.method()': u64 | 2025 | 465..466 'S': S |
2020 | 481..483 'x4': u64 | 2026 | 477..479 'x3': u64 |
2021 | 486..487 'S': S | 2027 | 482..483 'S': S |
2022 | 486..511 'S.foo2...(), S)': u64 | 2028 | 482..507 'S.foo1...hod())': u64 |
2023 | 493..507 '|s| s.method()': |S| -> u64 | 2029 | 489..490 'S': S |
2024 | 494..495 's': S | 2030 | 492..506 '|s| s.method()': |S| -> u64 |
2025 | 497..498 's': S | 2031 | 493..494 's': S |
2026 | 497..507 's.method()': u64 | 2032 | 496..497 's': S |
2027 | 509..510 'S': S | 2033 | 496..506 's.method()': u64 |
2034 | 517..519 'x4': u64 | ||
2035 | 522..523 'S': S | ||
2036 | 522..547 'S.foo2...(), S)': u64 | ||
2037 | 529..543 '|s| s.method()': |S| -> u64 | ||
2038 | 530..531 's': S | ||
2039 | 533..534 's': S | ||
2040 | 533..543 's.method()': u64 | ||
2041 | 545..546 'S': S | ||
2028 | "#]], | 2042 | "#]], |
2029 | ); | 2043 | ); |
2030 | } | 2044 | } |
@@ -2536,7 +2550,7 @@ fn test() { | |||
2536 | 2550 | ||
2537 | #[test] | 2551 | #[test] |
2538 | fn iterator_chain() { | 2552 | fn iterator_chain() { |
2539 | check_infer( | 2553 | check_infer_with_mismatches( |
2540 | r#" | 2554 | r#" |
2541 | //- /main.rs | 2555 | //- /main.rs |
2542 | #[lang = "fn_once"] | 2556 | #[lang = "fn_once"] |
@@ -2939,7 +2953,7 @@ fn infer_closure_arg() { | |||
2939 | 2953 | ||
2940 | #[test] | 2954 | #[test] |
2941 | fn infer_fn_trait_arg() { | 2955 | fn infer_fn_trait_arg() { |
2942 | check_infer( | 2956 | check_infer_with_mismatches( |
2943 | r#" | 2957 | r#" |
2944 | //- /lib.rs deps:std | 2958 | //- /lib.rs deps:std |
2945 | 2959 | ||
@@ -2986,7 +3000,8 @@ fn infer_fn_trait_arg() { | |||
2986 | 3000 | ||
2987 | #[test] | 3001 | #[test] |
2988 | fn infer_box_fn_arg() { | 3002 | fn infer_box_fn_arg() { |
2989 | check_infer( | 3003 | // The type mismatch is a bug |
3004 | check_infer_with_mismatches( | ||
2990 | r#" | 3005 | r#" |
2991 | //- /lib.rs deps:std | 3006 | //- /lib.rs deps:std |
2992 | 3007 | ||
@@ -3025,7 +3040,7 @@ fn infer_box_fn_arg() { | |||
3025 | fn foo() { | 3040 | fn foo() { |
3026 | let s = Option::None; | 3041 | let s = Option::None; |
3027 | let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); | 3042 | let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); |
3028 | f(&s) | 3043 | f(&s); |
3029 | } | 3044 | } |
3030 | "#, | 3045 | "#, |
3031 | expect![[r#" | 3046 | expect![[r#" |
@@ -3037,7 +3052,7 @@ fn infer_box_fn_arg() { | |||
3037 | 406..417 '&self.inner': &*mut T | 3052 | 406..417 '&self.inner': &*mut T |
3038 | 407..411 'self': &Box<T> | 3053 | 407..411 'self': &Box<T> |
3039 | 407..417 'self.inner': *mut T | 3054 | 407..417 'self.inner': *mut T |
3040 | 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> | 3055 | 478..576 '{ ...&s); }': () |
3041 | 488..489 's': Option<i32> | 3056 | 488..489 's': Option<i32> |
3042 | 492..504 'Option::None': Option<i32> | 3057 | 492..504 'Option::None': Option<i32> |
3043 | 514..515 'f': Box<dyn FnOnce(&Option<i32>)> | 3058 | 514..515 'f': Box<dyn FnOnce(&Option<i32>)> |
@@ -3049,6 +3064,7 @@ fn infer_box_fn_arg() { | |||
3049 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> | 3064 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> |
3050 | 570..572 '&s': &Option<i32> | 3065 | 570..572 '&s': &Option<i32> |
3051 | 571..572 's': Option<i32> | 3066 | 571..572 's': Option<i32> |
3067 | 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|_| -> ()> | ||
3052 | "#]], | 3068 | "#]], |
3053 | ); | 3069 | ); |
3054 | } | 3070 | } |
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index e4cdb6d53..a6a63c673 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -10,7 +10,9 @@ use stdx::panic_context; | |||
10 | 10 | ||
11 | use crate::{db::HirDatabase, DebruijnIndex, Substs}; | 11 | use crate::{db::HirDatabase, DebruijnIndex, Substs}; |
12 | 12 | ||
13 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; | 13 | use super::{ |
14 | Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk, | ||
15 | }; | ||
14 | 16 | ||
15 | use self::chalk::{from_chalk, Interner, ToChalk}; | 17 | use self::chalk::{from_chalk, Interner, ToChalk}; |
16 | 18 | ||
@@ -38,26 +40,38 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> { | |||
38 | /// fn foo<T: Default>(t: T) {} | 40 | /// fn foo<T: Default>(t: T) {} |
39 | /// ``` | 41 | /// ``` |
40 | /// we assume that `T: Default`. | 42 | /// we assume that `T: Default`. |
41 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 43 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
42 | pub struct TraitEnvironment { | 44 | pub struct TraitEnvironment { |
43 | pub predicates: Vec<GenericPredicate>, | 45 | // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord, |
46 | // but for now it's too annoying... | ||
47 | pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, | ||
48 | pub(crate) env: chalk_ir::Environment<Interner>, | ||
44 | } | 49 | } |
45 | 50 | ||
46 | impl TraitEnvironment { | 51 | impl TraitEnvironment { |
47 | /// Returns trait refs with the given self type which are supposed to hold | 52 | pub(crate) fn traits_in_scope_from_clauses<'a>( |
48 | /// in this trait env. E.g. if we are in `foo<T: SomeTrait>()`, this will | ||
49 | /// find that `T: SomeTrait` if we call it for `T`. | ||
50 | pub(crate) fn trait_predicates_for_self_ty<'a>( | ||
51 | &'a self, | 53 | &'a self, |
52 | ty: &'a Ty, | 54 | ty: &'a Ty, |
53 | ) -> impl Iterator<Item = &'a TraitRef> + 'a { | 55 | ) -> impl Iterator<Item = TraitId> + 'a { |
54 | self.predicates.iter().filter_map(move |pred| match pred { | 56 | self.traits_from_clauses.iter().filter_map(move |(self_ty, trait_id)| { |
55 | GenericPredicate::Implemented(tr) if tr.self_ty() == ty => Some(tr), | 57 | if self_ty == ty { |
56 | _ => None, | 58 | Some(*trait_id) |
59 | } else { | ||
60 | None | ||
61 | } | ||
57 | }) | 62 | }) |
58 | } | 63 | } |
59 | } | 64 | } |
60 | 65 | ||
66 | impl Default for TraitEnvironment { | ||
67 | fn default() -> Self { | ||
68 | TraitEnvironment { | ||
69 | traits_from_clauses: Vec::new(), | ||
70 | env: chalk_ir::Environment::new(&Interner), | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | |||
61 | /// Something (usually a goal), along with an environment. | 75 | /// Something (usually a goal), along with an environment. |
62 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 76 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
63 | pub struct InEnvironment<T> { | 77 | pub struct InEnvironment<T> { |
@@ -129,7 +143,7 @@ pub(crate) fn trait_solve_query( | |||
129 | log::info!("trait_solve_query({})", goal.value.value.display(db)); | 143 | log::info!("trait_solve_query({})", goal.value.value.display(db)); |
130 | 144 | ||
131 | if let Obligation::Projection(pred) = &goal.value.value { | 145 | if let Obligation::Projection(pred) = &goal.value.value { |
132 | if let Ty::BoundVar(_) = &pred.projection_ty.parameters[0] { | 146 | if let TyKind::BoundVar(_) = &pred.projection_ty.substitution[0].interned(&Interner) { |
133 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible | 147 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible |
134 | return Some(Solution::Ambig(Guidance::Unknown)); | 148 | return Some(Solution::Ambig(Guidance::Unknown)); |
135 | } | 149 | } |
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index 565672b6b..232cf9cd0 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
@@ -17,29 +17,31 @@ use super::ChalkContext; | |||
17 | use crate::{ | 17 | use crate::{ |
18 | db::HirDatabase, | 18 | db::HirDatabase, |
19 | display::HirDisplay, | 19 | display::HirDisplay, |
20 | from_assoc_type_id, | ||
20 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | 21 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, |
22 | to_assoc_type_id, | ||
21 | utils::generics, | 23 | utils::generics, |
22 | BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate, | 24 | BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate, |
23 | ProjectionTy, Substs, TraitRef, Ty, | 25 | ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TyKind, |
24 | }; | 26 | }; |
25 | use mapping::{ | 27 | use mapping::{ |
26 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, | 28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, |
27 | TypeAliasAsValue, | ||
28 | }; | 29 | }; |
29 | 30 | ||
31 | pub use self::interner::Interner; | ||
30 | pub(crate) use self::interner::*; | 32 | pub(crate) use self::interner::*; |
31 | 33 | ||
32 | pub(super) mod tls; | 34 | pub(super) mod tls; |
33 | mod interner; | 35 | mod interner; |
34 | mod mapping; | 36 | mod mapping; |
35 | 37 | ||
36 | pub(super) trait ToChalk { | 38 | pub(crate) trait ToChalk { |
37 | type Chalk; | 39 | type Chalk; |
38 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk; | 40 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk; |
39 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self; | 41 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self; |
40 | } | 42 | } |
41 | 43 | ||
42 | pub(super) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T | 44 | pub(crate) fn from_chalk<T, ChalkT>(db: &dyn HirDatabase, chalk: ChalkT) -> T |
43 | where | 45 | where |
44 | T: ToChalk<Chalk = ChalkT>, | 46 | T: ToChalk<Chalk = ChalkT>, |
45 | { | 47 | { |
@@ -90,7 +92,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
90 | ty: &Ty, | 92 | ty: &Ty, |
91 | binders: &CanonicalVarKinds<Interner>, | 93 | binders: &CanonicalVarKinds<Interner>, |
92 | ) -> Option<chalk_ir::TyVariableKind> { | 94 | ) -> Option<chalk_ir::TyVariableKind> { |
93 | if let Ty::BoundVar(bv) = ty { | 95 | if let TyKind::BoundVar(bv) = ty.interned(&Interner) { |
94 | let binders = binders.as_slice(&Interner); | 96 | let binders = binders.as_slice(&Interner); |
95 | if bv.debruijn == DebruijnIndex::INNERMOST { | 97 | if bv.debruijn == DebruijnIndex::INNERMOST { |
96 | if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { | 98 | if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { |
@@ -175,10 +177,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
175 | } | 177 | } |
176 | 178 | ||
177 | fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> { | 179 | fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> { |
178 | let interned_id = crate::db::InternedOpaqueTyId::from(id); | 180 | let full_id = self.db.lookup_intern_impl_trait_id(id.into()); |
179 | let full_id = self.db.lookup_intern_impl_trait_id(interned_id); | ||
180 | let bound = match full_id { | 181 | let bound = match full_id { |
181 | crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 182 | crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => { |
182 | let datas = self | 183 | let datas = self |
183 | .db | 184 | .db |
184 | .return_type_impl_traits(func) | 185 | .return_type_impl_traits(func) |
@@ -200,7 +201,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
200 | let num_vars = datas.num_binders; | 201 | let num_vars = datas.num_binders; |
201 | make_binders(bound, num_vars) | 202 | make_binders(bound, num_vars) |
202 | } | 203 | } |
203 | crate::OpaqueTyId::AsyncBlockTypeImplTrait(..) => { | 204 | crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => { |
204 | if let Some((future_trait, future_output)) = self | 205 | if let Some((future_trait, future_output)) = self |
205 | .db | 206 | .db |
206 | .lang_item(self.krate, "future_trait".into()) | 207 | .lang_item(self.krate, "future_trait".into()) |
@@ -220,21 +221,25 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
220 | let impl_bound = GenericPredicate::Implemented(TraitRef { | 221 | let impl_bound = GenericPredicate::Implemented(TraitRef { |
221 | trait_: future_trait, | 222 | trait_: future_trait, |
222 | // Self type as the first parameter. | 223 | // Self type as the first parameter. |
223 | substs: Substs::single(Ty::BoundVar(BoundVar { | 224 | substs: Substs::single( |
224 | debruijn: DebruijnIndex::INNERMOST, | 225 | TyKind::BoundVar(BoundVar { |
225 | index: 0, | 226 | debruijn: DebruijnIndex::INNERMOST, |
226 | })), | 227 | index: 0, |
228 | }) | ||
229 | .intern(&Interner), | ||
230 | ), | ||
227 | }); | 231 | }); |
228 | let proj_bound = GenericPredicate::Projection(ProjectionPredicate { | 232 | let proj_bound = GenericPredicate::Projection(ProjectionPredicate { |
229 | // The parameter of the opaque type. | 233 | // The parameter of the opaque type. |
230 | ty: Ty::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }), | 234 | ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }) |
235 | .intern(&Interner), | ||
231 | projection_ty: ProjectionTy { | 236 | projection_ty: ProjectionTy { |
232 | associated_ty: future_output, | 237 | associated_ty_id: to_assoc_type_id(future_output), |
233 | // Self type as the first parameter. | 238 | // Self type as the first parameter. |
234 | parameters: Substs::single(Ty::BoundVar(BoundVar::new( | 239 | substitution: Substs::single( |
235 | DebruijnIndex::INNERMOST, | 240 | TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) |
236 | 0, | 241 | .intern(&Interner), |
237 | ))), | 242 | ), |
238 | }, | 243 | }, |
239 | }); | 244 | }); |
240 | let bound = OpaqueTyDatumBound { | 245 | let bound = OpaqueTyDatumBound { |
@@ -263,7 +268,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
263 | 268 | ||
264 | fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { | 269 | fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { |
265 | // FIXME: actually provide the hidden type; it is relevant for auto traits | 270 | // FIXME: actually provide the hidden type; it is relevant for auto traits |
266 | Ty::Unknown.to_chalk(self.db) | 271 | TyKind::Unknown.intern(&Interner).to_chalk(self.db) |
267 | } | 272 | } |
268 | 273 | ||
269 | fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool { | 274 | fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool { |
@@ -378,7 +383,7 @@ pub(crate) fn associated_ty_data_query( | |||
378 | id: AssocTypeId, | 383 | id: AssocTypeId, |
379 | ) -> Arc<AssociatedTyDatum> { | 384 | ) -> Arc<AssociatedTyDatum> { |
380 | debug!("associated_ty_data {:?}", id); | 385 | debug!("associated_ty_data {:?}", id); |
381 | let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(db, id).0; | 386 | let type_alias: TypeAliasId = from_assoc_type_id(id); |
382 | let trait_ = match type_alias.lookup(db.upcast()).container { | 387 | let trait_ = match type_alias.lookup(db.upcast()).container { |
383 | AssocContainerId::TraitId(t) => t, | 388 | AssocContainerId::TraitId(t) => t, |
384 | _ => panic!("associated type not in trait"), | 389 | _ => panic!("associated type not in trait"), |
@@ -391,11 +396,12 @@ pub(crate) fn associated_ty_data_query( | |||
391 | let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); | 396 | let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); |
392 | let ctx = crate::TyLoweringContext::new(db, &resolver) | 397 | let ctx = crate::TyLoweringContext::new(db, &resolver) |
393 | .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); | 398 | .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); |
394 | let self_ty = Ty::BoundVar(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)); | 399 | let self_ty = |
400 | TyKind::BoundVar(BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)).intern(&Interner); | ||
395 | let bounds = type_alias_data | 401 | let bounds = type_alias_data |
396 | .bounds | 402 | .bounds |
397 | .iter() | 403 | .iter() |
398 | .flat_map(|bound| GenericPredicate::from_type_bound(&ctx, bound, self_ty.clone())) | 404 | .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone())) |
399 | .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty)) | 405 | .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty)) |
400 | .map(|bound| make_binders(bound.shifted_in(&Interner), 0)) | 406 | .map(|bound| make_binders(bound.shifted_in(&Interner), 0)) |
401 | .collect(); | 407 | .collect(); |
@@ -432,10 +438,8 @@ pub(crate) fn trait_datum_query( | |||
432 | fundamental: false, | 438 | fundamental: false, |
433 | }; | 439 | }; |
434 | let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); | 440 | let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); |
435 | let associated_ty_ids = trait_data | 441 | let associated_ty_ids = |
436 | .associated_types() | 442 | trait_data.associated_types().map(|type_alias| to_assoc_type_id(type_alias)).collect(); |
437 | .map(|type_alias| TypeAliasAsAssocType(type_alias).to_chalk(db)) | ||
438 | .collect(); | ||
439 | let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; | 443 | let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; |
440 | let well_known = | 444 | let well_known = |
441 | lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); | 445 | lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); |
@@ -487,19 +491,14 @@ pub(crate) fn struct_datum_query( | |||
487 | struct_id: AdtId, | 491 | struct_id: AdtId, |
488 | ) -> Arc<StructDatum> { | 492 | ) -> Arc<StructDatum> { |
489 | debug!("struct_datum {:?}", struct_id); | 493 | debug!("struct_datum {:?}", struct_id); |
490 | let type_ctor = Ty::Adt(struct_id, Substs::empty()); | ||
491 | let chalk_ir::AdtId(adt_id) = struct_id; | 494 | let chalk_ir::AdtId(adt_id) = struct_id; |
492 | debug!("struct {:?} = {:?}", struct_id, type_ctor); | ||
493 | let num_params = generics(db.upcast(), adt_id.into()).len(); | 495 | let num_params = generics(db.upcast(), adt_id.into()).len(); |
494 | let upstream = adt_id.module(db.upcast()).krate() != krate; | 496 | let upstream = adt_id.module(db.upcast()).krate() != krate; |
495 | let where_clauses = type_ctor | 497 | let where_clauses = { |
496 | .as_generic_def() | 498 | let generic_params = generics(db.upcast(), adt_id.into()); |
497 | .map(|generic_def| { | 499 | let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); |
498 | let generic_params = generics(db.upcast(), generic_def); | 500 | convert_where_clauses(db, adt_id.into(), &bound_vars) |
499 | let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); | 501 | }; |
500 | convert_where_clauses(db, generic_def, &bound_vars) | ||
501 | }) | ||
502 | .unwrap_or_else(Vec::new); | ||
503 | let flags = rust_ir::AdtFlags { | 502 | let flags = rust_ir::AdtFlags { |
504 | upstream, | 503 | upstream, |
505 | // FIXME set fundamental and phantom_data flags correctly | 504 | // FIXME set fundamental and phantom_data flags correctly |
@@ -622,7 +621,7 @@ fn type_alias_associated_ty_value( | |||
622 | let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; | 621 | let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; |
623 | let value = rust_ir::AssociatedTyValue { | 622 | let value = rust_ir::AssociatedTyValue { |
624 | impl_id: impl_id.to_chalk(db), | 623 | impl_id: impl_id.to_chalk(db), |
625 | associated_ty_id: TypeAliasAsAssocType(assoc_ty).to_chalk(db), | 624 | associated_ty_id: to_assoc_type_id(assoc_ty), |
626 | value: make_binders(value_bound, ty.num_binders), | 625 | value: make_binders(value_bound, ty.num_binders), |
627 | }; | 626 | }; |
628 | Arc::new(value) | 627 | Arc::new(value) |
@@ -716,14 +715,14 @@ impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId { | |||
716 | } | 715 | } |
717 | } | 716 | } |
718 | 717 | ||
719 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId { | 718 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId { |
720 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { | 719 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { |
721 | Self::from_intern_id(id.0) | 720 | Self::from_intern_id(id.0) |
722 | } | 721 | } |
723 | } | 722 | } |
724 | 723 | ||
725 | impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> { | 724 | impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { |
726 | fn from(id: crate::db::ClosureId) -> Self { | 725 | fn from(id: crate::db::InternedClosureId) -> Self { |
727 | chalk_ir::ClosureId(id.as_intern_id()) | 726 | chalk_ir::ClosureId(id.as_intern_id()) |
728 | } | 727 | } |
729 | } | 728 | } |
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs index 54bd1c724..1dc3f497d 100644 --- a/crates/hir_ty/src/traits/chalk/interner.rs +++ b/crates/hir_ty/src/traits/chalk/interner.rs | |||
@@ -12,7 +12,6 @@ pub struct Interner; | |||
12 | 12 | ||
13 | pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | 13 | pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; |
14 | pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; | 14 | pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; |
15 | pub(crate) type ForeignDefId = chalk_ir::ForeignDefId<Interner>; | ||
16 | pub(crate) type TraitId = chalk_ir::TraitId<Interner>; | 15 | pub(crate) type TraitId = chalk_ir::TraitId<Interner>; |
17 | pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; | 16 | pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; |
18 | pub(crate) type AdtId = chalk_ir::AdtId<Interner>; | 17 | pub(crate) type AdtId = chalk_ir::AdtId<Interner>; |
@@ -21,7 +20,6 @@ pub(crate) type ImplId = chalk_ir::ImplId<Interner>; | |||
21 | pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; | 20 | pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; |
22 | pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; | 21 | pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; |
23 | pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; | 22 | pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; |
24 | pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>; | ||
25 | pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; | 23 | pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; |
26 | pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 24 | pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
27 | pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; | 25 | pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 3a08b67e9..6a8b6752e 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -3,10 +3,7 @@ | |||
3 | //! Chalk (in both directions); plus some helper functions for more specialized | 3 | //! Chalk (in both directions); plus some helper functions for more specialized |
4 | //! conversions. | 4 | //! conversions. |
5 | 5 | ||
6 | use chalk_ir::{ | 6 | use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData}; |
7 | cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, | ||
8 | UniverseIndex, | ||
9 | }; | ||
10 | use chalk_solve::rust_ir; | 7 | use chalk_solve::rust_ir; |
11 | 8 | ||
12 | use base_db::salsa::InternKey; | 9 | use base_db::salsa::InternKey; |
@@ -14,10 +11,11 @@ use hir_def::{AssocContainerId, GenericDefId, Lookup, TypeAliasId}; | |||
14 | 11 | ||
15 | use crate::{ | 12 | use crate::{ |
16 | db::HirDatabase, | 13 | db::HirDatabase, |
14 | from_assoc_type_id, | ||
17 | primitive::UintTy, | 15 | primitive::UintTy, |
18 | traits::{Canonical, Obligation}, | 16 | traits::{Canonical, Obligation}, |
19 | AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, | 17 | AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, |
20 | OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, | 18 | ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty, |
21 | }; | 19 | }; |
22 | 20 | ||
23 | use super::interner::*; | 21 | use super::interner::*; |
@@ -26,71 +24,60 @@ use super::*; | |||
26 | impl ToChalk for Ty { | 24 | impl ToChalk for Ty { |
27 | type Chalk = chalk_ir::Ty<Interner>; | 25 | type Chalk = chalk_ir::Ty<Interner>; |
28 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { | 26 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { |
29 | match self { | 27 | match self.into_inner() { |
30 | Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters), | 28 | TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty), |
31 | Ty::Array(parameters) => array_to_chalk(db, parameters), | 29 | TyKind::Array(ty) => array_to_chalk(db, ty), |
32 | Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => { | 30 | TyKind::Function(FnPointer { sig, substs, .. }) => { |
33 | let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); | 31 | let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); |
34 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | 32 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { |
35 | num_binders: 0, | 33 | num_binders: 0, |
36 | sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic }, | 34 | sig, |
37 | substitution, | 35 | substitution, |
38 | }) | 36 | }) |
39 | .intern(&Interner) | 37 | .intern(&Interner) |
40 | } | 38 | } |
41 | Ty::AssociatedType(type_alias, substs) => { | 39 | TyKind::AssociatedType(assoc_type_id, substs) => { |
42 | let assoc_type = TypeAliasAsAssocType(type_alias); | ||
43 | let assoc_type_id = assoc_type.to_chalk(db); | ||
44 | let substitution = substs.to_chalk(db); | 40 | let substitution = substs.to_chalk(db); |
45 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) | 41 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) |
46 | } | 42 | } |
47 | 43 | ||
48 | Ty::OpaqueType(impl_trait_id, substs) => { | 44 | TyKind::OpaqueType(id, substs) => { |
49 | let id = impl_trait_id.to_chalk(db); | ||
50 | let substitution = substs.to_chalk(db); | 45 | let substitution = substs.to_chalk(db); |
51 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) | 46 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) |
52 | } | 47 | } |
53 | 48 | ||
54 | Ty::ForeignType(type_alias) => { | 49 | TyKind::ForeignType(id) => chalk_ir::TyKind::Foreign(id).intern(&Interner), |
55 | let foreign_type = TypeAliasAsForeignType(type_alias); | ||
56 | let foreign_type_id = foreign_type.to_chalk(db); | ||
57 | chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) | ||
58 | } | ||
59 | 50 | ||
60 | Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), | 51 | TyKind::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), |
61 | 52 | ||
62 | Ty::Tuple(cardinality, substs) => { | 53 | TyKind::Tuple(cardinality, substs) => { |
63 | let substitution = substs.to_chalk(db); | 54 | let substitution = substs.to_chalk(db); |
64 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) | 55 | chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) |
65 | } | 56 | } |
66 | Ty::Raw(mutability, substs) => { | 57 | TyKind::Raw(mutability, ty) => { |
67 | let ty = substs[0].clone().to_chalk(db); | 58 | let ty = ty.to_chalk(db); |
68 | chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner) | 59 | chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner) |
69 | } | 60 | } |
70 | Ty::Slice(substs) => { | 61 | TyKind::Slice(ty) => chalk_ir::TyKind::Slice(ty.to_chalk(db)).intern(&Interner), |
71 | chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) | 62 | TyKind::Str => chalk_ir::TyKind::Str.intern(&Interner), |
72 | } | 63 | TyKind::FnDef(id, substs) => { |
73 | Ty::Str => chalk_ir::TyKind::Str.intern(&Interner), | ||
74 | Ty::FnDef(callable_def, substs) => { | ||
75 | let id = callable_def.to_chalk(db); | ||
76 | let substitution = substs.to_chalk(db); | 64 | let substitution = substs.to_chalk(db); |
77 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) | 65 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) |
78 | } | 66 | } |
79 | Ty::Never => chalk_ir::TyKind::Never.intern(&Interner), | 67 | TyKind::Never => chalk_ir::TyKind::Never.intern(&Interner), |
80 | 68 | ||
81 | Ty::Closure(def, expr, substs) => { | 69 | TyKind::Closure(closure_id, substs) => { |
82 | let closure_id = db.intern_closure((def, expr)); | ||
83 | let substitution = substs.to_chalk(db); | 70 | let substitution = substs.to_chalk(db); |
84 | chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) | 71 | chalk_ir::TyKind::Closure(closure_id, substitution).intern(&Interner) |
85 | } | 72 | } |
86 | 73 | ||
87 | Ty::Adt(adt_id, substs) => { | 74 | TyKind::Adt(adt_id, substs) => { |
88 | let substitution = substs.to_chalk(db); | 75 | let substitution = substs.to_chalk(db); |
89 | chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner) | 76 | chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner) |
90 | } | 77 | } |
91 | Ty::Alias(AliasTy::Projection(proj_ty)) => { | 78 | TyKind::Alias(AliasTy::Projection(proj_ty)) => { |
92 | let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); | 79 | let associated_ty_id = proj_ty.associated_ty_id; |
93 | let substitution = proj_ty.parameters.to_chalk(db); | 80 | let substitution = proj_ty.substitution.to_chalk(db); |
94 | chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { | 81 | chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { |
95 | associated_ty_id, | 82 | associated_ty_id, |
96 | substitution, | 83 | substitution, |
@@ -98,17 +85,17 @@ impl ToChalk for Ty { | |||
98 | .cast(&Interner) | 85 | .cast(&Interner) |
99 | .intern(&Interner) | 86 | .intern(&Interner) |
100 | } | 87 | } |
101 | Ty::Placeholder(id) => { | 88 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
102 | let interned_id = db.intern_type_param_id(id); | 89 | let opaque_ty_id = opaque_ty.opaque_ty_id; |
103 | PlaceholderIndex { | 90 | let substitution = opaque_ty.substitution.to_chalk(db); |
104 | ui: UniverseIndex::ROOT, | 91 | chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { opaque_ty_id, substitution }) |
105 | idx: interned_id.as_intern_id().as_usize(), | 92 | .cast(&Interner) |
106 | } | 93 | .intern(&Interner) |
107 | .to_ty::<Interner>(&Interner) | 94 | } |
108 | } | 95 | TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner), |
109 | Ty::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), | 96 | TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), |
110 | Ty::InferenceVar(..) => panic!("uncanonicalized infer ty"), | 97 | TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"), |
111 | Ty::Dyn(predicates) => { | 98 | TyKind::Dyn(predicates) => { |
112 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( | 99 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( |
113 | &Interner, | 100 | &Interner, |
114 | predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), | 101 | predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), |
@@ -119,43 +106,30 @@ impl ToChalk for Ty { | |||
119 | }; | 106 | }; |
120 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) | 107 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) |
121 | } | 108 | } |
122 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | 109 | TyKind::Unknown => chalk_ir::TyKind::Error.intern(&Interner), |
123 | let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); | ||
124 | let substitution = opaque_ty.parameters.to_chalk(db); | ||
125 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { | ||
126 | opaque_ty_id, | ||
127 | substitution, | ||
128 | })) | ||
129 | .intern(&Interner) | ||
130 | } | ||
131 | Ty::Unknown => chalk_ir::TyKind::Error.intern(&Interner), | ||
132 | } | 110 | } |
133 | } | 111 | } |
134 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { | 112 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { |
135 | match chalk.data(&Interner).kind.clone() { | 113 | match chalk.data(&Interner).kind.clone() { |
136 | chalk_ir::TyKind::Error => Ty::Unknown, | 114 | chalk_ir::TyKind::Error => TyKind::Unknown, |
137 | chalk_ir::TyKind::Array(ty, _size) => Ty::Array(Substs::single(from_chalk(db, ty))), | 115 | chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(from_chalk(db, ty)), |
138 | chalk_ir::TyKind::Placeholder(idx) => { | 116 | chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx), |
139 | assert_eq!(idx.ui, UniverseIndex::ROOT); | ||
140 | let interned_id = crate::db::GlobalTypeParamId::from_intern_id( | ||
141 | crate::salsa::InternId::from(idx.idx), | ||
142 | ); | ||
143 | Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) | ||
144 | } | ||
145 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => { | 117 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => { |
146 | let associated_ty = | 118 | let associated_ty = proj.associated_ty_id; |
147 | from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; | ||
148 | let parameters = from_chalk(db, proj.substitution); | 119 | let parameters = from_chalk(db, proj.substitution); |
149 | Ty::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters })) | 120 | TyKind::Alias(AliasTy::Projection(ProjectionTy { |
121 | associated_ty_id: associated_ty, | ||
122 | substitution: parameters, | ||
123 | })) | ||
150 | } | 124 | } |
151 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { | 125 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { |
152 | let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); | 126 | let opaque_ty_id = opaque_ty.opaque_ty_id; |
153 | let parameters = from_chalk(db, opaque_ty.substitution); | 127 | let parameters = from_chalk(db, opaque_ty.substitution); |
154 | Ty::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })) | 128 | TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, substitution: parameters })) |
155 | } | 129 | } |
156 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | 130 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { |
157 | num_binders, | 131 | num_binders, |
158 | sig: chalk_ir::FnSig { variadic, .. }, | 132 | sig, |
159 | substitution, | 133 | substitution, |
160 | .. | 134 | .. |
161 | }) => { | 135 | }) => { |
@@ -164,14 +138,10 @@ impl ToChalk for Ty { | |||
164 | db, | 138 | db, |
165 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), | 139 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), |
166 | ); | 140 | ); |
167 | Ty::Function(FnPointer { | 141 | TyKind::Function(FnPointer { num_args: (substs.len() - 1), sig, substs }) |
168 | num_args: (substs.len() - 1), | ||
169 | sig: FnSig { variadic }, | ||
170 | substs, | ||
171 | }) | ||
172 | } | 142 | } |
173 | chalk_ir::TyKind::BoundVar(idx) => Ty::BoundVar(idx), | 143 | chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx), |
174 | chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, | 144 | chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown, |
175 | chalk_ir::TyKind::Dyn(where_clauses) => { | 145 | chalk_ir::TyKind::Dyn(where_clauses) => { |
176 | assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); | 146 | assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); |
177 | let predicates = where_clauses | 147 | let predicates = where_clauses |
@@ -180,49 +150,41 @@ impl ToChalk for Ty { | |||
180 | .iter(&Interner) | 150 | .iter(&Interner) |
181 | .map(|c| from_chalk(db, c.clone())) | 151 | .map(|c| from_chalk(db, c.clone())) |
182 | .collect(); | 152 | .collect(); |
183 | Ty::Dyn(predicates) | 153 | TyKind::Dyn(predicates) |
184 | } | 154 | } |
185 | 155 | ||
186 | chalk_ir::TyKind::Adt(adt_id, subst) => Ty::Adt(adt_id, from_chalk(db, subst)), | 156 | chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)), |
187 | chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType( | 157 | chalk_ir::TyKind::AssociatedType(type_id, subst) => { |
188 | from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0, | 158 | TyKind::AssociatedType(type_id, from_chalk(db, subst)) |
189 | from_chalk(db, subst), | 159 | } |
190 | ), | ||
191 | 160 | ||
192 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { | 161 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { |
193 | Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst)) | 162 | TyKind::OpaqueType(opaque_type_id, from_chalk(db, subst)) |
194 | } | 163 | } |
195 | 164 | ||
196 | chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar), | 165 | chalk_ir::TyKind::Scalar(scalar) => TyKind::Scalar(scalar), |
197 | chalk_ir::TyKind::Tuple(cardinality, subst) => { | 166 | chalk_ir::TyKind::Tuple(cardinality, subst) => { |
198 | Ty::Tuple(cardinality, from_chalk(db, subst)) | 167 | TyKind::Tuple(cardinality, from_chalk(db, subst)) |
199 | } | 168 | } |
200 | chalk_ir::TyKind::Raw(mutability, ty) => { | 169 | chalk_ir::TyKind::Raw(mutability, ty) => TyKind::Raw(mutability, from_chalk(db, ty)), |
201 | Ty::Raw(mutability, Substs::single(from_chalk(db, ty))) | 170 | chalk_ir::TyKind::Slice(ty) => TyKind::Slice(from_chalk(db, ty)), |
202 | } | ||
203 | chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))), | ||
204 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { | 171 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { |
205 | Ty::Ref(mutability, Substs::single(from_chalk(db, ty))) | 172 | TyKind::Ref(mutability, from_chalk(db, ty)) |
206 | } | 173 | } |
207 | chalk_ir::TyKind::Str => Ty::Str, | 174 | chalk_ir::TyKind::Str => TyKind::Str, |
208 | chalk_ir::TyKind::Never => Ty::Never, | 175 | chalk_ir::TyKind::Never => TyKind::Never, |
209 | 176 | ||
210 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { | 177 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { |
211 | Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst)) | 178 | TyKind::FnDef(fn_def_id, from_chalk(db, subst)) |
212 | } | 179 | } |
213 | 180 | ||
214 | chalk_ir::TyKind::Closure(id, subst) => { | 181 | chalk_ir::TyKind::Closure(id, subst) => TyKind::Closure(id, from_chalk(db, subst)), |
215 | let id: crate::db::ClosureId = id.into(); | ||
216 | let (def, expr) = db.lookup_intern_closure(id); | ||
217 | Ty::Closure(def, expr, from_chalk(db, subst)) | ||
218 | } | ||
219 | 182 | ||
220 | chalk_ir::TyKind::Foreign(foreign_def_id) => { | 183 | chalk_ir::TyKind::Foreign(foreign_def_id) => TyKind::ForeignType(foreign_def_id), |
221 | Ty::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0) | ||
222 | } | ||
223 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME | 184 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME |
224 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME | 185 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME |
225 | } | 186 | } |
187 | .intern(&Interner) | ||
226 | } | 188 | } |
227 | } | 189 | } |
228 | 190 | ||
@@ -231,17 +193,17 @@ impl ToChalk for Ty { | |||
231 | fn ref_to_chalk( | 193 | fn ref_to_chalk( |
232 | db: &dyn HirDatabase, | 194 | db: &dyn HirDatabase, |
233 | mutability: chalk_ir::Mutability, | 195 | mutability: chalk_ir::Mutability, |
234 | subst: Substs, | 196 | ty: Ty, |
235 | ) -> chalk_ir::Ty<Interner> { | 197 | ) -> chalk_ir::Ty<Interner> { |
236 | let arg = subst[0].clone().to_chalk(db); | 198 | let arg = ty.to_chalk(db); |
237 | let lifetime = LifetimeData::Static.intern(&Interner); | 199 | let lifetime = LifetimeData::Static.intern(&Interner); |
238 | chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner) | 200 | chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner) |
239 | } | 201 | } |
240 | 202 | ||
241 | /// We currently don't model constants, but Chalk does. So, we have to insert a | 203 | /// We currently don't model constants, but Chalk does. So, we have to insert a |
242 | /// fake constant here, because Chalks built-in logic may expect it to be there. | 204 | /// fake constant here, because Chalks built-in logic may expect it to be there. |
243 | fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { | 205 | fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> { |
244 | let arg = subst[0].clone().to_chalk(db); | 206 | let arg = ty.to_chalk(db); |
245 | let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); | 207 | let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); |
246 | let const_ = chalk_ir::ConstData { | 208 | let const_ = chalk_ir::ConstData { |
247 | ty: usize_ty, | 209 | ty: usize_ty, |
@@ -298,21 +260,6 @@ impl ToChalk for hir_def::TraitId { | |||
298 | } | 260 | } |
299 | } | 261 | } |
300 | 262 | ||
301 | impl ToChalk for OpaqueTyId { | ||
302 | type Chalk = chalk_ir::OpaqueTyId<Interner>; | ||
303 | |||
304 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId<Interner> { | ||
305 | db.intern_impl_trait_id(self).into() | ||
306 | } | ||
307 | |||
308 | fn from_chalk( | ||
309 | db: &dyn HirDatabase, | ||
310 | opaque_ty_id: chalk_ir::OpaqueTyId<Interner>, | ||
311 | ) -> OpaqueTyId { | ||
312 | db.lookup_intern_impl_trait_id(opaque_ty_id.into()) | ||
313 | } | ||
314 | } | ||
315 | |||
316 | impl ToChalk for hir_def::ImplId { | 263 | impl ToChalk for hir_def::ImplId { |
317 | type Chalk = ImplId; | 264 | type Chalk = ImplId; |
318 | 265 | ||
@@ -337,34 +284,6 @@ impl ToChalk for CallableDefId { | |||
337 | } | 284 | } |
338 | } | 285 | } |
339 | 286 | ||
340 | pub(crate) struct TypeAliasAsAssocType(pub(crate) TypeAliasId); | ||
341 | |||
342 | impl ToChalk for TypeAliasAsAssocType { | ||
343 | type Chalk = AssocTypeId; | ||
344 | |||
345 | fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId { | ||
346 | chalk_ir::AssocTypeId(self.0.as_intern_id()) | ||
347 | } | ||
348 | |||
349 | fn from_chalk(_db: &dyn HirDatabase, assoc_type_id: AssocTypeId) -> TypeAliasAsAssocType { | ||
350 | TypeAliasAsAssocType(InternKey::from_intern_id(assoc_type_id.0)) | ||
351 | } | ||
352 | } | ||
353 | |||
354 | pub(crate) struct TypeAliasAsForeignType(pub(crate) TypeAliasId); | ||
355 | |||
356 | impl ToChalk for TypeAliasAsForeignType { | ||
357 | type Chalk = ForeignDefId; | ||
358 | |||
359 | fn to_chalk(self, _db: &dyn HirDatabase) -> ForeignDefId { | ||
360 | chalk_ir::ForeignDefId(self.0.as_intern_id()) | ||
361 | } | ||
362 | |||
363 | fn from_chalk(_db: &dyn HirDatabase, foreign_def_id: ForeignDefId) -> TypeAliasAsForeignType { | ||
364 | TypeAliasAsForeignType(InternKey::from_intern_id(foreign_def_id.0)) | ||
365 | } | ||
366 | } | ||
367 | |||
368 | pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); | 287 | pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); |
369 | 288 | ||
370 | impl ToChalk for TypeAliasAsValue { | 289 | impl ToChalk for TypeAliasAsValue { |
@@ -446,8 +365,8 @@ impl ToChalk for ProjectionTy { | |||
446 | 365 | ||
447 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> { | 366 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> { |
448 | chalk_ir::ProjectionTy { | 367 | chalk_ir::ProjectionTy { |
449 | associated_ty_id: TypeAliasAsAssocType(self.associated_ty).to_chalk(db), | 368 | associated_ty_id: self.associated_ty_id, |
450 | substitution: self.parameters.to_chalk(db), | 369 | substitution: self.substitution.to_chalk(db), |
451 | } | 370 | } |
452 | } | 371 | } |
453 | 372 | ||
@@ -456,12 +375,8 @@ impl ToChalk for ProjectionTy { | |||
456 | projection_ty: chalk_ir::ProjectionTy<Interner>, | 375 | projection_ty: chalk_ir::ProjectionTy<Interner>, |
457 | ) -> ProjectionTy { | 376 | ) -> ProjectionTy { |
458 | ProjectionTy { | 377 | ProjectionTy { |
459 | associated_ty: from_chalk::<TypeAliasAsAssocType, _>( | 378 | associated_ty_id: projection_ty.associated_ty_id, |
460 | db, | 379 | substitution: from_chalk(db, projection_ty.substitution), |
461 | projection_ty.associated_ty_id, | ||
462 | ) | ||
463 | .0, | ||
464 | parameters: from_chalk(db, projection_ty.substitution), | ||
465 | } | 380 | } |
466 | } | 381 | } |
467 | } | 382 | } |
@@ -536,31 +451,6 @@ where | |||
536 | } | 451 | } |
537 | } | 452 | } |
538 | 453 | ||
539 | impl ToChalk for Arc<TraitEnvironment> { | ||
540 | type Chalk = chalk_ir::Environment<Interner>; | ||
541 | |||
542 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Environment<Interner> { | ||
543 | let mut clauses = Vec::new(); | ||
544 | for pred in &self.predicates { | ||
545 | if pred.is_error() { | ||
546 | // for env, we just ignore errors | ||
547 | continue; | ||
548 | } | ||
549 | let program_clause: chalk_ir::ProgramClause<Interner> = | ||
550 | pred.clone().to_chalk(db).cast(&Interner); | ||
551 | clauses.push(program_clause.into_from_env_clause(&Interner)); | ||
552 | } | ||
553 | chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses) | ||
554 | } | ||
555 | |||
556 | fn from_chalk( | ||
557 | _db: &dyn HirDatabase, | ||
558 | _env: chalk_ir::Environment<Interner>, | ||
559 | ) -> Arc<TraitEnvironment> { | ||
560 | unimplemented!() | ||
561 | } | ||
562 | } | ||
563 | |||
564 | impl<T: ToChalk> ToChalk for InEnvironment<T> | 454 | impl<T: ToChalk> ToChalk for InEnvironment<T> |
565 | where | 455 | where |
566 | T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>, | 456 | T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>, |
@@ -569,19 +459,16 @@ where | |||
569 | 459 | ||
570 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { | 460 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { |
571 | chalk_ir::InEnvironment { | 461 | chalk_ir::InEnvironment { |
572 | environment: self.environment.to_chalk(db), | 462 | environment: self.environment.env.clone(), |
573 | goal: self.value.to_chalk(db), | 463 | goal: self.value.to_chalk(db), |
574 | } | 464 | } |
575 | } | 465 | } |
576 | 466 | ||
577 | fn from_chalk( | 467 | fn from_chalk( |
578 | db: &dyn HirDatabase, | 468 | _db: &dyn HirDatabase, |
579 | in_env: chalk_ir::InEnvironment<T::Chalk>, | 469 | _in_env: chalk_ir::InEnvironment<T::Chalk>, |
580 | ) -> InEnvironment<T> { | 470 | ) -> InEnvironment<T> { |
581 | InEnvironment { | 471 | unimplemented!() |
582 | environment: from_chalk(db, in_env.environment), | ||
583 | value: from_chalk(db, in_env.goal), | ||
584 | } | ||
585 | } | 472 | } |
586 | } | 473 | } |
587 | 474 | ||
@@ -639,22 +526,24 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
639 | Some(rust_ir::InlineBound::TraitBound(trait_bound)) | 526 | Some(rust_ir::InlineBound::TraitBound(trait_bound)) |
640 | } | 527 | } |
641 | GenericPredicate::Projection(proj) => { | 528 | GenericPredicate::Projection(proj) => { |
642 | if &proj.projection_ty.parameters[0] != self_ty { | 529 | if &proj.projection_ty.substitution[0] != self_ty { |
643 | return None; | 530 | return None; |
644 | } | 531 | } |
645 | let trait_ = match proj.projection_ty.associated_ty.lookup(db.upcast()).container { | 532 | let trait_ = match from_assoc_type_id(proj.projection_ty.associated_ty_id) |
533 | .lookup(db.upcast()) | ||
534 | .container | ||
535 | { | ||
646 | AssocContainerId::TraitId(t) => t, | 536 | AssocContainerId::TraitId(t) => t, |
647 | _ => panic!("associated type not in trait"), | 537 | _ => panic!("associated type not in trait"), |
648 | }; | 538 | }; |
649 | let args_no_self = proj.projection_ty.parameters[1..] | 539 | let args_no_self = proj.projection_ty.substitution[1..] |
650 | .iter() | 540 | .iter() |
651 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 541 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
652 | .collect(); | 542 | .collect(); |
653 | let alias_eq_bound = rust_ir::AliasEqBound { | 543 | let alias_eq_bound = rust_ir::AliasEqBound { |
654 | value: proj.ty.clone().to_chalk(db), | 544 | value: proj.ty.clone().to_chalk(db), |
655 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | 545 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, |
656 | associated_ty_id: TypeAliasAsAssocType(proj.projection_ty.associated_ty) | 546 | associated_ty_id: proj.projection_ty.associated_ty_id, |
657 | .to_chalk(db), | ||
658 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | 547 | parameters: Vec::new(), // FIXME we don't support generic associated types yet |
659 | }; | 548 | }; |
660 | Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) | 549 | Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) |
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs index 75b16172e..8892a63a9 100644 --- a/crates/hir_ty/src/traits/chalk/tls.rs +++ b/crates/hir_ty/src/traits/chalk/tls.rs | |||
@@ -4,8 +4,8 @@ use std::fmt; | |||
4 | use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication}; | 4 | use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication}; |
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | 6 | ||
7 | use super::{from_chalk, Interner, TypeAliasAsAssocType}; | 7 | use super::{from_chalk, Interner}; |
8 | use crate::{db::HirDatabase, CallableDefId}; | 8 | use crate::{db::HirDatabase, from_assoc_type_id, CallableDefId}; |
9 | use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; | 9 | use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; |
10 | 10 | ||
11 | pub(crate) use unsafe_tls::{set_current_program, with_current_program}; | 11 | pub(crate) use unsafe_tls::{set_current_program, with_current_program}; |
@@ -41,7 +41,7 @@ impl DebugContext<'_> { | |||
41 | id: super::AssocTypeId, | 41 | id: super::AssocTypeId, |
42 | fmt: &mut fmt::Formatter<'_>, | 42 | fmt: &mut fmt::Formatter<'_>, |
43 | ) -> Result<(), fmt::Error> { | 43 | ) -> Result<(), fmt::Error> { |
44 | let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(self.0, id).0; | 44 | let type_alias: TypeAliasId = from_assoc_type_id(id); |
45 | let type_alias_data = self.0.type_alias_data(type_alias); | 45 | let type_alias_data = self.0.type_alias_data(type_alias); |
46 | let trait_ = match type_alias.lookup(self.0.upcast()).container { | 46 | let trait_ = match type_alias.lookup(self.0.upcast()).container { |
47 | AssocContainerId::TraitId(t) => t, | 47 | AssocContainerId::TraitId(t) => t, |
@@ -75,8 +75,7 @@ impl DebugContext<'_> { | |||
75 | projection_ty: &chalk_ir::ProjectionTy<Interner>, | 75 | projection_ty: &chalk_ir::ProjectionTy<Interner>, |
76 | fmt: &mut fmt::Formatter<'_>, | 76 | fmt: &mut fmt::Formatter<'_>, |
77 | ) -> Result<(), fmt::Error> { | 77 | ) -> Result<(), fmt::Error> { |
78 | let type_alias: TypeAliasId = | 78 | let type_alias = from_assoc_type_id(projection_ty.associated_ty_id); |
79 | from_chalk::<TypeAliasAsAssocType, _>(self.0, projection_ty.associated_ty_id).0; | ||
80 | let type_alias_data = self.0.type_alias_data(type_alias); | 79 | let type_alias_data = self.0.type_alias_data(type_alias); |
81 | let trait_ = match type_alias.lookup(self.0.upcast()).container { | 80 | let trait_ = match type_alias.lookup(self.0.upcast()).container { |
82 | AssocContainerId::TraitId(t) => t, | 81 | AssocContainerId::TraitId(t) => t, |