Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs159
1 files changed, 110 insertions, 49 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 55da27781d..2bb2f80ecc 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -36,6 +36,7 @@ pub mod term_search;
mod display;
use std::{
+ fmt,
mem::discriminant,
ops::{ControlFlow, Not},
};
@@ -74,7 +75,7 @@ use hir_ty::{
TraitEnvironment, TyDefId, TyLoweringDiagnostic, ValueTyDefId, all_super_traits, autoderef,
check_orphan_rules,
consteval::try_const_usize,
- db::InternedClosureId,
+ db::{InternedClosureId, InternedCoroutineId},
diagnostics::BodyValidationDiagnostic,
direct_super_traits, known_const_to_ast,
layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
@@ -91,7 +92,7 @@ use itertools::Itertools;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTyKind, TypeSuperVisitable, TypeVisitable, TypeVisitor,
- inherent::{AdtDef, IntoKind, SliceLike, Term as _, Ty as _},
+ inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _},
};
use smallvec::SmallVec;
use span::{AstIdNode, Edition, FileId};
@@ -160,7 +161,7 @@ pub use {
// FIXME: Properly encapsulate mir
hir_ty::mir,
hir_ty::{
- CastError, FnAbi, PointerCast, Variance, attach_db, attach_db_allow_change,
+ CastError, FnAbi, PointerCast, attach_db, attach_db_allow_change,
consteval::ConstEvalError,
diagnostics::UnsafetyReason,
display::{ClosureStyle, DisplayTarget, HirDisplay, HirDisplayError, HirWrite},
@@ -170,6 +171,7 @@ pub use {
method_resolution::TyFingerprint,
mir::{MirEvalError, MirLowerError},
next_solver::abi::Safety,
+ next_solver::clear_tls_solver_cache,
},
intern::{Symbol, sym},
};
@@ -1270,7 +1272,7 @@ impl<'db> InstantiatedField<'db> {
let interner = DbInterner::new_with(db, Some(krate.base()), None);
let var_id = self.inner.parent.into();
- let field = db.field_types_ns(var_id)[self.inner.id];
+ let field = db.field_types(var_id)[self.inner.id];
let ty = field.instantiate(interner, self.args);
TypeNs::new(db, var_id, ty)
}
@@ -1349,7 +1351,7 @@ impl Field {
/// context of the field definition.
pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
let var_id = self.parent.into();
- let ty = db.field_types_ns(var_id)[self.id].skip_binder();
+ let ty = db.field_types(var_id)[self.id].skip_binder();
TypeNs::new(db, var_id, ty)
}
@@ -1367,7 +1369,7 @@ impl Field {
};
let interner = DbInterner::new_with(db, None, None);
let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty));
- let ty = db.field_types_ns(var_id)[self.id].instantiate(interner, args);
+ let ty = db.field_types(var_id)[self.id].instantiate(interner, args);
Type::new(db, var_id, ty)
}
@@ -1802,7 +1804,7 @@ impl Adt {
let env = db.trait_environment(self.into());
let interner = DbInterner::new_with(db, Some(env.krate), env.block);
let adt_id = AdtId::from(self);
- let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, _, id, _| {
+ let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| {
GenericArg::error_from_id(interner, id)
});
db.layout_of_adt(adt_id, args, env)
@@ -4110,7 +4112,39 @@ impl GenericParam {
GenericParam::ConstParam(_) => return None,
GenericParam::LifetimeParam(it) => generics.lifetime_idx(it.id)?,
};
- db.variances_of(parent)?.get(index).copied()
+ db.variances_of(parent).get(index).map(Into::into)
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum Variance {
+ Bivariant,
+ Covariant,
+ Contravariant,
+ Invariant,
+}
+
+impl From<rustc_type_ir::Variance> for Variance {
+ #[inline]
+ fn from(value: rustc_type_ir::Variance) -> Self {
+ match value {
+ rustc_type_ir::Variance::Covariant => Variance::Covariant,
+ rustc_type_ir::Variance::Invariant => Variance::Invariant,
+ rustc_type_ir::Variance::Contravariant => Variance::Contravariant,
+ rustc_type_ir::Variance::Bivariant => Variance::Bivariant,
+ }
+ }
+}
+
+impl fmt::Display for Variance {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let description = match self {
+ Variance::Bivariant => "bivariant",
+ Variance::Covariant => "covariant",
+ Variance::Contravariant => "contravariant",
+ Variance::Invariant => "invariant",
+ };
+ f.pad(description)
}
}
@@ -4151,8 +4185,7 @@ impl TypeParam {
let resolver = self.id.parent().resolver(db);
let interner = DbInterner::new_with(db, None, None);
let index = hir_ty::param_idx(db, self.id.into()).unwrap();
- let name = self.name(db).symbol().clone();
- let ty = Ty::new_param(interner, self.id, index as u32, name);
+ let ty = Ty::new_param(interner, self.id, index as u32);
Type::new_with_resolver_inner(db, &resolver, ty)
}
@@ -4160,7 +4193,7 @@ impl TypeParam {
/// parameter, not additional bounds that might be added e.g. by a method if
/// the parameter comes from an impl!
pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> {
- db.generic_predicates_for_param_ns(self.id.parent(), self.id.into(), None)
+ db.generic_predicates_for_param(self.id.parent(), self.id.into(), None)
.iter()
.filter_map(|pred| match &pred.kind().skip_binder() {
ClauseKind::Trait(trait_ref) => Some(Trait::from(trait_ref.def_id().0)),
@@ -4250,7 +4283,7 @@ impl ConstParam {
fn generic_arg_from_param(db: &dyn HirDatabase, id: TypeOrConstParamId) -> Option<GenericArg<'_>> {
let local_idx = hir_ty::param_idx(db, id)?;
- let defaults = db.generic_defaults_ns(id.parent);
+ let defaults = db.generic_defaults(id.parent);
let ty = defaults.get(local_idx)?;
// FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s.
Some(ty.instantiate_identity())
@@ -4525,16 +4558,27 @@ impl<'db> TraitRef<'db> {
}
}
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+enum AnyClosureId {
+ ClosureId(InternedClosureId),
+ CoroutineClosureId(InternedCoroutineId),
+}
+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Closure<'db> {
- id: InternedClosureId,
+ id: AnyClosureId,
subst: GenericArgs<'db>,
}
impl<'db> Closure<'db> {
fn as_ty(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
let interner = DbInterner::new_with(db, None, None);
- Ty::new_closure(interner, self.id.into(), self.subst)
+ match self.id {
+ AnyClosureId::ClosureId(id) => Ty::new_closure(interner, id.into(), self.subst),
+ AnyClosureId::CoroutineClosureId(id) => {
+ Ty::new_coroutine_closure(interner, id.into(), self.subst)
+ }
+ }
}
pub fn display_with_id(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
@@ -4552,20 +4596,28 @@ impl<'db> Closure<'db> {
}
pub fn captured_items(&self, db: &'db dyn HirDatabase) -> Vec<ClosureCapture<'db>> {
- let owner = db.lookup_intern_closure(self.id).0;
+ let AnyClosureId::ClosureId(id) = self.id else {
+ // FIXME: Infer coroutine closures' captures.
+ return Vec::new();
+ };
+ let owner = db.lookup_intern_closure(id).0;
let infer = db.infer(owner);
- let info = infer.closure_info(self.id);
+ let info = infer.closure_info(id);
info.0
.iter()
.cloned()
- .map(|capture| ClosureCapture { owner, closure: self.id, capture })
+ .map(|capture| ClosureCapture { owner, closure: id, capture })
.collect()
}
pub fn capture_types(&self, db: &'db dyn HirDatabase) -> Vec<Type<'db>> {
- let owner = db.lookup_intern_closure(self.id).0;
+ let AnyClosureId::ClosureId(id) = self.id else {
+ // FIXME: Infer coroutine closures' captures.
+ return Vec::new();
+ };
+ let owner = db.lookup_intern_closure(id).0;
let infer = db.infer(owner);
- let (captures, _) = infer.closure_info(self.id);
+ let (captures, _) = infer.closure_info(id);
let env = db.trait_environment_for_body(owner);
captures
.iter()
@@ -4574,10 +4626,22 @@ impl<'db> Closure<'db> {
}
pub fn fn_trait(&self, db: &dyn HirDatabase) -> FnTrait {
- let owner = db.lookup_intern_closure(self.id).0;
- let infer = db.infer(owner);
- let info = infer.closure_info(self.id);
- info.1
+ match self.id {
+ AnyClosureId::ClosureId(id) => {
+ let owner = db.lookup_intern_closure(id).0;
+ let infer = db.infer(owner);
+ let info = infer.closure_info(id);
+ info.1
+ }
+ AnyClosureId::CoroutineClosureId(_id) => {
+ // FIXME: Infer kind for coroutine closures.
+ match self.subst.as_coroutine_closure().kind() {
+ rustc_type_ir::ClosureKind::Fn => FnTrait::AsyncFn,
+ rustc_type_ir::ClosureKind::FnMut => FnTrait::AsyncFnMut,
+ rustc_type_ir::ClosureKind::FnOnce => FnTrait::AsyncFnOnce,
+ }
+ }
+ }
}
}
@@ -4851,7 +4915,7 @@ impl<'db> Type<'db> {
if variant_data.fields().is_empty() {
vec![]
} else {
- let field_types = self.interner.db().field_types_ns(id);
+ let field_types = self.interner.db().field_types(id);
variant_data
.fields()
.iter()
@@ -5091,28 +5155,14 @@ impl<'db> Type<'db> {
let interner = DbInterner::new_with(db, None, None);
let callee = match self.ty.kind() {
TyKind::Closure(id, subst) => Callee::Closure(id.0, subst),
+ TyKind::CoroutineClosure(id, subst) => Callee::CoroutineClosure(id.0, subst),
TyKind::FnPtr(..) => Callee::FnPtr,
TyKind::FnDef(id, _) => Callee::Def(id.0),
- kind => {
- // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
- let (ty, kind) = if let TyKind::Ref(_, ty, _) = kind {
- (ty, ty.kind())
- } else {
- (self.ty, kind)
- };
- if let TyKind::Closure(closure, subst) = kind {
- let sig = subst
- .split_closure_args_untupled()
- .closure_sig_as_fn_ptr_ty
- .callable_sig(interner)?;
- return Some(Callable {
- ty: self.clone(),
- sig,
- callee: Callee::Closure(closure.0, subst),
- is_bound_method: false,
- });
- }
- let (fn_trait, sig) = hir_ty::callable_sig_from_fn_trait(ty, self.env.clone(), db)?;
+ // This will happen when it implements fn or fn mut, since we add an autoborrow adjustment
+ TyKind::Ref(_, inner_ty, _) => return self.derived(inner_ty).as_callable(db),
+ _ => {
+ let (fn_trait, sig) =
+ hir_ty::callable_sig_from_fn_trait(self.ty, self.env.clone(), db)?;
return Some(Callable {
ty: self.clone(),
sig,
@@ -5132,7 +5182,12 @@ impl<'db> Type<'db> {
pub fn as_closure(&self) -> Option<Closure<'db>> {
match self.ty.kind() {
- TyKind::Closure(id, subst) => Some(Closure { id: id.0, subst }),
+ TyKind::Closure(id, subst) => {
+ Some(Closure { id: AnyClosureId::ClosureId(id.0), subst })
+ }
+ TyKind::CoroutineClosure(id, subst) => {
+ Some(Closure { id: AnyClosureId::CoroutineClosureId(id.0), subst })
+ }
_ => None,
}
}
@@ -5184,7 +5239,7 @@ impl<'db> Type<'db> {
_ => return Vec::new(),
};
- db.field_types_ns(variant_id)
+ db.field_types(variant_id)
.iter()
.map(|(local_id, ty)| {
let def = Field { parent: variant_id.into(), id: local_id };
@@ -5791,6 +5846,7 @@ pub struct Callable<'db> {
enum Callee<'db> {
Def(CallableDefId),
Closure(InternedClosureId, GenericArgs<'db>),
+ CoroutineClosure(InternedCoroutineId, GenericArgs<'db>),
FnPtr,
FnImpl(FnTrait),
}
@@ -5812,7 +5868,12 @@ impl<'db> Callable<'db> {
Callee::Def(CallableDefId::EnumVariantId(it)) => {
CallableKind::TupleEnumVariant(it.into())
}
- Callee::Closure(id, ref subst) => CallableKind::Closure(Closure { id, subst: *subst }),
+ Callee::Closure(id, subst) => {
+ CallableKind::Closure(Closure { id: AnyClosureId::ClosureId(id), subst })
+ }
+ Callee::CoroutineClosure(id, subst) => {
+ CallableKind::Closure(Closure { id: AnyClosureId::CoroutineClosureId(id), subst })
+ }
Callee::FnPtr => CallableKind::FnPtr,
Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_),
}
@@ -6405,7 +6466,7 @@ fn generic_args_from_tys<'db>(
args: impl IntoIterator<Item = Ty<'db>>,
) -> GenericArgs<'db> {
let mut args = args.into_iter();
- GenericArgs::for_item(interner, def_id, |_, _, id, _| {
+ GenericArgs::for_item(interner, def_id, |_, id, _| {
if matches!(id, GenericParamId::TypeParamId(_))
&& let Some(arg) = args.next()
{
@@ -6418,7 +6479,7 @@ fn generic_args_from_tys<'db>(
fn has_non_default_type_params(db: &dyn HirDatabase, generic_def: GenericDefId) -> bool {
let params = db.generic_params(generic_def);
- let defaults = db.generic_defaults_ns(generic_def);
+ let defaults = db.generic_defaults(generic_def);
params
.iter_type_or_consts()
.filter(|(_, param)| matches!(param, TypeOrConstParamData::TypeParamData(_)))