diff --git a/crates/hir-ty/src/next_solver/mapping.rs b/crates/hir-ty/src/next_solver/mapping.rs index b24b996b09..5dcb1e6232 100644 --- a/crates/hir-ty/src/next_solver/mapping.rs +++ b/crates/hir-ty/src/next_solver/mapping.rs @@ -1266,7 +1266,7 @@ pub fn convert_args_for_result<'db>( 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 833a9ef030..2bf9bb85e5 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -24,7 +24,7 @@ use crate::{ 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 Type<'_> { } } +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 f231348d24..1cec01da60 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -86,7 +86,9 @@ use hir_ty::{ 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 @@ impl Field { 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 @@ impl Field { } pub fn layout(&self, db: &dyn HirDatabase) -> Result { - 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 @@ impl<'db> TypeNs<'db> { 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 @@ impl<'db> TypeNs<'db> { 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 4d3212c515..3910921fbe 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 @@ fn build_pat( 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 c80b78fd97..1c0d330fc3 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 @@ fn expand_tuple_struct_rest_pattern( 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 36f38a70db..2f5abd1893 100644 --- a/crates/ide-completion/src/completions/record.rs +++ b/crates/ide-completion/src/completions/record.rs @@ -28,7 +28,11 @@ pub(crate) fn complete_record_pattern_fields( 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 @@ pub(crate) fn complete_record_expr_fields( 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 ffd144a827..ae208fe1b5 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs @@ -88,7 +88,7 @@ pub(crate) fn goto_type_definition( 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 03b9b36775..c4fb6d1a5b 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -440,7 +440,7 @@ pub(crate) fn hover_for_definition( 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 @@ fn goto_type_action_for_def( 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 65375ed8f7..c5d695ccec 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -692,14 +692,14 @@ pub(super) fn definition( } 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 @@ pub(super) fn definition( 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 @@ pub(super) fn definition( 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 f45d096ac1..e74d997e97 100644 --- a/crates/ide/src/signature_help.rs +++ b/crates/ide/src/signature_help.rs @@ -526,7 +526,7 @@ fn signature_help_for_tuple_struct_pat( 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 950f3f6c64..5457d57b39 100644 --- a/crates/ide/src/view_memory_layout.rs +++ b/crates/ide/src/view_memory_layout.rs @@ -99,7 +99,7 @@ pub(crate) fn view_memory_layout( 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,