Skip to content

Commit

Permalink
Merge #8356
Browse files Browse the repository at this point in the history
8356: Align more methods to Chalk r=flodiebold a=flodiebold

Related to #8313.

Move some inherent methods that don't exist in Chalk to an extension trait, remove some others.

Co-authored-by: Florian Diebold <[email protected]>
  • Loading branch information
bors[bot] and flodiebold authored Apr 5, 2021
2 parents 7278108 + d4a6a13 commit 7ac1c8f
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 90 deletions.
2 changes: 1 addition & 1 deletion crates/hir_ty/src/autoderef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use log::{info, warn};

use crate::{
db::HirDatabase, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex,
InEnvironment, Interner, Solution, Ty, TyBuilder, TyKind,
InEnvironment, Interner, ProjectionTyExt, Solution, Ty, TyBuilder, TyKind,
};

const AUTODEREF_RECURSION_LIMIT: usize = 10;
Expand Down
28 changes: 27 additions & 1 deletion crates/hir_ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! Various extensions traits for Chalk types.
use crate::{Interner, Ty, TyKind};
use hir_def::{AssocContainerId, Lookup, TraitId};

use crate::{
db::HirDatabase, from_assoc_type_id, to_chalk_trait_id, Interner, ProjectionTy, TraitRef, Ty,
TyKind,
};

pub trait TyExt {
fn is_unit(&self) -> bool;
Expand All @@ -11,3 +16,24 @@ impl TyExt for Ty {
matches!(self.kind(&Interner), TyKind::Tuple(0, _))
}
}

pub trait ProjectionTyExt {
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef;
fn trait_(&self, db: &dyn HirDatabase) -> TraitId;
}

impl ProjectionTyExt for ProjectionTy {
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
TraitRef {
trait_id: to_chalk_trait_id(self.trait_(db)),
substitution: self.substitution.clone(),
}
}

fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
AssocContainerId::TraitId(it) => it,
_ => panic!("projection ty without parent trait"),
}
}
}
3 changes: 2 additions & 1 deletion crates/hir_ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ use crate::{
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy,
ProjectionTy, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind, WhereClause,
ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind,
WhereClause,
};

pub struct HirFormatter<'a> {
Expand Down
10 changes: 6 additions & 4 deletions crates/hir_ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use crate::{
to_chalk_trait_id,
traits::{chalk::from_chalk, FnTrait},
utils::{generics, variant_data, Generics},
AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, Rawness, Scalar,
Substitution, TraitRef, Ty, TyBuilder, TyKind,
AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, ProjectionTyExt,
Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind,
};

use super::{
Expand Down Expand Up @@ -180,7 +180,8 @@ impl<'a> InferenceContext<'a> {
let inner_ty = self.infer_expr(*body, &Expectation::none());
let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
TyKind::OpaqueType(opaque_ty_id, Substitution::single(inner_ty)).intern(&Interner)
TyKind::OpaqueType(opaque_ty_id, Substitution::from1(&Interner, inner_ty))
.intern(&Interner)
}
Expr::Loop { body, label } => {
self.breakables.push(BreakableContext {
Expand Down Expand Up @@ -266,7 +267,8 @@ impl<'a> InferenceContext<'a> {
.intern(&Interner);
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
let closure_ty =
TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner);
TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty))
.intern(&Interner);

// Eagerly try to relate the closure type with the expected
// type, otherwise we often won't have enough information to
Expand Down
75 changes: 7 additions & 68 deletions crates/hir_ty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ mod test_db;

use std::sync::Arc;

use chalk_ext::ProjectionTyExt;
use itertools::Itertools;
use smallvec::SmallVec;

use base_db::salsa;
use hir_def::{
Expand All @@ -49,16 +49,14 @@ pub use lower::{
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
TyDefId, TyLoweringContext, ValueTyDefId,
};
pub use traits::TraitEnvironment;
pub use traits::{chalk::Interner, TraitEnvironment};
pub use types::*;
pub use walk::TypeWalk;

pub use chalk_ir::{
cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
};

pub use crate::traits::chalk::Interner;

pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
pub type FnDefId = chalk_ir::FnDefId<Interner>;
Expand All @@ -72,37 +70,9 @@ pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;

pub type ChalkTraitId = chalk_ir::TraitId<Interner>;

impl ProjectionTy {
pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
TraitRef {
trait_id: to_chalk_trait_id(self.trait_(db)),
substitution: self.substitution.clone(),
}
}

pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
&self.substitution.interned()[0].assert_ty_ref(interner)
}

fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
AssocContainerId::TraitId(it) => it,
_ => panic!("projection ty without parent trait"),
}
}
}

pub type FnSig = chalk_ir::FnSig<Interner>;

impl Substitution {
pub fn single(ty: Ty) -> Substitution {
Substitution::intern({
let mut v = SmallVec::new();
v.push(ty.cast(&Interner));
v
})
}

pub fn prefix(&self, n: usize) -> Substitution {
Substitution::intern(self.interned()[..std::cmp::min(self.len(&Interner), n)].into())
}
Expand All @@ -119,22 +89,11 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
generics(db.upcast(), id.parent).param_idx(id)
}

impl<T> Binders<T> {
pub fn wrap_empty(value: T) -> Self
where
T: TypeWalk,
{
Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE))
}
}

impl<T: TypeWalk> Binders<T> {
/// Substitutes all variables.
pub fn substitute(self, interner: &Interner, subst: &Substitution) -> T {
let (value, binders) = self.into_value_and_skipped_binders();
assert_eq!(subst.len(interner), binders.len(interner));
value.subst_bound_vars(subst)
}
pub fn wrap_empty_binders<T>(value: T) -> Binders<T>
where
T: TypeWalk,
{
Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE))
}

pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> {
Expand All @@ -149,31 +108,11 @@ pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> {
}

impl TraitRef {
pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
&self.substitution.at(interner, 0).assert_ty_ref(interner)
}

pub fn hir_trait_id(&self) -> TraitId {
from_chalk_trait_id(self.trait_id)
}
}

impl WhereClause {
pub fn is_implemented(&self) -> bool {
matches!(self, WhereClause::Implemented(_))
}

pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
match self {
WhereClause::Implemented(tr) => Some(tr.clone()),
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
Some(proj.trait_ref(db))
}
WhereClause::AliasEq(_) => None,
}
}
}

impl<T> Canonical<T> {
pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
let kinds = kinds.into_iter().map(|tk| {
Expand Down
8 changes: 5 additions & 3 deletions crates/hir_ty/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,9 @@ impl<'a> TyLoweringContext<'a> {
1,
QuantifiedWhereClauses::from_iter(
&Interner,
Some(Binders::wrap_empty(WhereClause::Implemented(trait_ref))),
Some(crate::wrap_empty_binders(WhereClause::Implemented(
trait_ref,
))),
),
),
};
Expand Down Expand Up @@ -720,7 +722,7 @@ impl<'a> TyLoweringContext<'a> {
let trait_ref = match bound {
TypeBound::Path(path) => {
bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b))
bindings.clone().map(WhereClause::Implemented).map(|b| crate::wrap_empty_binders(b))
}
TypeBound::Lifetime(_) => None,
TypeBound::Error => None,
Expand Down Expand Up @@ -767,7 +769,7 @@ impl<'a> TyLoweringContext<'a> {
let ty = self.lower_ty(type_ref);
let alias_eq =
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq)));
preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
}
for bound in &binding.bounds {
preds.extend(self.lower_type_bound(
Expand Down
14 changes: 6 additions & 8 deletions crates/hir_ty/src/traits/chalk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
let impl_bound = WhereClause::Implemented(TraitRef {
trait_id: to_chalk_trait_id(future_trait),
// Self type as the first parameter.
substitution: Substitution::single(
substitution: Substitution::from1(
&Interner,
TyKind::BoundVar(BoundVar {
debruijn: DebruijnIndex::INNERMOST,
index: 0,
Expand All @@ -232,7 +233,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
alias: AliasTy::Projection(ProjectionTy {
associated_ty_id: to_assoc_type_id(future_output),
// Self type as the first parameter.
substitution: Substitution::single(
substitution: Substitution::from1(
&Interner,
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
.intern(&Interner),
),
Expand All @@ -244,8 +246,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
let bound = OpaqueTyDatumBound {
bounds: make_binders(
vec![
wrap_in_empty_binders(impl_bound).to_chalk(self.db),
wrap_in_empty_binders(proj_bound).to_chalk(self.db),
crate::wrap_empty_binders(impl_bound).to_chalk(self.db),
crate::wrap_empty_binders(proj_bound).to_chalk(self.db),
],
1,
),
Expand Down Expand Up @@ -721,7 +723,3 @@ impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
chalk_ir::ClosureId(id.as_intern_id())
}
}

fn wrap_in_empty_binders<T: crate::TypeWalk>(value: T) -> crate::Binders<T> {
crate::Binders::wrap_empty(value)
}
6 changes: 3 additions & 3 deletions crates/hir_ty/src/traits/chalk/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use base_db::salsa::InternKey;
use hir_def::{GenericDefId, TypeAliasId};

use crate::{
db::HirDatabase, primitive::UintTy, AliasTy, CallableDefId, Canonical, DomainGoal, FnPointer,
GenericArg, InEnvironment, OpaqueTy, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution,
TraitRef, Ty, TypeWalk, WhereClause,
chalk_ext::ProjectionTyExt, db::HirDatabase, primitive::UintTy, AliasTy, CallableDefId,
Canonical, DomainGoal, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy,
QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
};

use super::interner::*;
Expand Down
31 changes: 30 additions & 1 deletion crates/hir_ty/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::sync::Arc;

use chalk_ir::{
cast::{CastTo, Caster},
cast::{Cast, CastTo, Caster},
BoundVar, Mutability, Scalar, TyVariableKind,
};
use hir_def::LifetimeParamId;
Expand Down Expand Up @@ -36,6 +36,12 @@ pub struct ProjectionTy {
pub substitution: Substitution,
}

impl ProjectionTy {
pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
&self.substitution.interned()[0].assert_ty_ref(interner)
}
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct DynTy {
/// The unknown self type.
Expand Down Expand Up @@ -279,6 +285,14 @@ impl Substitution {
self.0.iter()
}

pub fn from1(_interner: &Interner, ty: Ty) -> Substitution {
Substitution::intern({
let mut v = SmallVec::new();
v.push(ty.cast(&Interner));
v
})
}

pub fn from_iter(
interner: &Interner,
elements: impl IntoIterator<Item = impl CastTo<GenericArg>>,
Expand Down Expand Up @@ -353,6 +367,15 @@ impl<T: Clone> Binders<&T> {
}
}

impl<T: TypeWalk> Binders<T> {
/// Substitutes all variables.
pub fn substitute(self, interner: &Interner, subst: &Substitution) -> T {
let (value, binders) = self.into_value_and_skipped_binders();
assert_eq!(subst.len(interner), binders.len(interner));
value.subst_bound_vars(subst)
}
}

impl<T: std::fmt::Debug> std::fmt::Debug for Binders<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let Binders { ref binders, ref value } = *self;
Expand All @@ -368,6 +391,12 @@ pub struct TraitRef {
pub substitution: Substitution,
}

impl TraitRef {
pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
&self.substitution.at(interner, 0).assert_ty_ref(interner)
}
}

/// Like `generics::WherePredicate`, but with resolved types: A condition on the
/// parameters of a generic item.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down

0 comments on commit 7ac1c8f

Please sign in to comment.