mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 17:28:09 +00:00
Move things from traits
module to types
as well
This commit is contained in:
parent
508a1ecad3
commit
645a9c3a27
12 changed files with 107 additions and 110 deletions
|
@ -55,10 +55,11 @@ use hir_ty::{
|
|||
autoderef, could_unify,
|
||||
method_resolution::{self, TyFingerprint},
|
||||
primitive::UintTy,
|
||||
traits::{FnTrait, Solution, SolutionVariables},
|
||||
traits::FnTrait,
|
||||
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
|
||||
DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Substitution,
|
||||
TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, TyVariableKind, WhereClause,
|
||||
DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution,
|
||||
SolutionVariables, Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind,
|
||||
TyVariableKind, WhereClause,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
|
|
@ -12,10 +12,8 @@ use hir_expand::name::name;
|
|||
use log::{info, warn};
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
traits::{InEnvironment, Solution},
|
||||
AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, Ty,
|
||||
TyBuilder, TyKind,
|
||||
db::HirDatabase, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex,
|
||||
InEnvironment, Interner, Solution, Ty, TyBuilder, TyKind,
|
||||
};
|
||||
|
||||
const AUTODEREF_RECURSION_LIMIT: usize = 10;
|
||||
|
|
|
@ -123,7 +123,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
|||
&self,
|
||||
krate: CrateId,
|
||||
goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
|
||||
) -> Option<crate::traits::Solution>;
|
||||
) -> Option<crate::Solution>;
|
||||
|
||||
#[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
|
||||
fn program_clauses_for_chalk_env(
|
||||
|
|
|
@ -37,8 +37,8 @@ use stdx::impl_from;
|
|||
use syntax::SmolStr;
|
||||
|
||||
use super::{
|
||||
traits::{DomainGoal, Guidance, Solution},
|
||||
InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty, TypeWalk,
|
||||
DomainGoal, Guidance, InEnvironment, ProjectionTy, Solution, TraitEnvironment, TraitRef, Ty,
|
||||
TypeWalk,
|
||||
};
|
||||
use crate::{
|
||||
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
|
||||
use hir_def::lang_item::LangItemTarget;
|
||||
|
||||
use crate::{autoderef, traits::Solution, Interner, Ty, TyBuilder, TyKind};
|
||||
use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyKind};
|
||||
|
||||
use super::{InEnvironment, InferenceContext};
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ use crate::{
|
|||
method_resolution, op,
|
||||
primitive::{self, UintTy},
|
||||
to_chalk_trait_id,
|
||||
traits::{chalk::from_chalk, FnTrait, InEnvironment},
|
||||
traits::{chalk::from_chalk, FnTrait},
|
||||
utils::{generics, variant_data, Generics},
|
||||
AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Rawness, Scalar, Substitution,
|
||||
TraitRef, Ty, TyBuilder, TyKind,
|
||||
AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, Rawness, Scalar,
|
||||
Substitution, TraitRef, Ty, TyBuilder, TyKind,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
|
@ -49,7 +49,7 @@ pub use lower::{
|
|||
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
|
||||
TyDefId, TyLoweringContext, ValueTyDefId,
|
||||
};
|
||||
pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment};
|
||||
pub use traits::TraitEnvironment;
|
||||
pub use types::*;
|
||||
pub use walk::TypeWalk;
|
||||
|
||||
|
|
|
@ -800,7 +800,7 @@ pub fn implements_trait_unique(
|
|||
let goal = generic_implements_goal(db, env, trait_, ty.clone());
|
||||
let solution = db.trait_solve(krate, goal);
|
||||
|
||||
matches!(solution, Some(crate::traits::Solution::Unique(_)))
|
||||
matches!(solution, Some(crate::Solution::Unique(_)))
|
||||
}
|
||||
|
||||
/// This creates Substs for a trait with the given Self type and type variables
|
||||
|
|
|
@ -8,8 +8,8 @@ use hir_def::{lang_item::LangItemTarget, TraitId};
|
|||
use stdx::panic_context;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, Ty, TyKind,
|
||||
TypeWalk, WhereClause,
|
||||
db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment,
|
||||
Solution, SolutionVariables, Ty, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
use self::chalk::{from_chalk, Interner, ToChalk};
|
||||
|
@ -70,55 +70,6 @@ impl Default for TraitEnvironment {
|
|||
}
|
||||
}
|
||||
|
||||
/// Something (usually a goal), along with an environment.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct InEnvironment<T> {
|
||||
pub environment: chalk_ir::Environment<Interner>,
|
||||
pub goal: T,
|
||||
}
|
||||
|
||||
impl<T> InEnvironment<T> {
|
||||
pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> {
|
||||
InEnvironment { environment, goal: value }
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that needs to be proven (by Chalk) during type checking, e.g. that
|
||||
/// a certain type implements a certain trait. Proving the Obligation might
|
||||
/// result in additional information about inference variables.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum DomainGoal {
|
||||
Holds(WhereClause),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct AliasEq {
|
||||
pub alias: AliasTy,
|
||||
pub ty: Ty,
|
||||
}
|
||||
|
||||
impl TypeWalk for AliasEq {
|
||||
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||
self.ty.walk(f);
|
||||
match &self.alias {
|
||||
AliasTy::Projection(projection_ty) => projection_ty.walk(f),
|
||||
AliasTy::Opaque(opaque) => opaque.walk(f),
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_mut_binders(
|
||||
&mut self,
|
||||
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
|
||||
binders: DebruijnIndex,
|
||||
) {
|
||||
self.ty.walk_mut_binders(f, binders);
|
||||
match &mut self.alias {
|
||||
AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders),
|
||||
AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Solve a trait goal using Chalk.
|
||||
pub(crate) fn trait_solve_query(
|
||||
db: &dyn HirDatabase,
|
||||
|
@ -246,41 +197,6 @@ fn solution_from_chalk(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SolutionVariables(pub Canonical<Substitution>);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// A (possible) solution for a proposed goal.
|
||||
pub enum Solution {
|
||||
/// The goal indeed holds, and there is a unique value for all existential
|
||||
/// variables.
|
||||
Unique(SolutionVariables),
|
||||
|
||||
/// The goal may be provable in multiple ways, but regardless we may have some guidance
|
||||
/// for type inference. In this case, we don't return any lifetime
|
||||
/// constraints, since we have not "committed" to any particular solution
|
||||
/// yet.
|
||||
Ambig(Guidance),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// When a goal holds ambiguously (e.g., because there are multiple possible
|
||||
/// solutions), we issue a set of *guidance* back to type inference.
|
||||
pub enum Guidance {
|
||||
/// The existential variables *must* have the given values if the goal is
|
||||
/// ever to hold, but that alone isn't enough to guarantee the goal will
|
||||
/// actually hold.
|
||||
Definite(SolutionVariables),
|
||||
|
||||
/// There are multiple plausible values for the existentials, but the ones
|
||||
/// here are suggested as the preferred choice heuristically. These should
|
||||
/// be used for inference fallback only.
|
||||
Suggested(SolutionVariables),
|
||||
|
||||
/// There's no useful information to feed back to type inference
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum FnTrait {
|
||||
FnOnce,
|
||||
|
|
|
@ -10,11 +10,9 @@ use base_db::salsa::InternKey;
|
|||
use hir_def::{GenericDefId, TypeAliasId};
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
primitive::UintTy,
|
||||
traits::{Canonical, DomainGoal},
|
||||
AliasTy, CallableDefId, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy,
|
||||
QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
|
||||
db::HirDatabase, primitive::UintTy, AliasTy, CallableDefId, Canonical, DomainGoal, FnPointer,
|
||||
GenericArg, InEnvironment, OpaqueTy, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution,
|
||||
TraitRef, Ty, TypeWalk, WhereClause,
|
||||
};
|
||||
|
||||
use super::interner::*;
|
||||
|
|
|
@ -11,7 +11,7 @@ use hir_def::LifetimeParamId;
|
|||
use smallvec::SmallVec;
|
||||
|
||||
use crate::{
|
||||
AliasEq, AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId,
|
||||
AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId,
|
||||
InferenceVar, Interner, OpaqueTyId, PlaceholderIndex,
|
||||
};
|
||||
|
||||
|
@ -352,3 +352,65 @@ pub struct Canonical<T> {
|
|||
pub value: T,
|
||||
pub binders: CanonicalVarKinds,
|
||||
}
|
||||
|
||||
/// Something (usually a goal), along with an environment.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct InEnvironment<T> {
|
||||
pub environment: chalk_ir::Environment<Interner>,
|
||||
pub goal: T,
|
||||
}
|
||||
|
||||
impl<T> InEnvironment<T> {
|
||||
pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> {
|
||||
InEnvironment { environment, goal: value }
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that needs to be proven (by Chalk) during type checking, e.g. that
|
||||
/// a certain type implements a certain trait. Proving the Obligation might
|
||||
/// result in additional information about inference variables.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum DomainGoal {
|
||||
Holds(WhereClause),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct AliasEq {
|
||||
pub alias: AliasTy,
|
||||
pub ty: Ty,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct SolutionVariables(pub Canonical<Substitution>);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// A (possible) solution for a proposed goal.
|
||||
pub enum Solution {
|
||||
/// The goal indeed holds, and there is a unique value for all existential
|
||||
/// variables.
|
||||
Unique(SolutionVariables),
|
||||
|
||||
/// The goal may be provable in multiple ways, but regardless we may have some guidance
|
||||
/// for type inference. In this case, we don't return any lifetime
|
||||
/// constraints, since we have not "committed" to any particular solution
|
||||
/// yet.
|
||||
Ambig(Guidance),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
/// When a goal holds ambiguously (e.g., because there are multiple possible
|
||||
/// solutions), we issue a set of *guidance* back to type inference.
|
||||
pub enum Guidance {
|
||||
/// The existential variables *must* have the given values if the goal is
|
||||
/// ever to hold, but that alone isn't enough to guarantee the goal will
|
||||
/// actually hold.
|
||||
Definite(SolutionVariables),
|
||||
|
||||
/// There are multiple plausible values for the existentials, but the ones
|
||||
/// here are suggested as the preferred choice heuristically. These should
|
||||
/// be used for inference fallback only.
|
||||
Suggested(SolutionVariables),
|
||||
|
||||
/// There's no useful information to feed back to type inference
|
||||
Unknown,
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::mem;
|
|||
use chalk_ir::DebruijnIndex;
|
||||
|
||||
use crate::{
|
||||
utils::make_mut_slice, AliasTy, Binders, CallableSig, GenericArg, GenericArgData, Interner,
|
||||
OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause,
|
||||
utils::make_mut_slice, AliasEq, AliasTy, Binders, CallableSig, GenericArg, GenericArgData,
|
||||
Interner, OpaqueTy, ProjectionTy, Substitution, TraitRef, Ty, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
/// This allows walking structures that contain types to do something with those
|
||||
|
@ -357,3 +357,25 @@ impl TypeWalk for CallableSig {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeWalk for AliasEq {
|
||||
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||
self.ty.walk(f);
|
||||
match &self.alias {
|
||||
AliasTy::Projection(projection_ty) => projection_ty.walk(f),
|
||||
AliasTy::Opaque(opaque) => opaque.walk(f),
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_mut_binders(
|
||||
&mut self,
|
||||
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
|
||||
binders: DebruijnIndex,
|
||||
) {
|
||||
self.ty.walk_mut_binders(f, binders);
|
||||
match &mut self.alias {
|
||||
AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders),
|
||||
AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue