More TyBuilder use

This commit is contained in:
Florian Diebold 2021-04-03 21:56:18 +02:00
parent cd227f581e
commit 66fec39aa0

View file

@ -13,11 +13,9 @@ use log::{info, warn};
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
to_assoc_type_id, to_chalk_trait_id,
traits::{InEnvironment, Solution}, traits::{InEnvironment, Solution},
utils::generics, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, Ty,
AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, TyBuilder, TyKind,
ProjectionTy, Substitution, TraitRef, Ty, TyKind,
}; };
const AUTODEREF_RECURSION_LIMIT: usize = 10; const AUTODEREF_RECURSION_LIMIT: usize = 10;
@ -57,21 +55,20 @@ fn deref_by_trait(
}; };
let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?; let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
let generic_params = generics(db.upcast(), target.into()); let projection = {
if generic_params.len() != 1 { let b = TyBuilder::assoc_type_projection(db, target);
if b.remaining() != 1 {
// the Target type + Deref trait should only have one generic parameter, // the Target type + Deref trait should only have one generic parameter,
// namely Deref's Self type // namely Deref's Self type
return None; return None;
} }
b.push(ty.goal.value.clone()).build()
};
// FIXME make the Canonical / bound var handling nicer // FIXME make the Canonical / bound var handling nicer
let parameters =
Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
// Check that the type implements Deref at all // Check that the type implements Deref at all
let trait_ref = let trait_ref = projection.trait_ref(db);
TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
let implements_goal = Canonical { let implements_goal = Canonical {
binders: ty.goal.binders.clone(), binders: ty.goal.binders.clone(),
value: InEnvironment { value: InEnvironment {
@ -84,11 +81,8 @@ fn deref_by_trait(
} }
// Now do the assoc type projection // Now do the assoc type projection
let projection = AliasEq { let alias_eq = AliasEq {
alias: AliasTy::Projection(ProjectionTy { alias: AliasTy::Projection(projection),
associated_ty_id: to_assoc_type_id(target),
substitution: parameters,
}),
ty: TyKind::BoundVar(BoundVar::new( ty: TyKind::BoundVar(BoundVar::new(
DebruijnIndex::INNERMOST, DebruijnIndex::INNERMOST,
ty.goal.binders.len(&Interner), ty.goal.binders.len(&Interner),
@ -96,9 +90,7 @@ fn deref_by_trait(
.intern(&Interner), .intern(&Interner),
}; };
let obligation = projection.cast(&Interner); let in_env = InEnvironment { goal: alias_eq.cast(&Interner), environment: ty.environment };
let in_env = InEnvironment { goal: obligation, environment: ty.environment };
let canonical = Canonical { let canonical = Canonical {
value: in_env, value: in_env,