Make Field::ty return TypeNs
diff --git a/crates/hir-ty/src/next_solver/mapping.rs b/crates/hir-ty/src/next_solver/mapping.rs
index b24b996..5dcb1e6 100644
--- a/crates/hir-ty/src/next_solver/mapping.rs
+++ b/crates/hir-ty/src/next_solver/mapping.rs
@@ -1266,7 +1266,7 @@
Substitution::from_iter(Interner, substs)
}
-pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>) -> crate::Ty {
+pub fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>) -> crate::Ty {
use crate::{Scalar, TyKind};
use chalk_ir::{FloatTy, IntTy, UintTy};
match ty.kind() {
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 833a9ef..2bf9bb8 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -24,7 +24,7 @@
Adt, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum,
ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam,
Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, TyBuilder,
- Type, TypeAlias, TypeOrConstParam, TypeParam, Union, Variant,
+ Type, TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant,
};
impl HirDisplay for Function {
@@ -437,6 +437,12 @@
}
}
+impl HirDisplay for TypeNs<'_> {
+ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
+ self.ty.hir_fmt(f)
+ }
+}
+
impl HirDisplay for ExternCrateDecl {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index f231348..1cec01d 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -86,7 +86,9 @@
method_resolution,
mir::{MutBorrowKind, interpret_mir},
next_solver::{
- ClauseKind, DbInterner, GenericArgs, infer::InferCtxt, mapping::ChalkToNextSolver,
+ ClauseKind, DbInterner, GenericArgs,
+ infer::InferCtxt,
+ mapping::{ChalkToNextSolver, convert_ty_for_result},
},
primitive::UintTy,
traits::FnTrait,
@@ -1346,19 +1348,12 @@
u32::from(self.id.into_raw()) as usize
}
- /// Returns the type as in the signature of the struct (i.e., with
- /// placeholder types for type parameters). Only use this in the context of
- /// the field definition.
- pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> {
+ /// Returns the type as in the signature of the struct. Only use this in the
+ /// context of the field definition.
+ pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> {
let var_id = self.parent.into();
- let generic_def_id: GenericDefId = match self.parent {
- VariantDef::Struct(it) => it.id.into(),
- VariantDef::Union(it) => it.id.into(),
- VariantDef::Variant(it) => it.id.lookup(db).parent.into(),
- };
- let substs = TyBuilder::placeholder_subst(db, generic_def_id);
- let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
- Type::new(db, var_id, ty)
+ let ty = db.field_types_ns(var_id)[self.id].skip_binder();
+ TypeNs::new(db, var_id, ty)
}
// FIXME: Find better API to also handle const generics
@@ -1388,9 +1383,8 @@
}
pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
- let interner = DbInterner::new_with(db, None, None);
db.layout_of_ty(
- self.ty(db).ty.to_nextsolver(interner),
+ self.ty(db).ty,
db.trait_environment(match hir_def::VariantId::from(self.parent) {
hir_def::VariantId::EnumVariantId(id) => {
GenericDefId::AdtId(id.lookup(db).parent.into())
@@ -5969,6 +5963,11 @@
TypeNs { env: environment, ty, _pd: PhantomCovariantLifetime::new() }
}
+ pub fn to_type(&self, db: &'db dyn HirDatabase) -> Type<'db> {
+ let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block);
+ Type { env: self.env.clone(), ty: convert_ty_for_result(interner, self.ty), _pd: self._pd }
+ }
+
// FIXME: Find better API that also handles const generics
pub fn impls_trait(&self, infcx: InferCtxt<'db>, trait_: Trait, args: &[TypeNs<'db>]) -> bool {
let args = GenericArgs::new_from_iter(
@@ -5992,6 +5991,10 @@
let res = hir_ty::traits::next_trait_solve_in_ctxt(&infcx, goal);
res.map_or(false, |res| matches!(res.1, rustc_type_ir::solve::Certainty::Yes))
}
+
+ pub fn is_bool(&self) -> bool {
+ matches!(self.ty.kind(), rustc_type_ir::TyKind::Bool)
+ }
}
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index 4d3212c..3910921 100644
--- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -521,7 +521,7 @@
hir::StructKind::Tuple => {
let mut name_generator = suggest_name::NameGenerator::default();
let pats = fields.into_iter().map(|f| {
- let name = name_generator.for_type(&f.ty(db), db, edition);
+ let name = name_generator.for_type(&f.ty(db).to_type(db), db, edition);
match name {
Some(name) => make::ext::simple_ident_pat(make.name(&name)).into(),
None => make.wildcard_pat().into(),
diff --git a/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/crates/ide-assists/src/handlers/expand_rest_pattern.rs
index c80b78f..1c0d330 100644
--- a/crates/ide-assists/src/handlers/expand_rest_pattern.rs
+++ b/crates/ide-assists/src/handlers/expand_rest_pattern.rs
@@ -145,8 +145,11 @@
make.ident_pat(
false,
false,
- match name_gen.for_type(&f.ty(ctx.sema.db), ctx.sema.db, ctx.edition())
- {
+ match name_gen.for_type(
+ &f.ty(ctx.sema.db).to_type(ctx.sema.db),
+ ctx.sema.db,
+ ctx.edition(),
+ ) {
Some(name) => make.name(&name),
None => make.name(&format!("_{}", f.index())),
},
diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs
index 36f38a7..2f5abd1 100644
--- a/crates/ide-completion/src/completions/record.rs
+++ b/crates/ide-completion/src/completions/record.rs
@@ -28,7 +28,11 @@
record_pat.record_pat_field_list().and_then(|fl| fl.fields().next()).is_some();
match were_fields_specified {
- false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
+ false => un
+ .fields(ctx.db)
+ .into_iter()
+ .map(|f| (f, f.ty(ctx.db).to_type(ctx.db)))
+ .collect(),
true => return,
}
}
@@ -56,7 +60,11 @@
record_expr.record_expr_field_list().and_then(|fl| fl.fields().next()).is_some();
match were_fields_specified {
- false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
+ false => un
+ .fields(ctx.db)
+ .into_iter()
+ .map(|f| (f, f.ty(ctx.db).to_type(ctx.db)))
+ .collect(),
true => return,
}
}
diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs
index ffd144a..ae208fe 100644
--- a/crates/ide/src/goto_type_definition.rs
+++ b/crates/ide/src/goto_type_definition.rs
@@ -88,7 +88,7 @@
ast::Pat(it) => sema.type_of_pat(&it)?.original,
ast::SelfParam(it) => sema.type_of_self(&it)?,
ast::Type(it) => sema.resolve_type(&it)?,
- ast::RecordField(it) => sema.to_def(&it)?.ty(db),
+ ast::RecordField(it) => sema.to_def(&it)?.ty(db).to_type(db),
// can't match on RecordExprField directly as `ast::Expr` will match an iteration too early otherwise
ast::NameRef(it) => {
if let Some(record_field) = ast::RecordExprField::for_name_ref(&it) {
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 03b9b36..c4fb6d1 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -440,7 +440,7 @@
Definition::Local(it) => Some(it.ty(db)),
Definition::GenericParam(hir::GenericParam::ConstParam(it)) => Some(it.ty(db)),
Definition::GenericParam(hir::GenericParam::TypeParam(it)) => Some(it.ty(db)),
- Definition::Field(field) => Some(field.ty(db)),
+ Definition::Field(field) => Some(field.ty(db).to_type(db)),
Definition::TupleField(it) => Some(it.ty(db)),
Definition::Function(it) => Some(it.ty(db)),
Definition::Adt(it) => Some(it.ty(db)),
@@ -602,7 +602,7 @@
let ty = match def {
Definition::Local(it) => Some(it.ty(db)),
- Definition::Field(field) => Some(field.ty(db)),
+ Definition::Field(field) => Some(field.ty(db).to_type(db)),
Definition::TupleField(field) => Some(field.ty(db)),
Definition::Const(it) => Some(it.ty(db)),
Definition::Static(it) => Some(it.ty(db)),
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index 65375ed..c5d695c 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -692,14 +692,14 @@
}
let drop_info = match def {
Definition::Field(field) => {
- DropInfo { drop_glue: field.ty(db).drop_glue(db), has_dtor: None }
+ DropInfo { drop_glue: field.ty(db).to_type(db).drop_glue(db), has_dtor: None }
}
Definition::Adt(Adt::Struct(strukt)) => {
let struct_drop_glue = strukt.ty_placeholders(db).drop_glue(db);
let mut fields_drop_glue = strukt
.fields(db)
.iter()
- .map(|field| field.ty(db).drop_glue(db))
+ .map(|field| field.ty(db).to_type(db).drop_glue(db))
.max()
.unwrap_or(DropGlue::None);
let has_dtor = match (fields_drop_glue, struct_drop_glue) {
@@ -727,7 +727,7 @@
variant
.fields(db)
.iter()
- .map(|field| field.ty(db).drop_glue(db))
+ .map(|field| field.ty(db).to_type(db).drop_glue(db))
.max()
.unwrap_or(DropGlue::None)
})
@@ -742,7 +742,7 @@
let fields_drop_glue = variant
.fields(db)
.iter()
- .map(|field| field.ty(db).drop_glue(db))
+ .map(|field| field.ty(db).to_type(db).drop_glue(db))
.max()
.unwrap_or(DropGlue::None);
DropInfo { drop_glue: fields_drop_glue, has_dtor: None }
diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs
index f45d096..e74d997 100644
--- a/crates/ide/src/signature_help.rs
+++ b/crates/ide/src/signature_help.rs
@@ -526,7 +526,7 @@
pat.syntax(),
token,
pat.fields(),
- fields.into_iter().map(|it| it.ty(db)),
+ fields.into_iter().map(|it| it.ty(db).to_type(db)),
display_target,
))
}
diff --git a/crates/ide/src/view_memory_layout.rs b/crates/ide/src/view_memory_layout.rs
index 950f3f6..5457d57 100644
--- a/crates/ide/src/view_memory_layout.rs
+++ b/crates/ide/src/view_memory_layout.rs
@@ -99,7 +99,7 @@
Definition::BuiltinType(it) => it.ty(db),
Definition::SelfType(it) => it.self_ty(db),
Definition::Local(it) => it.ty(db),
- Definition::Field(it) => it.ty(db),
+ Definition::Field(it) => salsa::attach(db, || it.ty(db).to_type(db)),
Definition::Const(it) => it.ty(db),
Definition::Static(it) => it.ty(db),
_ => return None,