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.rs | 487 |
1 files changed, 238 insertions, 249 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 2d70a8dca1..2146e4db77 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -48,17 +48,19 @@ use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateOrigin, LangCrateOrigin}; use either::Either; use hir_def::{ - AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId, - CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, - FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, + AdtId, AssocItemId, AssocItemLoc, CallableDefId, ConstId, ConstParamId, CrateRootModuleId, + DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, + GenericParamId, HasModule, ImplId, InternedModuleId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, + attrs::AttrFlags, expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap}, hir::{ BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, }, item_tree::ImportAlias, + lang_item::LangItemTarget, layout::{self, ReprOptions, TargetDataLayout}, nameres::{ assoc::TraitItems, @@ -66,17 +68,16 @@ use hir_def::{ }, per_ns::PerNs, resolver::{HasResolver, Resolver}, - signatures::{ImplFlags, StaticFlags, StructFlags, TraitFlags, VariantFields}, + signatures::{EnumSignature, ImplFlags, StaticFlags, StructFlags, TraitFlags, VariantFields}, src::HasSource as _, visibility::visibility_from_ast, }; use hir_expand::{ - AstId, MacroCallKind, RenderedExpandError, ValueResult, attrs::collect_attrs, - proc_macro::ProcMacroKind, + AstId, MacroCallKind, RenderedExpandError, ValueResult, proc_macro::ProcMacroKind, }; use hir_ty::{ - GenericPredicates, TraitEnvironment, TyDefId, TyLoweringDiagnostic, ValueTyDefId, - all_super_traits, autoderef, check_orphan_rules, + GenericPredicates, InferenceResult, TraitEnvironment, TyDefId, TyLoweringDiagnostic, + ValueTyDefId, all_super_traits, autoderef, check_orphan_rules, consteval::try_const_usize, db::{InternedClosureId, InternedCoroutineId}, diagnostics::BodyValidationDiagnostic, @@ -91,7 +92,7 @@ use hir_ty::{ PolyFnSig, Region, SolverDefId, Ty, TyKind, TypingMode, infer::{DbInternerInferExt, InferCtxt}, }, - traits::{self, FnTrait, is_inherent_impl_coherent, structurally_normalize_ty}, + traits::{self, is_inherent_impl_coherent, structurally_normalize_ty}, }; use itertools::Itertools; use rustc_hash::FxHashSet; @@ -103,8 +104,8 @@ use smallvec::SmallVec; use span::{AstIdNode, Edition, FileId}; use stdx::{format_to, impl_from, never}; use syntax::{ - AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, T, TextRange, ToSmolStr, - ast::{self, HasAttrs as _, HasName, HasVisibility as _}, + AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, + ast::{self, HasName, HasVisibility as _}, format_smolstr, }; use triomphe::{Arc, ThinArc}; @@ -112,7 +113,7 @@ use triomphe::{Arc, ThinArc}; use crate::db::{DefDatabase, HirDatabase}; pub use crate::{ - attrs::{HasAttrs, resolve_doc_path_on}, + attrs::{AttrsWithOwner, HasAttrs, resolve_doc_path_on}, diagnostics::*, has_source::HasSource, semantics::{ @@ -135,10 +136,10 @@ pub use { hir_def::{ Complete, FindPathConfig, - attr::{AttrSourceMap, Attrs, AttrsWithOwner}, + attrs::{Docs, IsInnerDoc}, find_path::PrefixKind, import_map, - lang_item::{LangItem, crate_lang_items}, + lang_item::{LangItemEnum as LangItem, crate_lang_items}, nameres::{DefMap, ModuleSource, crate_def_map}, per_ns::Namespace, type_ref::{Mutability, TypeRef}, @@ -149,7 +150,6 @@ pub use { }, hir_expand::{ EditionedFileId, ExpandResult, HirFileId, MacroCallId, MacroKind, - attrs::{Attr, AttrId}, change::ChangeWithProcMacros, files::{ FilePosition, FilePositionWrapper, FileRange, FileRangeWrapper, HirFilePosition, @@ -305,11 +305,10 @@ impl Crate { } /// Try to get the root URL of the documentation of a crate. - pub fn get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option<String> { + pub fn get_html_root_url(self, db: &dyn HirDatabase) -> Option<String> { // Look for #![doc(html_root_url = "...")] - let attrs = db.attrs(AttrDefId::ModuleId(self.root_module().into())); - let doc_url = attrs.by_key(sym::doc).find_string_value_in_tt(sym::html_root_url); - doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") + let doc_url = AttrFlags::doc_html_root_url(db, self.id); + doc_url.as_ref().map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") } pub fn cfg<'db>(&self, db: &'db dyn HirDatabase) -> &'db CfgOptions { @@ -654,7 +653,7 @@ impl Module { // FIXME: This is accidentally quadratic. continue; } - emit_def_diagnostic(db, acc, diag, edition); + emit_def_diagnostic(db, acc, diag, edition, def_map.krate()); } if !self.id.is_block_module() { @@ -673,8 +672,9 @@ impl Module { acc.extend(def.diagnostics(db, style_lints)) } ModuleDef::Trait(t) => { + let krate = t.krate(db); for diag in TraitItems::query_with_diagnostics(db, t.id).1.iter() { - emit_def_diagnostic(db, acc, diag, edition); + emit_def_diagnostic(db, acc, diag, edition, krate.id); } for item in t.items(db) { @@ -765,7 +765,7 @@ impl Module { } self.legacy_macros(db).into_iter().for_each(|m| emit_macro_def_diagnostics(db, acc, m)); - let interner = DbInterner::new_with(db, Some(self.id.krate()), self.id.containing_block()); + let interner = DbInterner::new_with(db, self.id.krate()); let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis()); let mut impl_assoc_items_scratch = vec![]; @@ -790,7 +790,7 @@ impl Module { let ast_id_map = db.ast_id_map(file_id); for diag in impl_def.id.impl_items_with_diagnostics(db).1.iter() { - emit_def_diagnostic(db, acc, diag, edition); + emit_def_diagnostic(db, acc, diag, edition, loc.container.krate()); } if impl_signature.target_trait.is_none() @@ -818,26 +818,15 @@ impl Module { let drop_maybe_dangle = (|| { // FIXME: This can be simplified a lot by exposing hir-ty's utils.rs::Generics helper let trait_ = trait_?; - let drop_trait = LangItem::Drop.resolve_trait(db, self.krate().into())?; + let drop_trait = interner.lang_items().Drop?; if drop_trait != trait_.into() { return None; } let parent = impl_def.id.into(); - let generic_params = db.generic_params(parent); - let lifetime_params = generic_params.iter_lt().map(|(local_id, _)| { - GenericParamId::LifetimeParamId(LifetimeParamId { parent, local_id }) - }); - let type_params = generic_params - .iter_type_or_consts() - .filter(|(_, it)| it.type_param().is_some()) - .map(|(local_id, _)| { - GenericParamId::TypeParamId(TypeParamId::from_unchecked( - TypeOrConstParamId { parent, local_id }, - )) - }); - let res = type_params.chain(lifetime_params).any(|p| { - db.attrs(AttrDefId::GenericParamId(p)).by_key(sym::may_dangle).exists() - }); + let (lifetimes_attrs, type_and_consts_attrs) = + AttrFlags::query_generic_params(db, parent); + let res = lifetimes_attrs.values().any(|it| it.contains(AttrFlags::MAY_DANGLE)) + || type_and_consts_attrs.values().any(|it| it.contains(AttrFlags::MAY_DANGLE)); Some(res) })() .unwrap_or(false); @@ -998,6 +987,17 @@ impl Module { ) -> Option<ModPath> { hir_def::find_path::find_path(db, item.into().into(), self.into(), prefix_kind, true, cfg) } + + #[inline] + pub fn doc_keyword(self, db: &dyn HirDatabase) -> Option<Symbol> { + AttrFlags::doc_keyword(db, InternedModuleId::new(db, self.id)) + } + + /// Whether it has `#[path = "..."]` attribute. + #[inline] + pub fn has_path(&self, db: &dyn HirDatabase) -> bool { + self.attrs(db).attrs.contains(AttrFlags::HAS_PATH) + } } fn macro_call_diagnostics<'db>( @@ -1012,31 +1012,19 @@ fn macro_call_diagnostics<'db>( if let Some(err) = err { let loc = db.lookup_intern_macro_call(macro_call_id); let file_id = loc.kind.file_id(); - let node = - InFile::new(file_id, db.ast_id_map(file_id).get_erased(loc.kind.erased_ast_id())); + let mut range = precise_macro_call_location(&loc.kind, db, loc.krate); let RenderedExpandError { message, error, kind } = err.render_to_string(db); - let editioned_file_id = EditionedFileId::from_span(db, err.span().anchor.file_id); - let precise_location = if editioned_file_id == file_id { - Some( - err.span().range - + db.ast_id_map(editioned_file_id.into()) - .get_erased(err.span().anchor.ast_id) - .text_range() - .start(), - ) - } else { - None - }; - acc.push(MacroError { node, precise_location, message, error, kind }.into()); + if Some(err.span().anchor.file_id) == file_id.file_id().map(|it| it.editioned_file_id(db)) { + range.value = err.span().range + + db.ast_id_map(file_id).get_erased(err.span().anchor.ast_id).text_range().start(); + } + acc.push(MacroError { range, message, error, kind }.into()); } if !parse_errors.is_empty() { let loc = db.lookup_intern_macro_call(macro_call_id); - let (node, precise_location) = precise_macro_call_location(&loc.kind, db); - acc.push( - MacroExpansionParseError { node, precise_location, errors: parse_errors.clone() } - .into(), - ) + let range = precise_macro_call_location(&loc.kind, db, loc.krate); + acc.push(MacroExpansionParseError { range, errors: parse_errors.clone() }.into()) } } @@ -1060,6 +1048,7 @@ fn emit_macro_def_diagnostics<'db>( acc, &DefDiagnosticKind::MacroDefError { ast, message: e.to_string() }, edition, + m.krate(db).id, ); } } @@ -1069,8 +1058,9 @@ fn emit_def_diagnostic<'db>( acc: &mut Vec<AnyDiagnostic<'db>>, diag: &DefDiagnostic, edition: Edition, + krate: base_db::Crate, ) { - emit_def_diagnostic_(db, acc, &diag.kind, edition) + emit_def_diagnostic_(db, acc, &diag.kind, edition, krate) } fn emit_def_diagnostic_<'db>( @@ -1078,6 +1068,7 @@ fn emit_def_diagnostic_<'db>( acc: &mut Vec<AnyDiagnostic<'db>>, diag: &DefDiagnosticKind, edition: Edition, + krate: base_db::Crate, ) { match diag { DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates } => { @@ -1100,8 +1091,7 @@ fn emit_def_diagnostic_<'db>( let RenderedExpandError { message, error, kind } = err.render_to_string(db); acc.push( MacroError { - node: InFile::new(ast.file_id, item.syntax_node_ptr()), - precise_location: None, + range: InFile::new(ast.file_id, item.text_range()), message: format!("{}: {message}", path.display(db, edition)), error, kind, @@ -1131,11 +1121,10 @@ fn emit_def_diagnostic_<'db>( ); } DefDiagnosticKind::UnresolvedMacroCall { ast, path } => { - let (node, precise_location) = precise_macro_call_location(ast, db); + let location = precise_macro_call_location(ast, db, krate); acc.push( UnresolvedMacroCall { - macro_call: node, - precise_location, + range: location, path: path.clone(), is_bang: matches!(ast, MacroCallKind::FnLike { .. }), } @@ -1154,34 +1143,12 @@ fn emit_def_diagnostic_<'db>( ); } DefDiagnosticKind::InvalidDeriveTarget { ast, id } => { - let node = ast.to_node(db); - let derive = node.attrs().nth(*id); - match derive { - Some(derive) => { - acc.push( - InvalidDeriveTarget { - node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&derive))), - } - .into(), - ); - } - None => stdx::never!("derive diagnostic on item without derive attribute"), - } + let derive = id.find_attr_range(db, krate, *ast).3.path_range(); + acc.push(InvalidDeriveTarget { range: ast.with_value(derive) }.into()); } DefDiagnosticKind::MalformedDerive { ast, id } => { - let node = ast.to_node(db); - let derive = node.attrs().nth(*id); - match derive { - Some(derive) => { - acc.push( - MalformedDerive { - node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&derive))), - } - .into(), - ); - } - None => stdx::never!("derive diagnostic on item without derive attribute"), - } + let derive = id.find_attr_range(db, krate, *ast).2; + acc.push(MalformedDerive { range: ast.with_value(derive) }.into()); } DefDiagnosticKind::MacroDefError { ast, message } => { let node = ast.to_node(db); @@ -1200,61 +1167,28 @@ fn emit_def_diagnostic_<'db>( fn precise_macro_call_location( ast: &MacroCallKind, db: &dyn HirDatabase, -) -> (InFile<SyntaxNodePtr>, Option<TextRange>) { + krate: base_db::Crate, +) -> InFile<TextRange> { // FIXME: maybe we actually want slightly different ranges for the different macro diagnostics // - e.g. the full attribute for macro errors, but only the name for name resolution match ast { MacroCallKind::FnLike { ast_id, .. } => { let node = ast_id.to_node(db); - ( - ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))), - node.path() - .and_then(|it| it.segment()) - .and_then(|it| it.name_ref()) - .map(|it| it.syntax().text_range()), - ) + let range = node + .path() + .and_then(|it| it.segment()) + .and_then(|it| it.name_ref()) + .map(|it| it.syntax().text_range()); + let range = range.unwrap_or_else(|| node.syntax().text_range()); + ast_id.with_value(range) } MacroCallKind::Derive { ast_id, derive_attr_index, derive_index, .. } => { - let node = ast_id.to_node(db); - // Compute the precise location of the macro name's token in the derive - // list. - let token = (|| { - let derive_attr = collect_attrs(&node) - .nth(derive_attr_index.ast_index()) - .and_then(|x| Either::left(x.1))?; - let token_tree = derive_attr.meta()?.token_tree()?; - let chunk_by = token_tree - .syntax() - .children_with_tokens() - .filter_map(|elem| match elem { - syntax::NodeOrToken::Token(tok) => Some(tok), - _ => None, - }) - .chunk_by(|t| t.kind() == T![,]); - let (_, mut group) = chunk_by - .into_iter() - .filter(|&(comma, _)| !comma) - .nth(*derive_index as usize)?; - group.find(|t| t.kind() == T![ident]) - })(); - ( - ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node))), - token.as_ref().map(|tok| tok.text_range()), - ) + let range = derive_attr_index.find_derive_range(db, krate, *ast_id, *derive_index); + ast_id.with_value(range) } - MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => { - let node = ast_id.to_node(db); - let attr = collect_attrs(&node) - .nth(invoc_attr_index.ast_index()) - .and_then(|x| Either::left(x.1)) - .unwrap_or_else(|| { - panic!("cannot find attribute #{}", invoc_attr_index.ast_index()) - }); - - ( - ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))), - Some(attr.syntax().text_range()), - ) + MacroCallKind::Attr { ast_id, censored_attr_ids: attr_ids, .. } => { + let attr_range = attr_ids.invoc_attr().find_attr_range(db, krate, *ast_id).2; + ast_id.with_value(attr_range) } } } @@ -1282,8 +1216,7 @@ pub struct InstantiatedField<'db> { impl<'db> InstantiatedField<'db> { /// Returns the type as in the signature of the struct. pub fn ty(&self, db: &'db dyn HirDatabase) -> TypeNs<'db> { - let krate = self.inner.krate(db); - let interner = DbInterner::new_with(db, Some(krate.base()), None); + let interner = DbInterner::new_no_crate(db); let var_id = self.inner.parent.into(); let field = db.field_types(var_id)[self.inner.id]; @@ -1305,9 +1238,8 @@ impl TupleField { } pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { - let interner = DbInterner::new_with(db, None, None); - let ty = db - .infer(self.owner) + let interner = DbInterner::new_no_crate(db); + let ty = InferenceResult::for_body(db, self.owner) .tuple_field_access_type(self.tuple) .as_slice() .get(self.index as usize) @@ -1381,7 +1313,7 @@ impl Field { VariantDef::Union(it) => it.id.into(), VariantDef::Variant(it) => it.parent_enum(db).id.into(), }; - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty)); let ty = db.field_types(var_id)[self.id].instantiate(interner, args); Type::new(db, var_id, ty) @@ -1452,7 +1384,7 @@ impl Struct { } pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> { - db.struct_signature(self.id).repr + AttrFlags::repr(db, self.id.into()) } pub fn kind(self, db: &dyn HirDatabase) -> StructKind { @@ -1468,7 +1400,7 @@ impl Struct { } pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_unstable() + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE) } pub fn instantiate_infer<'db>(self, infer_ctxt: &InferCtxt<'db>) -> InstantiatedStruct<'db> { @@ -1506,8 +1438,7 @@ impl<'db> InstantiatedStruct<'db> { } pub fn ty(self, db: &'db dyn HirDatabase) -> TypeNs<'db> { - let krate = self.inner.krate(db); - let interner = DbInterner::new_with(db, Some(krate.base()), None); + let interner = DbInterner::new_no_crate(db); let ty = db.ty(self.inner.id.into()); TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args)) @@ -1557,7 +1488,7 @@ impl Union { .collect() } pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_unstable() + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE) } } @@ -1592,7 +1523,7 @@ impl Enum { } pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> { - db.enum_signature(self.id).repr + AttrFlags::repr(db, self.id.into()) } pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { @@ -1605,10 +1536,10 @@ impl Enum { /// The type of the enum variant bodies. pub fn variant_body_ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); Type::new_for_crate( self.id.lookup(db).container.krate(), - match db.enum_signature(self.id).variant_body_type() { + match EnumSignature::variant_body_type(db, self.id) { layout::IntegerType::Pointer(sign) => match sign { true => Ty::new_int(interner, rustc_type_ir::IntTy::Isize), false => Ty::new_uint(interner, rustc_type_ir::UintTy::Usize), @@ -1649,7 +1580,7 @@ impl Enum { } pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_unstable() + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE) } } @@ -1669,8 +1600,7 @@ pub struct InstantiatedEnum<'db> { impl<'db> InstantiatedEnum<'db> { pub fn ty(self, db: &'db dyn HirDatabase) -> TypeNs<'db> { - let krate = self.inner.krate(db); - let interner = DbInterner::new_with(db, Some(krate.base()), None); + let interner = DbInterner::new_no_crate(db); let ty = db.ty(self.inner.id.into()); TypeNs::new(db, self.inner.id, ty.instantiate(interner, self.args)) @@ -1750,7 +1680,7 @@ impl Variant { } pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_unstable() + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE) } pub fn instantiate_infer<'db>(self, infer_ctxt: &InferCtxt<'db>) -> InstantiatedVariant<'db> { @@ -1816,7 +1746,7 @@ impl Adt { pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { let env = db.trait_environment(self.into()); - let interner = DbInterner::new_with(db, Some(env.krate), env.block); + let interner = DbInterner::new_no_crate(db); let adt_id = AdtId::from(self); let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| { GenericArg::error_from_id(interner, id) @@ -1841,7 +1771,7 @@ impl Adt { args: impl IntoIterator<Item = Type<'db>>, ) -> Type<'db> { let id = AdtId::from(self); - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let ty = Ty::new_adt( interner, id, @@ -2025,7 +1955,7 @@ impl DefWithBody { expr_store_diagnostics(db, acc, &source_map); - let infer = db.infer(self.into()); + let infer = InferenceResult::for_body(db, self.into()); for d in infer.diagnostics() { acc.extend(AnyDiagnostic::inference_diagnostic( db, @@ -2235,8 +2165,7 @@ fn expr_store_diagnostics<'db>( InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into() } ExpressionStoreDiagnostics::UnresolvedMacroCall { node, path } => UnresolvedMacroCall { - macro_call: (*node).map(|ast_ptr| ast_ptr.into()), - precise_location: None, + range: node.map(|ptr| ptr.text_range()), path: path.clone(), is_bang: true, } @@ -2277,7 +2206,7 @@ impl Function { pub fn fn_ptr_type(self, db: &dyn HirDatabase) -> Type<'_> { let resolver = self.id.resolver(db); - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); // FIXME: This shouldn't be `instantiate_identity()`, we shouldn't leak `TyKind::Param`s. let callable_sig = db.callable_item_signature(self.id.into()).instantiate_identity(); let ty = Ty::new_fn_ptr(interner, callable_sig); @@ -2305,10 +2234,10 @@ impl Function { generics: impl Iterator<Item = Type<'db>>, ) -> Type<'db> { let resolver = self.id.resolver(db); - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty)); - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let ty = db .callable_item_signature(self.id.into()) .instantiate(interner, args) @@ -2396,7 +2325,7 @@ impl Function { generics: impl Iterator<Item = Type<'db>>, ) -> Vec<Param<'db>> { let environment = db.trait_environment(self.id.into()); - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, self.id.into(), generics.map(|ty| ty.ty)); let callable_sig = db.callable_item_signature(self.id.into()).instantiate(interner, args).skip_binder(); @@ -2439,11 +2368,11 @@ impl Function { let ret_type = self.ret_type(db); let Some(impl_traits) = ret_type.as_impl_traits(db) else { return false }; - let Some(future_trait_id) = LangItem::Future.resolve_trait(db, self.ty(db).env.krate) - else { + let lang_items = hir_def::lang_item::lang_items(db, self.krate(db).id); + let Some(future_trait_id) = lang_items.Future else { return false; }; - let Some(sized_trait_id) = LangItem::Sized.resolve_trait(db, self.ty(db).env.krate) else { + let Some(sized_trait_id) = lang_items.Sized else { return false; }; @@ -2461,33 +2390,33 @@ impl Function { /// Does this function have `#[test]` attribute? pub fn is_test(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_test() + self.attrs(db).is_test() } /// is this a `fn main` or a function with an `export_name` of `main`? pub fn is_main(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).export_name() == Some(&sym::main) + self.exported_main(db) || self.module(db).is_crate_root() && db.function_signature(self.id).name == sym::main } /// Is this a function with an `export_name` of `main`? pub fn exported_main(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).export_name() == Some(&sym::main) + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_EXPORT_NAME_MAIN) } /// Does this function have the ignore attribute? pub fn is_ignore(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_ignore() + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_IGNORE) } /// Does this function have `#[bench]` attribute? pub fn is_bench(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_bench() + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_BENCH) } /// Is this function marked as unstable with `#[feature]` attribute? pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { - db.attrs(self.id.into()).is_unstable() + AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_UNSTABLE) } pub fn is_unsafe_to_call( @@ -2498,8 +2427,7 @@ impl Function { ) -> bool { let (target_features, target_feature_is_safe_in_target) = caller .map(|caller| { - let target_features = - hir_ty::TargetFeatures::from_attrs(&db.attrs(caller.id.into())); + let target_features = hir_ty::TargetFeatures::from_fn(db, caller.id); let target_feature_is_safe_in_target = match &caller.krate(db).id.workspace_data(db).target { Ok(target) => hir_ty::target_feature_is_safe_in_target(target), @@ -2530,14 +2458,6 @@ impl Function { } pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option<Macro> { - let attrs = db.attrs(self.id.into()); - // FIXME: Store this in FunctionData flags? - if !(attrs.is_proc_macro() - || attrs.is_proc_macro_attribute() - || attrs.is_proc_macro_derive()) - { - return None; - } let def_map = crate_def_map(db, HasModule::krate(&self.id, db)); def_map.fn_as_proc_macro(self.id).map(|id| Macro { id: id.into() }) } @@ -2547,7 +2467,7 @@ impl Function { db: &dyn HirDatabase, span_formatter: impl Fn(FileId, TextRange) -> String, ) -> Result<String, ConstEvalError<'_>> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let body = db.monomorphized_mir_body( self.id.into(), GenericArgs::new_from_iter(interner, []), @@ -2704,7 +2624,7 @@ impl SelfParam { db: &'db dyn HirDatabase, generics: impl Iterator<Item = Type<'db>>, ) -> Type<'db> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, self.func.into(), generics.map(|ty| ty.ty)); let callable_sig = db.callable_item_signature(self.func.into()).instantiate(interner, args).skip_binder(); @@ -2804,7 +2724,7 @@ impl Const { /// Evaluate the constant. pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst<'_>, ConstEvalError<'_>> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity(); db.const_eval(self.id, GenericArgs::new_from_iter(interner, []), None) .map(|it| EvaluatedConst { const_: it, def: self.id.into(), ty }) @@ -2908,8 +2828,12 @@ pub struct Trait { } impl Trait { - pub fn lang(db: &dyn HirDatabase, krate: Crate, name: &Name) -> Option<Trait> { - LangItem::from_name(name)?.resolve_trait(db, krate.into()).map(Into::into) + pub fn lang(db: &dyn HirDatabase, krate: Crate, lang_item: LangItem) -> Option<Trait> { + let lang_items = hir_def::lang_item::lang_items(db, krate.id); + match lang_item.from_lang_items(lang_items)? { + LangItemTarget::TraitId(it) => Some(it.into()), + _ => None, + } } pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -2992,7 +2916,7 @@ impl Trait { /// `#[rust_analyzer::completions(...)]` mode. pub fn complete(self, db: &dyn HirDatabase) -> Complete { - Complete::extract(true, &self.attrs(db)) + Complete::extract(true, self.attrs(db).attrs) } } @@ -3076,7 +3000,7 @@ impl BuiltinType { pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { let core = Crate::core(db).map(|core| core.id).unwrap_or_else(|| db.all_crates()[0]); - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); Type::new_for_crate(core, Ty::from_builtin_type(interner, self.inner)) } @@ -3163,10 +3087,10 @@ impl Macro { let loc = id.lookup(db); let source = loc.source(db); match loc.kind { - ProcMacroKind::CustomDerive => db - .attrs(id.into()) - .parse_proc_macro_derive() - .map_or_else(|| as_name_opt(source.value.name()), |(it, _)| it), + ProcMacroKind::CustomDerive => AttrFlags::derive_info(db, self.id).map_or_else( + || as_name_opt(source.value.name()), + |info| Name::new_symbol_root(info.trait_name.clone()), + ), ProcMacroKind::Bang | ProcMacroKind::Attr => as_name_opt(source.value.name()), } } @@ -3174,7 +3098,7 @@ impl Macro { } pub fn is_macro_export(self, db: &dyn HirDatabase) -> bool { - matches!(self.id, MacroId::MacroRulesId(_) if db.attrs(self.id.into()).by_key(sym::macro_export).exists()) + matches!(self.id, MacroId::MacroRulesId(_) if AttrFlags::query(db, self.id.into()).contains(AttrFlags::IS_MACRO_EXPORT)) } pub fn is_proc_macro(self) -> bool { @@ -3919,7 +3843,7 @@ impl Local { pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let def = self.parent; - let infer = db.infer(def); + let infer = InferenceResult::for_body(db, def); let ty = infer[self.binding_id]; Type::new(db, def, ty) } @@ -4007,18 +3931,10 @@ impl DeriveHelper { } pub fn name(&self, db: &dyn HirDatabase) -> Name { - match self.derive { - makro @ MacroId::Macro2Id(_) => db - .attrs(makro.into()) - .parse_rustc_builtin_macro() - .and_then(|(_, helpers)| helpers.get(self.idx as usize).cloned()), - MacroId::MacroRulesId(_) => None, - makro @ MacroId::ProcMacroId(_) => db - .attrs(makro.into()) - .parse_proc_macro_derive() - .and_then(|(_, helpers)| helpers.get(self.idx as usize).cloned()), - } - .unwrap_or_else(Name::missing) + AttrFlags::derive_info(db, self.derive) + .and_then(|it| it.helpers.get(self.idx as usize)) + .map(|helper| Name::new_symbol_root(helper.clone())) + .unwrap_or_else(Name::missing) } } @@ -4208,7 +4124,7 @@ impl TypeParam { pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let resolver = self.id.parent().resolver(db); - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let index = hir_ty::param_idx(db, self.id.into()).unwrap(); let ty = Ty::new_param(interner, self.id, index as u32); Type::new_with_resolver_inner(db, &resolver, ty) @@ -4242,7 +4158,7 @@ impl TypeParam { } pub fn is_unstable(self, db: &dyn HirDatabase) -> bool { - db.attrs(GenericParamId::from(self.id).into()).is_unstable() + self.attrs(db).is_unstable() } } @@ -4412,9 +4328,12 @@ impl Impl { /// blanket impls, and only does a shallow type constructor check. In fact, this should've probably been on `Adt` /// etc., and not on `Type`. If you would want to create a precise list of all impls applying to a type, /// you would need to include blanket impls, and try to prove to predicates for each candidate. - pub fn all_for_type<'db>(db: &'db dyn HirDatabase, Type { ty, env }: Type<'db>) -> Vec<Impl> { + pub fn all_for_type<'db>( + db: &'db dyn HirDatabase, + Type { ty, env: _ }: Type<'db>, + ) -> Vec<Impl> { let mut result = Vec::new(); - let interner = DbInterner::new_with(db, Some(env.krate), env.block); + let interner = DbInterner::new_no_crate(db); let Some(simplified_ty) = fast_reject::simplify_type(interner, ty, fast_reject::TreatParams::AsRigid) else { @@ -4591,7 +4510,7 @@ pub struct Closure<'db> { impl<'db> Closure<'db> { fn as_ty(&self, db: &'db dyn HirDatabase) -> Ty<'db> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); match self.id { AnyClosureId::ClosureId(id) => Ty::new_closure(interner, id.into(), self.subst), AnyClosureId::CoroutineClosureId(id) => { @@ -4620,7 +4539,7 @@ impl<'db> Closure<'db> { return Vec::new(); }; let owner = db.lookup_intern_closure(id).0; - let infer = db.infer(owner); + let infer = InferenceResult::for_body(db, owner); let info = infer.closure_info(id); info.0 .iter() @@ -4635,7 +4554,7 @@ impl<'db> Closure<'db> { return Vec::new(); }; let owner = db.lookup_intern_closure(id).0; - let infer = db.infer(owner); + let infer = InferenceResult::for_body(db, owner); let (captures, _) = infer.closure_info(id); let env = db.trait_environment_for_body(owner); captures @@ -4648,9 +4567,9 @@ impl<'db> Closure<'db> { match self.id { AnyClosureId::ClosureId(id) => { let owner = db.lookup_intern_closure(id).0; - let infer = db.infer(owner); + let infer = InferenceResult::for_body(db, owner); let info = infer.closure_info(id); - info.1 + info.1.into() } AnyClosureId::CoroutineClosureId(_id) => { // FIXME: Infer kind for coroutine closures. @@ -4664,6 +4583,71 @@ impl<'db> Closure<'db> { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum FnTrait { + FnOnce, + FnMut, + Fn, + + AsyncFnOnce, + AsyncFnMut, + AsyncFn, +} + +impl From<traits::FnTrait> for FnTrait { + fn from(value: traits::FnTrait) -> Self { + match value { + traits::FnTrait::FnOnce => FnTrait::FnOnce, + traits::FnTrait::FnMut => FnTrait::FnMut, + traits::FnTrait::Fn => FnTrait::Fn, + traits::FnTrait::AsyncFnOnce => FnTrait::AsyncFnOnce, + traits::FnTrait::AsyncFnMut => FnTrait::AsyncFnMut, + traits::FnTrait::AsyncFn => FnTrait::AsyncFn, + } + } +} + +impl fmt::Display for FnTrait { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FnTrait::FnOnce => write!(f, "FnOnce"), + FnTrait::FnMut => write!(f, "FnMut"), + FnTrait::Fn => write!(f, "Fn"), + FnTrait::AsyncFnOnce => write!(f, "AsyncFnOnce"), + FnTrait::AsyncFnMut => write!(f, "AsyncFnMut"), + FnTrait::AsyncFn => write!(f, "AsyncFn"), + } + } +} + +impl FnTrait { + pub const fn function_name(&self) -> &'static str { + match self { + FnTrait::FnOnce => "call_once", + FnTrait::FnMut => "call_mut", + FnTrait::Fn => "call", + FnTrait::AsyncFnOnce => "async_call_once", + FnTrait::AsyncFnMut => "async_call_mut", + FnTrait::AsyncFn => "async_call", + } + } + + pub fn lang_item(self) -> LangItem { + match self { + FnTrait::FnOnce => LangItem::FnOnce, + FnTrait::FnMut => LangItem::FnMut, + FnTrait::Fn => LangItem::Fn, + FnTrait::AsyncFnOnce => LangItem::AsyncFnOnce, + FnTrait::AsyncFnMut => LangItem::AsyncFnMut, + FnTrait::AsyncFn => LangItem::AsyncFn, + } + } + + pub fn get_id(self, db: &dyn HirDatabase, krate: Crate) -> Option<Trait> { + Trait::lang(db, krate, self.lang_item()) + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct ClosureCapture<'db> { owner: DefWithBodyId, @@ -4821,7 +4805,7 @@ impl<'db> Type<'db> { } fn from_def(db: &'db dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Self { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let ty = db.ty(def.into()); let def = match def.into() { TyDefId::AdtId(it) => GenericDefId::AdtId(it), @@ -4844,7 +4828,7 @@ impl<'db> Type<'db> { db: &'db dyn HirDatabase, def: impl Into<ValueTyDefId> + HasResolver, ) -> Self { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let Some(ty) = db.value_ty(def.into()) else { return Type::new(db, def, Ty::new_error(interner, ErrorGuaranteed)); }; @@ -4900,7 +4884,7 @@ impl<'db> Type<'db> { } pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); return self.ty.visit_with(&mut Visitor { interner }).is_break(); fn is_phantom_data(db: &dyn HirDatabase, adt_id: AdtId) -> bool { @@ -5052,14 +5036,15 @@ impl<'db> Type<'db> { /// `std::future::Future` and returns the `Output` associated type. /// This function is used in `.await` syntax completion. pub fn into_future_output(&self, db: &'db dyn HirDatabase) -> Option<Type<'db>> { - let trait_ = LangItem::IntoFutureIntoFuture - .resolve_function(db, self.env.krate) + let lang_items = hir_def::lang_item::lang_items(db, self.env.krate); + let trait_ = lang_items + .IntoFutureIntoFuture .and_then(|into_future_fn| { let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?; let into_future_trait = assoc_item.container_or_implemented_trait(db)?; Some(into_future_trait.id) }) - .or_else(|| LangItem::Future.resolve_trait(db, self.env.krate))?; + .or(lang_items.Future)?; if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) { return None; @@ -5072,13 +5057,15 @@ impl<'db> Type<'db> { /// This does **not** resolve `IntoFuture`, only `Future`. pub fn future_output(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> { - let future_output = LangItem::FutureOutput.resolve_type_alias(db, self.env.krate)?; + let lang_items = hir_def::lang_item::lang_items(db, self.env.krate); + let future_output = lang_items.FutureOutput?; self.normalize_trait_assoc_type(db, &[], future_output.into()) } /// This does **not** resolve `IntoIterator`, only `Iterator`. pub fn iterator_item(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> { - let iterator_trait = LangItem::Iterator.resolve_trait(db, self.env.krate)?; + let lang_items = hir_def::lang_item::lang_items(db, self.env.krate); + let iterator_trait = lang_items.Iterator?; let iterator_item = iterator_trait .trait_items(db) .associated_type_by_name(&Name::new_symbol_root(sym::Item))?; @@ -5086,7 +5073,8 @@ impl<'db> Type<'db> { } pub fn impls_iterator(self, db: &'db dyn HirDatabase) -> bool { - let Some(iterator_trait) = LangItem::Iterator.resolve_trait(db, self.env.krate) else { + let lang_items = hir_def::lang_item::lang_items(db, self.env.krate); + let Some(iterator_trait) = lang_items.Iterator else { return false; }; traits::implements_trait_unique(self.ty, db, self.env.clone(), iterator_trait) @@ -5094,13 +5082,12 @@ impl<'db> Type<'db> { /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type pub fn into_iterator_iter(self, db: &'db dyn HirDatabase) -> Option<Type<'db>> { - let trait_ = LangItem::IntoIterIntoIter.resolve_function(db, self.env.krate).and_then( - |into_iter_fn| { - let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?; - let into_iter_trait = assoc_item.container_or_implemented_trait(db)?; - Some(into_iter_trait.id) - }, - )?; + let lang_items = hir_def::lang_item::lang_items(db, self.env.krate); + let trait_ = lang_items.IntoIterIntoIter.and_then(|into_iter_fn| { + let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?; + let into_iter_trait = assoc_item.container_or_implemented_trait(db)?; + Some(into_iter_trait.id) + })?; if !traits::implements_trait_unique(self.ty, db, self.env.clone(), trait_) { return None; @@ -5117,7 +5104,8 @@ impl<'db> Type<'db> { /// This function can be used to check if a particular type is callable, since FnOnce is a /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce. pub fn impls_fnonce(&self, db: &'db dyn HirDatabase) -> bool { - let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.env.krate) { + let lang_items = hir_def::lang_item::lang_items(db, self.env.krate); + let fnonce_trait = match lang_items.FnOnce { Some(it) => it, None => return false, }; @@ -5127,7 +5115,7 @@ impl<'db> Type<'db> { // FIXME: Find better API that also handles const generics pub fn impls_trait(&self, db: &'db dyn HirDatabase, trait_: Trait, args: &[Type<'db>]) -> bool { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys( interner, trait_.id.into(), @@ -5142,7 +5130,7 @@ impl<'db> Type<'db> { args: &[Type<'db>], alias: TypeAlias, ) -> Option<Type<'db>> { - let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block); + let interner = DbInterner::new_with(db, self.env.krate); let args = generic_args_from_tys( interner, alias.id.into(), @@ -5161,14 +5149,15 @@ impl<'db> Type<'db> { } pub fn is_copy(&self, db: &'db dyn HirDatabase) -> bool { - let Some(copy_trait) = LangItem::Copy.resolve_trait(db, self.env.krate) else { + let lang_items = hir_def::lang_item::lang_items(db, self.env.krate); + let Some(copy_trait) = lang_items.Copy else { return false; }; self.impls_trait(db, copy_trait.into(), &[]) } pub fn as_callable(&self, db: &'db dyn HirDatabase) -> Option<Callable<'db>> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let callee = match self.ty.kind() { TyKind::Closure(id, subst) => Callee::Closure(id.0, subst), TyKind::CoroutineClosure(id, subst) => Callee::CoroutineClosure(id.0, subst), @@ -5242,7 +5231,7 @@ impl<'db> Type<'db> { } pub fn fields(&self, db: &'db dyn HirDatabase) -> Vec<(Field, Self)> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let (variant_id, substs) = match self.ty.kind() { TyKind::Adt(adt_def, substs) => { let id = match adt_def.def_id().0 { @@ -5299,7 +5288,7 @@ impl<'db> Type<'db> { } fn autoderef_(&self, db: &'db dyn HirDatabase) -> impl Iterator<Item = Ty<'db>> { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); // There should be no inference vars in types passed here let canonical = hir_ty::replace_errors_with_variables(interner, &self.ty); autoderef(db, self.env.clone(), canonical) @@ -5335,7 +5324,7 @@ impl<'db> Type<'db> { } }; - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let Some(simplified_type) = fast_reject::simplify_type(interner, self.ty, fast_reject::TreatParams::AsRigid) else { @@ -5484,7 +5473,7 @@ impl<'db> Type<'db> { f: impl FnOnce(&MethodResolutionContext<'_, 'db>) -> R, ) -> R { let module = resolver.module(); - let interner = DbInterner::new_with(db, Some(module.krate()), module.containing_block()); + let interner = DbInterner::new_with(db, module.krate()); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); let unstable_features = MethodResolutionUnstableFeatures::from_def_map(resolver.top_level_def_map()); @@ -5781,7 +5770,7 @@ impl<'db> Type<'db> { /// Note that we consider placeholder types to unify with everything. /// For example `Option<T>` and `Option<U>` unify although there is unresolved goal `T = U`. pub fn could_unify_with(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty)); hir_ty::could_unify(db, self.env.clone(), &tys) } @@ -5791,13 +5780,13 @@ impl<'db> Type<'db> { /// This means that placeholder types are not considered to unify if there are any bounds set on /// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U` pub fn could_unify_with_deeply(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, other.ty)); hir_ty::could_unify_deeply(db, self.env.clone(), &tys) } pub fn could_coerce_to(&self, db: &'db dyn HirDatabase, to: &Type<'db>) -> bool { - let interner = DbInterner::new_with(db, None, None); + let interner = DbInterner::new_no_crate(db); let tys = hir_ty::replace_errors_with_variables(interner, &(self.ty, to.ty)); hir_ty::could_coerce(db, self.env.clone(), &tys) } @@ -5823,7 +5812,7 @@ impl<'db> Type<'db> { } pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue { - let interner = DbInterner::new_with(db, Some(self.env.krate), self.env.block); + let interner = DbInterner::new_with(db, self.env.krate); let infcx = interner.infer_ctxt().build(TypingMode::PostAnalysis); hir_ty::drop::has_drop_glue(&infcx, self.ty, self.env.clone()) } @@ -5913,7 +5902,7 @@ enum Callee<'db> { Closure(InternedClosureId, GenericArgs<'db>), CoroutineClosure(InternedCoroutineId, GenericArgs<'db>), FnPtr, - FnImpl(FnTrait), + FnImpl(traits::FnTrait), } pub enum CallableKind<'db> { @@ -5940,7 +5929,7 @@ impl<'db> Callable<'db> { CallableKind::Closure(Closure { id: AnyClosureId::CoroutineClosureId(id), subst }) } Callee::FnPtr => CallableKind::FnPtr, - Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_), + Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_.into()), } } pub fn receiver_param(&self, db: &'db dyn HirDatabase) -> Option<(SelfParam, Type<'db>)> { |