Move things from traits module to types as well

This commit is contained in:
Florian Diebold 2021-04-04 20:27:40 +02:00
parent 508a1ecad3
commit 645a9c3a27
12 changed files with 107 additions and 110 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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(

View file

@ -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,

View file

@ -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};

View file

@ -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::{

View file

@ -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;

View file

@ -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

View file

@ -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,

View file

@ -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::*;

View file

@ -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,
}

View file

@ -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),
}
}
}