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 | 145 |
1 files changed, 107 insertions, 38 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 0cbc75726b..5923a1bc30 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -42,8 +42,8 @@ use arrayvec::ArrayVec; use base_db::{CrateDisplayName, CrateId, CrateOrigin}; use either::Either; use hir_def::{ - body::BodyDiagnostic, data::{adt::VariantData, TraitFlags}, + expr_store::ExpressionStoreDiagnostics, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat}, item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode}, @@ -55,8 +55,8 @@ use hir_def::{ resolver::{HasResolver, Resolver}, type_ref::TypesSourceMap, AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId, - CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FunctionId, - GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId, + CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, + FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, SyntheticSyntax, TraitAliasId, TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, }; @@ -1892,10 +1892,10 @@ impl DefWithBody { for diag in source_map.diagnostics() { acc.push(match diag { - BodyDiagnostic::InactiveCode { node, cfg, opts } => { + ExpressionStoreDiagnostics::InactiveCode { node, cfg, opts } => { InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into() } - BodyDiagnostic::MacroError { node, err } => { + ExpressionStoreDiagnostics::MacroError { node, err } => { let RenderedExpandError { message, error, kind } = err.render_to_string(db.upcast()); @@ -1919,20 +1919,22 @@ impl DefWithBody { } .into() } - BodyDiagnostic::UnresolvedMacroCall { node, path } => UnresolvedMacroCall { - macro_call: (*node).map(|ast_ptr| ast_ptr.into()), - precise_location: None, - path: path.clone(), - is_bang: true, + ExpressionStoreDiagnostics::UnresolvedMacroCall { node, path } => { + UnresolvedMacroCall { + macro_call: (*node).map(|ast_ptr| ast_ptr.into()), + precise_location: None, + path: path.clone(), + is_bang: true, + } + .into() } - .into(), - BodyDiagnostic::AwaitOutsideOfAsync { node, location } => { + ExpressionStoreDiagnostics::AwaitOutsideOfAsync { node, location } => { AwaitOutsideOfAsync { node: *node, location: location.clone() }.into() } - BodyDiagnostic::UnreachableLabel { node, name } => { + ExpressionStoreDiagnostics::UnreachableLabel { node, name } => { UnreachableLabel { node: *node, name: name.clone() }.into() } - BodyDiagnostic::UndeclaredLabel { node, name } => { + ExpressionStoreDiagnostics::UndeclaredLabel { node, name } => { UndeclaredLabel { node: *node, name: name.clone() }.into() } }); @@ -1955,7 +1957,7 @@ impl DefWithBody { ExprOrPatId::PatId(pat) => source_map.pat_syntax(pat).map(Either::Right), }; let expr_or_pat = match expr_or_pat { - Ok(Either::Left(expr)) => expr.map(AstPtr::wrap_left), + Ok(Either::Left(expr)) => expr, Ok(Either::Right(InFile { file_id, value: pat })) => { // cast from Either<Pat, SelfParam> -> Either<_, Pat> let Some(ptr) = AstPtr::try_from_raw(pat.syntax_node_ptr()) else { @@ -1976,16 +1978,40 @@ impl DefWithBody { ); } - let (unsafe_exprs, only_lint) = hir_ty::diagnostics::missing_unsafe(db, self.into()); - for (node, reason) in unsafe_exprs { + let missing_unsafe = hir_ty::diagnostics::missing_unsafe(db, self.into()); + for (node, reason) in missing_unsafe.unsafe_exprs { match source_map.expr_or_pat_syntax(node) { - Ok(node) => acc.push(MissingUnsafe { node, only_lint, reason }.into()), + Ok(node) => acc.push( + MissingUnsafe { + node, + lint: if missing_unsafe.fn_is_unsafe { + UnsafeLint::UnsafeOpInUnsafeFn + } else { + UnsafeLint::HardError + }, + reason, + } + .into(), + ), Err(SyntheticSyntax) => { // FIXME: Here and elsewhere in this file, the `expr` was // desugared, report or assert that this doesn't happen. } } } + for node in missing_unsafe.deprecated_safe_calls { + match source_map.expr_syntax(node) { + Ok(node) => acc.push( + MissingUnsafe { + node, + lint: UnsafeLint::DeprecatedSafe2024, + reason: UnsafetyReason::UnsafeFnCall, + } + .into(), + ), + Err(SyntheticSyntax) => never!("synthetic DeprecatedSafe2024"), + } + } if let Ok(borrowck_results) = db.borrowck(self.into()) { for borrowck_result in borrowck_results.iter() { @@ -2301,6 +2327,13 @@ impl Function { db.function_data(self.id).is_async() } + pub fn extern_block(self, db: &dyn HirDatabase) -> Option<ExternBlock> { + match self.id.lookup(db.upcast()).container { + ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }), + _ => None, + } + } + pub fn returns_impl_future(self, db: &dyn HirDatabase) -> bool { if self.is_async(db) { return true; @@ -2361,8 +2394,19 @@ impl Function { db.attrs(self.id.into()).is_unstable() } - pub fn is_unsafe_to_call(self, db: &dyn HirDatabase) -> bool { - hir_ty::is_fn_unsafe_to_call(db, self.id) + pub fn is_unsafe_to_call( + self, + db: &dyn HirDatabase, + caller: Option<Function>, + call_edition: Edition, + ) -> bool { + let target_features = caller + .map(|caller| hir_ty::TargetFeatures::from_attrs(&db.attrs(caller.id.into()))) + .unwrap_or_default(); + matches!( + hir_ty::is_fn_unsafe_to_call(db, self.id, &target_features, call_edition), + hir_ty::Unsafety::Unsafe + ) } /// Whether this function declaration has a definition. @@ -2724,6 +2768,13 @@ impl Static { Type::from_value_def(db, self.id) } + pub fn extern_block(self, db: &dyn HirDatabase) -> Option<ExternBlock> { + match self.id.lookup(db.upcast()).container { + ItemContainerId::ExternBlockId(id) => Some(ExternBlock { id }), + _ => None, + } + } + /// Evaluate the static initializer. pub fn eval(self, db: &dyn HirDatabase) -> Result<EvaluatedConst, ConstEvalError> { db.const_eval(self.id.into(), Substitution::empty(Interner), None) @@ -2892,6 +2943,17 @@ impl HasVisibility for TypeAlias { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct ExternBlock { + pub(crate) id: ExternBlockId, +} + +impl ExternBlock { + pub fn module(self, db: &dyn HirDatabase) -> Module { + Module { id: self.id.module(db.upcast()) } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StaticLifetime; impl StaticLifetime { @@ -3453,6 +3515,7 @@ pub enum GenericDef { Impl(Impl), // consts can have type parameters from their parents (i.e. associated consts of traits) Const(Const), + Static(Static), } impl_from!( Function, @@ -3461,7 +3524,8 @@ impl_from!( TraitAlias, TypeAlias, Impl, - Const + Const, + Static for GenericDef ); @@ -3511,6 +3575,7 @@ impl GenericDef { GenericDef::TypeAlias(it) => it.id.into(), GenericDef::Impl(it) => it.id.into(), GenericDef::Const(it) => it.id.into(), + GenericDef::Static(it) => it.id.into(), } } @@ -3568,6 +3633,7 @@ impl GenericDef { item_tree_source_maps.impl_(id.value).generics() } GenericDefId::ConstId(_) => return, + GenericDefId::StaticId(_) => return, }, }; @@ -4551,10 +4617,7 @@ impl CaptureUsages { match span { mir::MirSpan::ExprId(expr) => { if let Ok(expr) = source_map.expr_syntax(expr) { - result.push(CaptureUsageSource { - is_ref, - source: expr.map(AstPtr::wrap_left), - }) + result.push(CaptureUsageSource { is_ref, source: expr }) } } mir::MirSpan::PatId(pat) => { @@ -4624,17 +4687,6 @@ impl Type { Type { env: TraitEnvironment::empty(krate), ty } } - pub fn reference(inner: &Type, m: Mutability) -> Type { - inner.derived( - TyKind::Ref( - if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not }, - hir_ty::error_lifetime(), - inner.ty.clone(), - ) - .intern(Interner), - ) - } - fn new(db: &dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Type { let resolver = lexical_env.resolver(db.upcast()); let environment = resolver @@ -4866,6 +4918,17 @@ impl Type { self.normalize_trait_assoc_type(db, &[], iterator_item.into()) } + pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool { + let Some(iterator_trait) = + db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait()) + else { + return false; + }; + let canonical_ty = + Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) }; + method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, iterator_trait) + } + /// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> { let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| { @@ -6139,9 +6202,15 @@ impl HasContainer for TraitAlias { } } +impl HasContainer for ExternBlock { + fn container(&self, db: &dyn HirDatabase) -> ItemContainer { + ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container }) + } +} + fn container_id_to_hir(c: ItemContainerId) -> ItemContainer { match c { - ItemContainerId::ExternBlockId(_id) => ItemContainer::ExternBlock(), + ItemContainerId::ExternBlockId(id) => ItemContainer::ExternBlock(ExternBlock { id }), ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }), ItemContainerId::ImplId(id) => ItemContainer::Impl(Impl { id }), ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }), @@ -6153,7 +6222,7 @@ pub enum ItemContainer { Trait(Trait), Impl(Impl), Module(Module), - ExternBlock(), + ExternBlock(ExternBlock), Crate(CrateId), } |