Add SubstsBuilder

+ further refactoring.
This commit is contained in:
Florian Diebold 2019-09-26 21:37:03 +02:00
parent 1002e47074
commit daaf46177e
11 changed files with 212 additions and 126 deletions

View file

@ -339,10 +339,14 @@ pub struct Struct {
} }
impl Struct { impl Struct {
pub fn module(self, db: &impl HirDatabase) -> Module { pub fn module(self, db: &impl DefDatabase) -> Module {
self.id.module(db) self.id.module(db)
} }
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
self.module(db).krate(db)
}
pub fn name(self, db: &impl DefDatabase) -> Option<Name> { pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
db.struct_data(self).name.clone() db.struct_data(self).name.clone()
} }
@ -423,10 +427,14 @@ pub struct Enum {
} }
impl Enum { impl Enum {
pub fn module(self, db: &impl HirDatabase) -> Module { pub fn module(self, db: &impl DefDatabase) -> Module {
self.id.module(db) self.id.module(db)
} }
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
self.module(db).krate(db)
}
pub fn name(self, db: &impl DefDatabase) -> Option<Name> { pub fn name(self, db: &impl DefDatabase) -> Option<Name> {
db.enum_data(self).name.clone() db.enum_data(self).name.clone()
} }
@ -514,7 +522,7 @@ impl Adt {
} }
} }
pub(crate) fn krate(self, db: &impl HirDatabase) -> Option<Crate> { pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
match self { match self {
Adt::Struct(s) => s.module(db), Adt::Struct(s) => s.module(db),
Adt::Union(s) => s.module(db), Adt::Union(s) => s.module(db),

View file

@ -9,7 +9,6 @@ test_utils::marks!(
glob_across_crates glob_across_crates
std_prelude std_prelude
match_ergonomics_ref match_ergonomics_ref
trait_resolution_on_fn_type
infer_while_let infer_while_let
macro_rules_from_other_crates_are_visible_with_macro_use macro_rules_from_other_crates_are_visible_with_macro_use
prelude_is_macro_use prelude_is_macro_use

View file

@ -14,11 +14,11 @@ pub(crate) mod display;
use std::ops::Deref; use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use std::{fmt, mem}; use std::{fmt, iter, mem};
use crate::{ use crate::{
db::HirDatabase, expr::ExprId, type_ref::Mutability, Adt, DefWithBody, GenericParams, Name, db::HirDatabase, expr::ExprId, type_ref::Mutability, Adt, Crate, DefWithBody, GenericParams,
Trait, TypeAlias, HasGenericParams, Name, Trait, TypeAlias,
}; };
use display::{HirDisplay, HirFormatter}; use display::{HirDisplay, HirFormatter};
@ -111,6 +111,81 @@ pub enum TypeCtor {
Closure { def: DefWithBody, expr: ExprId }, Closure { def: DefWithBody, expr: ExprId },
} }
impl TypeCtor {
pub fn num_ty_params(self, db: &impl HirDatabase) -> usize {
match self {
TypeCtor::Bool
| TypeCtor::Char
| TypeCtor::Int(_)
| TypeCtor::Float(_)
| TypeCtor::Str
| TypeCtor::Never => 0,
TypeCtor::Slice
| TypeCtor::Array
| TypeCtor::RawPtr(_)
| TypeCtor::Ref(_)
| TypeCtor::Closure { .. } // 1 param representing the signature of the closure
=> 1,
TypeCtor::Adt(adt) => {
let generic_params = adt.generic_params(db);
generic_params.count_params_including_parent()
}
TypeCtor::FnDef(callable) => {
let generic_params = callable.generic_params(db);
generic_params.count_params_including_parent()
}
TypeCtor::AssociatedType(type_alias) => {
let generic_params = type_alias.generic_params(db);
generic_params.count_params_including_parent()
}
TypeCtor::FnPtr { num_args } => num_args as usize + 1,
TypeCtor::Tuple { cardinality } => cardinality as usize,
}
}
pub fn krate(self, db: &impl HirDatabase) -> Option<Crate> {
match self {
TypeCtor::Bool
| TypeCtor::Char
| TypeCtor::Int(_)
| TypeCtor::Float(_)
| TypeCtor::Str
| TypeCtor::Never
| TypeCtor::Slice
| TypeCtor::Array
| TypeCtor::RawPtr(_)
| TypeCtor::Ref(_)
| TypeCtor::FnPtr { .. }
| TypeCtor::Tuple { .. } => None,
TypeCtor::Closure { def, .. } => def.krate(db),
TypeCtor::Adt(adt) => adt.krate(db),
TypeCtor::FnDef(callable) => callable.krate(db),
TypeCtor::AssociatedType(type_alias) => type_alias.krate(db),
}
}
pub fn as_generic_def(self) -> Option<crate::generics::GenericDef> {
match self {
TypeCtor::Bool
| TypeCtor::Char
| TypeCtor::Int(_)
| TypeCtor::Float(_)
| TypeCtor::Str
| TypeCtor::Never
| TypeCtor::Slice
| TypeCtor::Array
| TypeCtor::RawPtr(_)
| TypeCtor::Ref(_)
| TypeCtor::FnPtr { .. }
| TypeCtor::Tuple { .. }
| TypeCtor::Closure { .. } => None,
TypeCtor::Adt(adt) => Some(adt.into()),
TypeCtor::FnDef(callable) => Some(callable.into()),
TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
}
}
}
/// A nominal type with (maybe 0) type parameters. This might be a primitive /// A nominal type with (maybe 0) type parameters. This might be a primitive
/// type like `bool`, a struct, tuple, function pointer, reference or /// type like `bool`, a struct, tuple, function pointer, reference or
/// several other things. /// several other things.
@ -271,11 +346,65 @@ impl Substs {
.into(), .into(),
) )
} }
pub fn build_for_def(
db: &impl HirDatabase,
def: impl crate::HasGenericParams,
) -> SubstsBuilder {
let params = def.generic_params(db);
let param_count = params.count_params_including_parent();
Substs::builder(param_count)
} }
impl From<Vec<Ty>> for Substs { pub fn build_for_generics(generic_params: &GenericParams) -> SubstsBuilder {
fn from(v: Vec<Ty>) -> Self { Substs::builder(generic_params.count_params_including_parent())
Substs(v.into()) }
pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
Substs::builder(type_ctor.num_ty_params(db))
}
fn builder(param_count: usize) -> SubstsBuilder {
SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
}
}
#[derive(Debug, Clone)]
pub struct SubstsBuilder {
vec: Vec<Ty>,
param_count: usize,
}
impl SubstsBuilder {
pub fn build(self) -> Substs {
assert_eq!(self.vec.len(), self.param_count);
Substs(self.vec.into())
}
pub fn push(mut self, ty: Ty) -> Self {
self.vec.push(ty);
self
}
fn remaining(&self) -> usize {
self.param_count - self.vec.len()
}
pub fn fill_with_bound_vars(mut self, starting_from: u32) -> Self {
self.vec.extend((starting_from..starting_from + self.remaining() as u32).map(Ty::Bound));
self
}
pub fn fill_with_unknown(mut self) -> Self {
self.vec.extend(iter::repeat(Ty::Unknown).take(self.remaining()));
self
}
pub fn use_parent_substs(mut self, parent_substs: &Substs) -> Self {
assert!(self.vec.is_empty());
assert!(parent_substs.len() <= self.param_count);
self.vec.extend(parent_substs.iter().cloned());
self
} }
} }

View file

@ -7,7 +7,7 @@ use std::iter::successors;
use log::{info, warn}; use log::{info, warn};
use super::{traits::Solution, Canonical, Ty, TypeWalk}; use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk};
use crate::{db::HirDatabase, name, HasGenericParams, Resolver}; use crate::{db::HirDatabase, name, HasGenericParams, Resolver};
const AUTODEREF_RECURSION_LIMIT: usize = 10; const AUTODEREF_RECURSION_LIMIT: usize = 10;
@ -44,7 +44,8 @@ fn deref_by_trait(
}; };
let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?;
if target.generic_params(db).count_params_including_parent() != 1 { let generic_params = target.generic_params(db);
if generic_params.count_params_including_parent() != 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;
@ -54,12 +55,13 @@ fn deref_by_trait(
let env = super::lower::trait_env(db, resolver); let env = super::lower::trait_env(db, resolver);
let parameters = Substs::build_for_generics(&generic_params)
.push(ty.value.clone().shift_bound_vars(1))
.build();
let projection = super::traits::ProjectionPredicate { let projection = super::traits::ProjectionPredicate {
ty: Ty::Bound(0), ty: Ty::Bound(0),
projection_ty: super::ProjectionTy { projection_ty: super::ProjectionTy { associated_ty: target, parameters },
associated_ty: target,
parameters: vec![ty.value.clone().shift_bound_vars(1)].into(),
},
}; };
let obligation = super::Obligation::Projection(projection); let obligation = super::Obligation::Projection(projection);

View file

@ -688,14 +688,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
}; };
let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown));
let inner_tys: Substs = args let inner_tys = args
.iter() .iter()
.zip(expectations_iter) .zip(expectations_iter)
.map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm)) .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm))
.collect::<Vec<_>>() .collect();
.into();
Ty::apply(TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, inner_tys) Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys))
} }
Pat::Ref { pat, mutability } => { Pat::Ref { pat, mutability } => {
let expectation = match expected.as_reference() { let expectation = match expected.as_reference() {
@ -1229,7 +1228,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
ty: pat_ty.clone(), ty: pat_ty.clone(),
projection_ty: ProjectionTy { projection_ty: ProjectionTy {
associated_ty: into_iter_item_alias, associated_ty: into_iter_item_alias,
parameters: vec![iterable_ty].into(), parameters: Substs::single(iterable_ty),
}, },
}; };
self.obligations.push(Obligation::Projection(projection)); self.obligations.push(Obligation::Projection(projection));
@ -1262,7 +1261,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
sig_tys.push(ret_ty.clone()); sig_tys.push(ret_ty.clone());
let sig_ty = Ty::apply( let sig_ty = Ty::apply(
TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 },
sig_tys.into(), Substs(sig_tys.into()),
); );
let closure_ty = Ty::apply_one( let closure_ty = Ty::apply_one(
TypeCtor::Closure { def: self.body.owner(), expr: tgt_expr }, TypeCtor::Closure { def: self.body.owner(), expr: tgt_expr },
@ -1400,7 +1399,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
ty: ty.clone(), ty: ty.clone(),
projection_ty: ProjectionTy { projection_ty: ProjectionTy {
associated_ty: future_future_output_alias, associated_ty: future_future_output_alias,
parameters: vec![inner_ty].into(), parameters: Substs::single(inner_ty),
}, },
}; };
self.obligations.push(Obligation::Projection(projection)); self.obligations.push(Obligation::Projection(projection));
@ -1419,7 +1418,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
ty: ty.clone(), ty: ty.clone(),
projection_ty: ProjectionTy { projection_ty: ProjectionTy {
associated_ty: ops_try_ok_alias, associated_ty: ops_try_ok_alias,
parameters: vec![inner_ty].into(), parameters: Substs::single(inner_ty),
}, },
}; };
self.obligations.push(Obligation::Projection(projection)); self.obligations.push(Obligation::Projection(projection));

View file

@ -158,13 +158,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
AssocItem::Const(c) => ValueNs::Const(c), AssocItem::Const(c) => ValueNs::Const(c),
AssocItem::TypeAlias(_) => unreachable!(), AssocItem::TypeAlias(_) => unreachable!(),
}; };
let generics = item.generic_params(self.db); let substs = Substs::build_for_def(self.db, item)
let mut substs = Vec::with_capacity(generics.count_params_including_parent()); .use_parent_substs(&trait_ref.substs)
substs.extend(trait_ref.substs.iter().cloned()); .fill_with_unknown()
substs.extend(std::iter::repeat(Ty::Unknown).take(generics.params.len())); .build();
self.write_assoc_resolution(id, item); self.write_assoc_resolution(id, item);
Some((def, Some(substs.into()))) Some((def, Some(substs)))
} }
fn resolve_ty_assoc_item( fn resolve_ty_assoc_item(

View file

@ -3,7 +3,8 @@
use super::{InferenceContext, Obligation}; use super::{InferenceContext, Obligation};
use crate::db::HirDatabase; use crate::db::HirDatabase;
use crate::ty::{ use crate::ty::{
Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, TraitRef, Ty, TypeWalk, Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty,
TypeWalk,
}; };
impl<'a, D: HirDatabase> InferenceContext<'a, D> { impl<'a, D: HirDatabase> InferenceContext<'a, D> {
@ -74,12 +75,9 @@ where
} }
fn do_canonicalize_trait_ref(&mut self, trait_ref: TraitRef) -> TraitRef { fn do_canonicalize_trait_ref(&mut self, trait_ref: TraitRef) -> TraitRef {
let substs = trait_ref let substs =
.substs trait_ref.substs.iter().map(|ty| self.do_canonicalize_ty(ty.clone())).collect();
.iter() TraitRef { trait_: trait_ref.trait_, substs: Substs(substs) }
.map(|ty| self.do_canonicalize_ty(ty.clone()))
.collect::<Vec<_>>();
TraitRef { trait_: trait_ref.trait_, substs: substs.into() }
} }
fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
@ -90,12 +88,9 @@ where
} }
fn do_canonicalize_projection_ty(&mut self, projection_ty: ProjectionTy) -> ProjectionTy { fn do_canonicalize_projection_ty(&mut self, projection_ty: ProjectionTy) -> ProjectionTy {
let params = projection_ty let params =
.parameters projection_ty.parameters.iter().map(|ty| self.do_canonicalize_ty(ty.clone())).collect();
.iter() ProjectionTy { associated_ty: projection_ty.associated_ty, parameters: Substs(params) }
.map(|ty| self.do_canonicalize_ty(ty.clone()))
.collect::<Vec<_>>();
ProjectionTy { associated_ty: projection_ty.associated_ty, parameters: params.into() }
} }
fn do_canonicalize_projection_predicate( fn do_canonicalize_projection_predicate(
@ -153,8 +148,7 @@ impl<T> Canonicalized<T> {
solution: Canonical<Vec<Ty>>, solution: Canonical<Vec<Ty>>,
) { ) {
// the solution may contain new variables, which we need to convert to new inference vars // the solution may contain new variables, which we need to convert to new inference vars
let new_vars = let new_vars = Substs((0..solution.num_vars).map(|_| ctx.new_type_var()).collect());
(0..solution.num_vars).map(|_| ctx.new_type_var()).collect::<Vec<_>>().into();
for (i, ty) in solution.value.into_iter().enumerate() { for (i, ty) in solution.value.into_iter().enumerate() {
let var = self.free_vars[i]; let var = self.free_vars[i];
ctx.unify(&Ty::Infer(var), &ty.subst_bound_vars(&new_vars)); ctx.unify(&Ty::Infer(var), &ty.subst_bound_vars(&new_vars));

View file

@ -239,14 +239,10 @@ impl Ty {
let traits = traits_from_env.flat_map(|t| t.all_super_traits(db)); let traits = traits_from_env.flat_map(|t| t.all_super_traits(db));
for t in traits { for t in traits {
if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) { if let Some(associated_ty) = t.associated_type_by_name(db, &segment.name) {
let generics = t.generic_params(db); let substs =
let mut substs = Vec::new(); Substs::build_for_def(db, t).push(self_ty.clone()).fill_with_unknown().build();
substs.push(self_ty.clone());
substs.extend(
iter::repeat(Ty::Unknown).take(generics.count_params_including_parent() - 1),
);
// FIXME handle type parameters on the segment // FIXME handle type parameters on the segment
return Ty::Projection(ProjectionTy { associated_ty, parameters: substs.into() }); return Ty::Projection(ProjectionTy { associated_ty, parameters: substs });
} }
} }
Ty::Unknown Ty::Unknown
@ -766,6 +762,16 @@ pub enum CallableDef {
} }
impl_froms!(CallableDef: Function, Struct, EnumVariant); impl_froms!(CallableDef: Function, Struct, EnumVariant);
impl CallableDef {
pub fn krate(self, db: &impl HirDatabase) -> Option<crate::Crate> {
match self {
CallableDef::Function(f) => f.krate(db),
CallableDef::Struct(s) => s.krate(db),
CallableDef::EnumVariant(e) => e.parent_enum(db).krate(db),
}
}
}
impl From<CallableDef> for GenericDef { impl From<CallableDef> for GenericDef {
fn from(def: CallableDef) -> GenericDef { fn from(def: CallableDef) -> GenericDef {
match def { match def {

View file

@ -10,7 +10,6 @@ use rustc_hash::FxHashMap;
use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef};
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
generics::HasGenericParams,
impl_block::{ImplBlock, ImplId}, impl_block::{ImplBlock, ImplId},
nameres::CrateModuleId, nameres::CrateModuleId,
resolve::Resolver, resolve::Resolver,
@ -331,20 +330,13 @@ fn generic_implements_goal(
trait_: Trait, trait_: Trait,
self_ty: Canonical<Ty>, self_ty: Canonical<Ty>,
) -> Canonical<InEnvironment<super::Obligation>> { ) -> Canonical<InEnvironment<super::Obligation>> {
let mut substs = Vec::new();
let generics = trait_.generic_params(db);
let num_vars = self_ty.num_vars; let num_vars = self_ty.num_vars;
substs.push(self_ty.value); let substs = super::Substs::build_for_def(db, trait_)
substs.extend( .push(self_ty.value)
generics .fill_with_bound_vars(num_vars as u32)
.params_including_parent() .build();
.into_iter()
.skip(1)
.enumerate()
.map(|(i, _p)| Ty::Bound((i + num_vars) as u32)),
);
let num_vars = substs.len() - 1 + self_ty.num_vars; let num_vars = substs.len() - 1 + self_ty.num_vars;
let trait_ref = TraitRef { trait_, substs: substs.into() }; let trait_ref = TraitRef { trait_, substs };
let obligation = super::Obligation::Trait(trait_ref); let obligation = super::Obligation::Trait(trait_ref);
Canonical { num_vars, value: InEnvironment::new(env, obligation) } Canonical { num_vars, value: InEnvironment::new(env, obligation) }
} }

View file

@ -3321,7 +3321,6 @@ fn test() { S2.into()<|>; }
#[test] #[test]
fn method_resolution_encountering_fn_type() { fn method_resolution_encountering_fn_type() {
covers!(trait_resolution_on_fn_type);
type_at( type_at(
r#" r#"
//- /main.rs //- /main.rs

View file

@ -10,17 +10,13 @@ use chalk_ir::{
use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum};
use ra_db::salsa::{InternId, InternKey}; use ra_db::salsa::{InternId, InternKey};
use test_utils::tested_by;
use super::{Canonical, ChalkContext, Impl, Obligation}; use super::{Canonical, ChalkContext, Impl, Obligation};
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
generics::GenericDef, generics::GenericDef,
ty::display::HirDisplay, ty::display::HirDisplay,
ty::{ ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
ApplicationTy, CallableDef, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
TypeWalk,
},
AssocItem, Crate, HasGenericParams, ImplBlock, Trait, TypeAlias, AssocItem, Crate, HasGenericParams, ImplBlock, Trait, TypeAlias,
}; };
@ -124,14 +120,15 @@ impl ToChalk for Substs {
} }
fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter>) -> Substs { fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter>) -> Substs {
parameters let tys = parameters
.into_iter() .into_iter()
.map(|p| match p { .map(|p| match p {
chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty), chalk_ir::Parameter(chalk_ir::ParameterKind::Ty(ty)) => from_chalk(db, ty),
chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(), chalk_ir::Parameter(chalk_ir::ParameterKind::Lifetime(_)) => unimplemented!(),
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into() .into();
Substs(tys)
} }
} }
@ -539,60 +536,18 @@ pub(crate) fn struct_datum_query(
struct_id: chalk_ir::StructId, struct_id: chalk_ir::StructId,
) -> Arc<StructDatum> { ) -> Arc<StructDatum> {
debug!("struct_datum {:?}", struct_id); debug!("struct_datum {:?}", struct_id);
let type_ctor = from_chalk(db, struct_id); let type_ctor: TypeCtor = from_chalk(db, struct_id);
debug!("struct {:?} = {:?}", struct_id, type_ctor); debug!("struct {:?} = {:?}", struct_id, type_ctor);
// FIXME might be nicer if we can create a fake GenericParams for the TypeCtor let num_params = type_ctor.num_ty_params(db);
// FIXME extract this to a method on Ty let upstream = type_ctor.krate(db) != Some(krate);
let (num_params, where_clauses, upstream) = match type_ctor { let where_clauses = type_ctor
TypeCtor::Bool .as_generic_def()
| TypeCtor::Char .map(|generic_def| {
| TypeCtor::Int(_)
| TypeCtor::Float(_)
| TypeCtor::Never
| TypeCtor::Str => (0, vec![], true),
TypeCtor::Slice | TypeCtor::Array | TypeCtor::RawPtr(_) | TypeCtor::Ref(_) => {
(1, vec![], true)
}
TypeCtor::FnPtr { num_args } => (num_args as usize + 1, vec![], true),
TypeCtor::Tuple { cardinality } => (cardinality as usize, vec![], true),
TypeCtor::FnDef(callable) => {
tested_by!(trait_resolution_on_fn_type);
let upstream = match callable {
CallableDef::Function(f) => f.module(db).krate(db),
CallableDef::Struct(s) => s.module(db).krate(db),
CallableDef::EnumVariant(v) => v.parent_enum(db).module(db).krate(db),
} != Some(krate);
let generic_def: GenericDef = callable.into();
let generic_params = generic_def.generic_params(db); let generic_params = generic_def.generic_params(db);
let bound_vars = Substs::bound_vars(&generic_params); let bound_vars = Substs::bound_vars(&generic_params);
let where_clauses = convert_where_clauses(db, generic_def, &bound_vars); convert_where_clauses(db, generic_def, &bound_vars)
(generic_params.count_params_including_parent(), where_clauses, upstream) })
} .unwrap_or_else(Vec::new);
TypeCtor::Adt(adt) => {
let generic_params = adt.generic_params(db);
let bound_vars = Substs::bound_vars(&generic_params);
let where_clauses = convert_where_clauses(db, adt.into(), &bound_vars);
(
generic_params.count_params_including_parent(),
where_clauses,
adt.krate(db) != Some(krate),
)
}
TypeCtor::AssociatedType(type_alias) => {
let generic_params = type_alias.generic_params(db);
let bound_vars = Substs::bound_vars(&generic_params);
let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
(
generic_params.count_params_including_parent(),
where_clauses,
type_alias.krate(db) != Some(krate),
)
}
TypeCtor::Closure { def, .. } => {
let upstream = def.krate(db) != Some(krate);
(1, vec![], upstream)
}
};
let flags = chalk_rust_ir::StructFlags { let flags = chalk_rust_ir::StructFlags {
upstream, upstream,
// FIXME set fundamental flag correctly // FIXME set fundamental flag correctly
@ -729,17 +684,20 @@ fn closure_fn_trait_impl_datum(
let arg_ty = Ty::apply( let arg_ty = Ty::apply(
TypeCtor::Tuple { cardinality: num_args }, TypeCtor::Tuple { cardinality: num_args },
(0..num_args).map(|i| Ty::Bound(i.into())).collect::<Vec<_>>().into(), Substs::builder(num_args as usize).fill_with_bound_vars(0).build(),
); );
let output_ty = Ty::Bound(num_args.into()); let output_ty = Ty::Bound(num_args.into());
let sig_ty = Ty::apply( let sig_ty = Ty::apply(
TypeCtor::FnPtr { num_args }, TypeCtor::FnPtr { num_args },
(0..num_args + 1).map(|i| Ty::Bound(i.into())).collect::<Vec<_>>().into(), Substs::builder(num_args as usize + 1).fill_with_bound_vars(0).build(),
); );
let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty); let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
let trait_ref = TraitRef { trait_, substs: vec![self_ty, arg_ty].into() }; let trait_ref = TraitRef {
trait_,
substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(),
};
let output_ty_id = fn_once_trait.associated_type_by_name(db, &crate::name::OUTPUT_TYPE)?; let output_ty_id = fn_once_trait.associated_type_by_name(db, &crate::name::OUTPUT_TYPE)?;