Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower.rs')
-rw-r--r--crates/hir-ty/src/lower.rs116
1 files changed, 61 insertions, 55 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index e371e42761..386a03d93f 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -58,7 +58,7 @@ use crate::{
InTypeConstIdMetadata,
},
AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
- FnPointer, FnSig, FnSubst, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
+ FnAbi, FnPointer, FnSig, FnSubst, ImplTraitId, Interner, ParamKind, PolyFnSig, ProjectionTy,
QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
};
@@ -279,14 +279,14 @@ impl<'a> TyLoweringContext<'a> {
.intern(Interner)
}
TypeRef::Placeholder => TyKind::Error.intern(Interner),
- &TypeRef::Fn(ref params, variadic, is_unsafe) => {
+ &TypeRef::Fn(ref params, variadic, is_unsafe, ref abi) => {
let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
});
TyKind::Function(FnPointer {
num_binders: 0, // FIXME lower `for<'a> fn()` correctly
sig: FnSig {
- abi: (),
+ abi: abi.as_deref().map_or(FnAbi::Rust, FnAbi::from_str),
safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe },
variadic,
},
@@ -762,7 +762,7 @@ impl<'a> TyLoweringContext<'a> {
Some(segment) if segment.args_and_bindings.is_some() => Some(segment),
_ => last,
};
- (segment, Some(var.parent.into()))
+ (segment, Some(var.lookup(self.db.upcast()).parent.into()))
}
};
if let Some(segment) = segment {
@@ -1192,11 +1192,7 @@ impl<'a> TyLoweringContext<'a> {
return None;
}
- if bounds.first().and_then(|b| b.trait_id()).is_none() {
- // When there's no trait bound, that's an error. This happens when the trait refs
- // are unresolved.
- return None;
- }
+ bounds.first().and_then(|b| b.trait_id())?;
// As multiple occurrences of the same auto traits *are* permitted, we deduplicate the
// bounds. We shouldn't have repeated elements besides auto traits at this point.
@@ -1241,7 +1237,7 @@ impl<'a> TyLoweringContext<'a> {
});
crate::wrap_empty_binders(clause)
});
- predicates.extend(sized_clause.into_iter());
+ predicates.extend(sized_clause);
predicates.shrink_to_fit();
}
predicates
@@ -1339,7 +1335,7 @@ fn named_associated_type_shorthand_candidates<R>(
),
_ => None,
});
- if let Some(_) = res {
+ if res.is_some() {
return res;
}
// Handle `Self::Type` referring to own associated type in trait definitions
@@ -1375,11 +1371,13 @@ pub(crate) fn field_types_query(
let (resolver, def): (_, GenericDefId) = match variant_id {
VariantId::StructId(it) => (it.resolver(db.upcast()), it.into()),
VariantId::UnionId(it) => (it.resolver(db.upcast()), it.into()),
- VariantId::EnumVariantId(it) => (it.parent.resolver(db.upcast()), it.parent.into()),
+ VariantId::EnumVariantId(it) => {
+ (it.resolver(db.upcast()), it.lookup(db.upcast()).parent.into())
+ }
};
let generics = generics(db.upcast(), def);
let mut res = ArenaMap::default();
- let ctx = TyLoweringContext::new(db, &resolver, GenericDefId::from(variant_id.adt_id()).into())
+ let ctx = TyLoweringContext::new(db, &resolver, def.into())
.with_type_param_mode(ParamLoweringMode::Variable);
for (field_id, field_data) in var_data.fields().iter() {
res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
@@ -1677,6 +1675,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
ret,
data.is_varargs(),
if data.has_unsafe_kw() { Safety::Unsafe } else { Safety::Safe },
+ data.abi.as_deref().map_or(FnAbi::Rust, FnAbi::from_str),
);
make_binders(db, &generics, sig)
}
@@ -1721,50 +1720,65 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
.with_type_param_mode(ParamLoweringMode::Variable);
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
- Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
+ Binders::new(
+ binders,
+ CallableSig::from_params_and_return(params, ret, false, Safety::Safe, FnAbi::RustCall),
+ )
}
/// Build the type of a tuple struct constructor.
-fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<Ty> {
+fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Option<Binders<Ty>> {
let struct_data = db.struct_data(def);
- if let StructKind::Unit = struct_data.variant_data.kind() {
- return type_for_adt(db, def.into());
+ match struct_data.variant_data.kind() {
+ StructKind::Record => None,
+ StructKind::Unit => Some(type_for_adt(db, def.into())),
+ StructKind::Tuple => {
+ let generics = generics(db.upcast(), AdtId::from(def).into());
+ let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
+ Some(make_binders(
+ db,
+ &generics,
+ TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
+ ))
+ }
}
- let generics = generics(db.upcast(), AdtId::from(def).into());
- let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
- make_binders(
- db,
- &generics,
- TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(Interner),
- )
}
fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
- let enum_data = db.enum_data(def.parent);
- let var_data = &enum_data.variants[def.local_id];
+ let var_data = db.enum_variant_data(def);
let fields = var_data.variant_data.fields();
- let resolver = def.parent.resolver(db.upcast());
+ let resolver = def.resolver(db.upcast());
let ctx = TyLoweringContext::new(db, &resolver, DefWithBodyId::VariantId(def).into())
.with_type_param_mode(ParamLoweringMode::Variable);
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
- let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
- Binders::new(binders, CallableSig::from_params_and_return(params, ret, false, Safety::Safe))
+ let (ret, binders) =
+ type_for_adt(db, def.lookup(db.upcast()).parent.into()).into_value_and_skipped_binders();
+ Binders::new(
+ binders,
+ CallableSig::from_params_and_return(params, ret, false, Safety::Safe, FnAbi::RustCall),
+ )
}
/// Build the type of a tuple enum variant constructor.
-fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> Binders<Ty> {
- let enum_data = db.enum_data(def.parent);
- let var_data = &enum_data.variants[def.local_id].variant_data;
- if let StructKind::Unit = var_data.kind() {
- return type_for_adt(db, def.parent.into());
+fn type_for_enum_variant_constructor(
+ db: &dyn HirDatabase,
+ def: EnumVariantId,
+) -> Option<Binders<Ty>> {
+ let e = def.lookup(db.upcast()).parent;
+ match db.enum_variant_data(def).variant_data.kind() {
+ StructKind::Record => None,
+ StructKind::Unit => Some(type_for_adt(db, e.into())),
+ StructKind::Tuple => {
+ let generics = generics(db.upcast(), e.into());
+ let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
+ Some(make_binders(
+ db,
+ &generics,
+ TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs)
+ .intern(Interner),
+ ))
+ }
}
- let generics = generics(db.upcast(), def.parent.into());
- let substs = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
- make_binders(
- db,
- &generics,
- TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(Interner),
- )
}
fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
@@ -1812,7 +1826,7 @@ impl CallableDefId {
match self {
CallableDefId::FunctionId(f) => f.lookup(db).module(db),
CallableDefId::StructId(s) => s.lookup(db).container,
- CallableDefId::EnumVariantId(e) => e.parent.lookup(db).container,
+ CallableDefId::EnumVariantId(e) => e.module(db),
}
.krate()
}
@@ -1881,24 +1895,20 @@ pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &Cycle, def: &TyDefId) ->
make_binders(db, &generics, TyKind::Error.intern(Interner))
}
-pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
+pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Option<Binders<Ty>> {
match def {
- ValueTyDefId::FunctionId(it) => type_for_fn(db, it),
+ ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)),
ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
- ValueTyDefId::UnionId(it) => type_for_adt(db, it.into()),
+ ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())),
ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
- ValueTyDefId::ConstId(it) => type_for_const(db, it),
- ValueTyDefId::StaticId(it) => type_for_static(db, it),
+ ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)),
+ ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)),
}
}
pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binders<Ty> {
- let impl_loc = impl_id.lookup(db.upcast());
let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db.upcast());
- let _cx = stdx::panic_context::enter(format!(
- "impl_self_ty_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
- ));
let generics = generics(db.upcast(), impl_id.into());
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
.with_type_param_mode(ParamLoweringMode::Variable);
@@ -1930,12 +1940,8 @@ pub(crate) fn impl_self_ty_recover(
}
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
- let impl_loc = impl_id.lookup(db.upcast());
let impl_data = db.impl_data(impl_id);
let resolver = impl_id.resolver(db.upcast());
- let _cx = stdx::panic_context::enter(format!(
- "impl_trait_query({impl_id:?} -> {impl_loc:?} -> {impl_data:?})"
- ));
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
.with_type_param_mode(ParamLoweringMode::Variable);
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();