diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/db.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 88 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/types.rs | 64 | ||||
-rw-r--r-- | crates/hir_ty/src/walk.rs | 26 |
11 files changed, 103 insertions, 107 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index 70c56cc45..7ca4af80e 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -12,10 +12,8 @@ use hir_expand::name::name; | |||
12 | use log::{info, warn}; | 12 | use log::{info, warn}; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | db::HirDatabase, | 15 | db::HirDatabase, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, |
16 | traits::{InEnvironment, Solution}, | 16 | InEnvironment, Interner, Solution, Ty, TyBuilder, TyKind, |
17 | AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, Ty, | ||
18 | TyBuilder, TyKind, | ||
19 | }; | 17 | }; |
20 | 18 | ||
21 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 19 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs index 58e4247c6..4300680d9 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -123,7 +123,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
123 | &self, | 123 | &self, |
124 | krate: CrateId, | 124 | krate: CrateId, |
125 | goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>, | 125 | goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>, |
126 | ) -> Option<crate::traits::Solution>; | 126 | ) -> Option<crate::Solution>; |
127 | 127 | ||
128 | #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)] | 128 | #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)] |
129 | fn program_clauses_for_chalk_env( | 129 | fn program_clauses_for_chalk_env( |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 1b1d4458c..bb885db35 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -37,8 +37,8 @@ use stdx::impl_from; | |||
37 | use syntax::SmolStr; | 37 | use syntax::SmolStr; |
38 | 38 | ||
39 | use super::{ | 39 | use super::{ |
40 | traits::{DomainGoal, Guidance, Solution}, | 40 | DomainGoal, Guidance, InEnvironment, ProjectionTy, Solution, TraitEnvironment, TraitRef, Ty, |
41 | InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty, TypeWalk, | 41 | TypeWalk, |
42 | }; | 42 | }; |
43 | use crate::{ | 43 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, | 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, |
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 028a4d568..32c273afc 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::{cast::Cast, Mutability, TyVariableKind}; | 7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{autoderef, traits::Solution, Interner, Ty, TyBuilder, TyKind}; | 10 | use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyKind}; |
11 | 11 | ||
12 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
13 | 13 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index a87429a24..ccaae53e9 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -20,10 +20,10 @@ use crate::{ | |||
20 | method_resolution, op, | 20 | method_resolution, op, |
21 | primitive::{self, UintTy}, | 21 | primitive::{self, UintTy}, |
22 | to_chalk_trait_id, | 22 | to_chalk_trait_id, |
23 | traits::{chalk::from_chalk, FnTrait, InEnvironment}, | 23 | traits::{chalk::from_chalk, FnTrait}, |
24 | utils::{generics, variant_data, Generics}, | 24 | utils::{generics, variant_data, Generics}, |
25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution, | 25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, Rawness, Scalar, |
26 | TraitRef, Ty, TyBuilder, TyKind, | 26 | Substitution, TraitRef, Ty, TyBuilder, TyKind, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | use super::{ | 29 | use super::{ |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 40abbce42..76609e2df 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -49,7 +49,7 @@ pub use lower::{ | |||
49 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 49 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
50 | TyDefId, TyLoweringContext, ValueTyDefId, | 50 | TyDefId, TyLoweringContext, ValueTyDefId, |
51 | }; | 51 | }; |
52 | pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment}; | 52 | pub use traits::TraitEnvironment; |
53 | pub use types::*; | 53 | pub use types::*; |
54 | pub use walk::TypeWalk; | 54 | pub use walk::TypeWalk; |
55 | 55 | ||
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index a76586f0c..0e4a620b6 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -800,7 +800,7 @@ pub fn implements_trait_unique( | |||
800 | let goal = generic_implements_goal(db, env, trait_, ty.clone()); | 800 | let goal = generic_implements_goal(db, env, trait_, ty.clone()); |
801 | let solution = db.trait_solve(krate, goal); | 801 | let solution = db.trait_solve(krate, goal); |
802 | 802 | ||
803 | matches!(solution, Some(crate::traits::Solution::Unique(_))) | 803 | matches!(solution, Some(crate::Solution::Unique(_))) |
804 | } | 804 | } |
805 | 805 | ||
806 | /// This creates Substs for a trait with the given Self type and type variables | 806 | /// This creates Substs for a trait with the given Self type and type variables |
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index e5e8cff33..66d600bfc 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -8,8 +8,8 @@ use hir_def::{lang_item::LangItemTarget, TraitId}; | |||
8 | use stdx::panic_context; | 8 | use stdx::panic_context; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, Ty, TyKind, | 11 | db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, |
12 | TypeWalk, WhereClause, | 12 | Solution, SolutionVariables, Ty, TyKind, WhereClause, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | use self::chalk::{from_chalk, Interner, ToChalk}; | 15 | use self::chalk::{from_chalk, Interner, ToChalk}; |
@@ -70,55 +70,6 @@ impl Default for TraitEnvironment { | |||
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | /// Something (usually a goal), along with an environment. | ||
74 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
75 | pub struct InEnvironment<T> { | ||
76 | pub environment: chalk_ir::Environment<Interner>, | ||
77 | pub goal: T, | ||
78 | } | ||
79 | |||
80 | impl<T> InEnvironment<T> { | ||
81 | pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> { | ||
82 | InEnvironment { environment, goal: value } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | /// Something that needs to be proven (by Chalk) during type checking, e.g. that | ||
87 | /// a certain type implements a certain trait. Proving the Obligation might | ||
88 | /// result in additional information about inference variables. | ||
89 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
90 | pub enum DomainGoal { | ||
91 | Holds(WhereClause), | ||
92 | } | ||
93 | |||
94 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
95 | pub struct AliasEq { | ||
96 | pub alias: AliasTy, | ||
97 | pub ty: Ty, | ||
98 | } | ||
99 | |||
100 | impl TypeWalk for AliasEq { | ||
101 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
102 | self.ty.walk(f); | ||
103 | match &self.alias { | ||
104 | AliasTy::Projection(projection_ty) => projection_ty.walk(f), | ||
105 | AliasTy::Opaque(opaque) => opaque.walk(f), | ||
106 | } | ||
107 | } | ||
108 | |||
109 | fn walk_mut_binders( | ||
110 | &mut self, | ||
111 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | ||
112 | binders: DebruijnIndex, | ||
113 | ) { | ||
114 | self.ty.walk_mut_binders(f, binders); | ||
115 | match &mut self.alias { | ||
116 | AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders), | ||
117 | AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders), | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /// Solve a trait goal using Chalk. | 73 | /// Solve a trait goal using Chalk. |
123 | pub(crate) fn trait_solve_query( | 74 | pub(crate) fn trait_solve_query( |
124 | db: &dyn HirDatabase, | 75 | db: &dyn HirDatabase, |
@@ -246,41 +197,6 @@ fn solution_from_chalk( | |||
246 | } | 197 | } |
247 | } | 198 | } |
248 | 199 | ||
249 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
250 | pub struct SolutionVariables(pub Canonical<Substitution>); | ||
251 | |||
252 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
253 | /// A (possible) solution for a proposed goal. | ||
254 | pub enum Solution { | ||
255 | /// The goal indeed holds, and there is a unique value for all existential | ||
256 | /// variables. | ||
257 | Unique(SolutionVariables), | ||
258 | |||
259 | /// The goal may be provable in multiple ways, but regardless we may have some guidance | ||
260 | /// for type inference. In this case, we don't return any lifetime | ||
261 | /// constraints, since we have not "committed" to any particular solution | ||
262 | /// yet. | ||
263 | Ambig(Guidance), | ||
264 | } | ||
265 | |||
266 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
267 | /// When a goal holds ambiguously (e.g., because there are multiple possible | ||
268 | /// solutions), we issue a set of *guidance* back to type inference. | ||
269 | pub enum Guidance { | ||
270 | /// The existential variables *must* have the given values if the goal is | ||
271 | /// ever to hold, but that alone isn't enough to guarantee the goal will | ||
272 | /// actually hold. | ||
273 | Definite(SolutionVariables), | ||
274 | |||
275 | /// There are multiple plausible values for the existentials, but the ones | ||
276 | /// here are suggested as the preferred choice heuristically. These should | ||
277 | /// be used for inference fallback only. | ||
278 | Suggested(SolutionVariables), | ||
279 | |||
280 | /// There's no useful information to feed back to type inference | ||
281 | Unknown, | ||
282 | } | ||
283 | |||
284 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 200 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
285 | pub enum FnTrait { | 201 | pub enum FnTrait { |
286 | FnOnce, | 202 | FnOnce, |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 3a5800885..5e4f97a46 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -10,11 +10,9 @@ use base_db::salsa::InternKey; | |||
10 | use hir_def::{GenericDefId, TypeAliasId}; | 10 | use hir_def::{GenericDefId, TypeAliasId}; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::HirDatabase, | 13 | db::HirDatabase, primitive::UintTy, AliasTy, CallableDefId, Canonical, DomainGoal, FnPointer, |
14 | primitive::UintTy, | 14 | GenericArg, InEnvironment, OpaqueTy, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, |
15 | traits::{Canonical, DomainGoal}, | 15 | TraitRef, Ty, TypeWalk, WhereClause, |
16 | AliasTy, CallableDefId, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy, | ||
17 | QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause, | ||
18 | }; | 16 | }; |
19 | 17 | ||
20 | use super::interner::*; | 18 | use super::interner::*; |
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs index d00f8e9ab..53662fcdc 100644 --- a/crates/hir_ty/src/types.rs +++ b/crates/hir_ty/src/types.rs | |||
@@ -11,7 +11,7 @@ use hir_def::LifetimeParamId; | |||
11 | use smallvec::SmallVec; | 11 | use smallvec::SmallVec; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | AliasEq, AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, | 14 | AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, |
15 | InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, | 15 | InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, |
16 | }; | 16 | }; |
17 | 17 | ||
@@ -352,3 +352,65 @@ pub struct Canonical<T> { | |||
352 | pub value: T, | 352 | pub value: T, |
353 | pub binders: CanonicalVarKinds, | 353 | pub binders: CanonicalVarKinds, |
354 | } | 354 | } |
355 | |||
356 | /// Something (usually a goal), along with an environment. | ||
357 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
358 | pub struct InEnvironment<T> { | ||
359 | pub environment: chalk_ir::Environment<Interner>, | ||
360 | pub goal: T, | ||
361 | } | ||
362 | |||
363 | impl<T> InEnvironment<T> { | ||
364 | pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> { | ||
365 | InEnvironment { environment, goal: value } | ||
366 | } | ||
367 | } | ||
368 | |||
369 | /// Something that needs to be proven (by Chalk) during type checking, e.g. that | ||
370 | /// a certain type implements a certain trait. Proving the Obligation might | ||
371 | /// result in additional information about inference variables. | ||
372 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
373 | pub enum DomainGoal { | ||
374 | Holds(WhereClause), | ||
375 | } | ||
376 | |||
377 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
378 | pub struct AliasEq { | ||
379 | pub alias: AliasTy, | ||
380 | pub ty: Ty, | ||
381 | } | ||
382 | |||
383 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
384 | pub struct SolutionVariables(pub Canonical<Substitution>); | ||
385 | |||
386 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
387 | /// A (possible) solution for a proposed goal. | ||
388 | pub enum Solution { | ||
389 | /// The goal indeed holds, and there is a unique value for all existential | ||
390 | /// variables. | ||
391 | Unique(SolutionVariables), | ||
392 | |||
393 | /// The goal may be provable in multiple ways, but regardless we may have some guidance | ||
394 | /// for type inference. In this case, we don't return any lifetime | ||
395 | /// constraints, since we have not "committed" to any particular solution | ||
396 | /// yet. | ||
397 | Ambig(Guidance), | ||
398 | } | ||
399 | |||
400 | #[derive(Clone, Debug, PartialEq, Eq)] | ||
401 | /// When a goal holds ambiguously (e.g., because there are multiple possible | ||
402 | /// solutions), we issue a set of *guidance* back to type inference. | ||
403 | pub enum Guidance { | ||
404 | /// The existential variables *must* have the given values if the goal is | ||
405 | /// ever to hold, but that alone isn't enough to guarantee the goal will | ||
406 | /// actually hold. | ||
407 | Definite(SolutionVariables), | ||
408 | |||
409 | /// There are multiple plausible values for the existentials, but the ones | ||
410 | /// here are suggested as the preferred choice heuristically. These should | ||
411 | /// be used for inference fallback only. | ||
412 | Suggested(SolutionVariables), | ||
413 | |||
414 | /// There's no useful information to feed back to type inference | ||
415 | Unknown, | ||
416 | } | ||
diff --git a/crates/hir_ty/src/walk.rs b/crates/hir_ty/src/walk.rs index fec5c2f42..bfb3f1041 100644 --- a/crates/hir_ty/src/walk.rs +++ b/crates/hir_ty/src/walk.rs | |||
@@ -6,8 +6,8 @@ use std::mem; | |||
6 | use chalk_ir::DebruijnIndex; | 6 | use chalk_ir::DebruijnIndex; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | utils::make_mut_slice, AliasTy, Binders, CallableSig, GenericArg, GenericArgData, Interner, | 9 | utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, GenericArg, GenericArgData, |
10 | OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause, | 10 | Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | /// This allows walking structures that contain types to do something with those | 13 | /// This allows walking structures that contain types to do something with those |
@@ -357,3 +357,25 @@ impl TypeWalk for CallableSig { | |||
357 | } | 357 | } |
358 | } | 358 | } |
359 | } | 359 | } |
360 | |||
361 | impl TypeWalk for AliasEq { | ||
362 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
363 | self.ty.walk(f); | ||
364 | match &self.alias { | ||
365 | AliasTy::Projection(projection_ty) => projection_ty.walk(f), | ||
366 | AliasTy::Opaque(opaque) => opaque.walk(f), | ||
367 | } | ||
368 | } | ||
369 | |||
370 | fn walk_mut_binders( | ||
371 | &mut self, | ||
372 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | ||
373 | binders: DebruijnIndex, | ||
374 | ) { | ||
375 | self.ty.walk_mut_binders(f, binders); | ||
376 | match &mut self.alias { | ||
377 | AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders), | ||
378 | AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders), | ||
379 | } | ||
380 | } | ||
381 | } | ||