aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/autoderef.rs6
-rw-r--r--crates/hir_ty/src/db.rs2
-rw-r--r--crates/hir_ty/src/infer.rs4
-rw-r--r--crates/hir_ty/src/infer/coerce.rs2
-rw-r--r--crates/hir_ty/src/infer/expr.rs6
-rw-r--r--crates/hir_ty/src/lib.rs2
-rw-r--r--crates/hir_ty/src/method_resolution.rs2
-rw-r--r--crates/hir_ty/src/traits.rs88
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs8
-rw-r--r--crates/hir_ty/src/types.rs64
-rw-r--r--crates/hir_ty/src/walk.rs26
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;
12use log::{info, warn}; 12use log::{info, warn};
13 13
14use crate::{ 14use 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
21const AUTODEREF_RECURSION_LIMIT: usize = 10; 19const 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;
37use syntax::SmolStr; 37use syntax::SmolStr;
38 38
39use super::{ 39use 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};
43use crate::{ 43use 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 @@
7use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; 7use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{autoderef, traits::Solution, Interner, Ty, TyBuilder, TyKind}; 10use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyKind};
11 11
12use super::{InEnvironment, InferenceContext}; 12use 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
29use super::{ 29use 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};
52pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment}; 52pub use traits::TraitEnvironment;
53pub use types::*; 53pub use types::*;
54pub use walk::TypeWalk; 54pub 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};
8use stdx::panic_context; 8use stdx::panic_context;
9 9
10use crate::{ 10use 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
15use self::chalk::{from_chalk, Interner, ToChalk}; 15use 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)]
75pub struct InEnvironment<T> {
76 pub environment: chalk_ir::Environment<Interner>,
77 pub goal: T,
78}
79
80impl<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)]
90pub enum DomainGoal {
91 Holds(WhereClause),
92}
93
94#[derive(Clone, Debug, PartialEq, Eq, Hash)]
95pub struct AliasEq {
96 pub alias: AliasTy,
97 pub ty: Ty,
98}
99
100impl 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.
123pub(crate) fn trait_solve_query( 74pub(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)]
250pub struct SolutionVariables(pub Canonical<Substitution>);
251
252#[derive(Clone, Debug, PartialEq, Eq)]
253/// A (possible) solution for a proposed goal.
254pub 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.
269pub 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)]
285pub enum FnTrait { 201pub 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;
10use hir_def::{GenericDefId, TypeAliasId}; 10use hir_def::{GenericDefId, TypeAliasId};
11 11
12use crate::{ 12use 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
20use super::interner::*; 18use 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;
11use smallvec::SmallVec; 11use smallvec::SmallVec;
12 12
13use crate::{ 13use 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)]
358pub struct InEnvironment<T> {
359 pub environment: chalk_ir::Environment<Interner>,
360 pub goal: T,
361}
362
363impl<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)]
373pub enum DomainGoal {
374 Holds(WhereClause),
375}
376
377#[derive(Clone, Debug, PartialEq, Eq, Hash)]
378pub struct AliasEq {
379 pub alias: AliasTy,
380 pub ty: Ty,
381}
382
383#[derive(Clone, Debug, PartialEq, Eq)]
384pub struct SolutionVariables(pub Canonical<Substitution>);
385
386#[derive(Clone, Debug, PartialEq, Eq)]
387/// A (possible) solution for a proposed goal.
388pub 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.
403pub 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;
6use chalk_ir::DebruijnIndex; 6use chalk_ir::DebruijnIndex;
7 7
8use crate::{ 8use 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
361impl 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}