summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/hir
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /src/tools/rust-analyzer/crates/hir
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/rust-analyzer/crates/hir')
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/attrs.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/diagnostics.rs17
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs123
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs134
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs52
6 files changed, 270 insertions, 74 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/src/attrs.rs b/src/tools/rust-analyzer/crates/hir/src/attrs.rs
index 0bd379340..54425d69b 100644
--- a/src/tools/rust-analyzer/crates/hir/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/attrs.rs
@@ -148,7 +148,7 @@ fn resolve_doc_path(
let modpath = {
// FIXME: this is not how we should get a mod path here
- let ast_path = ast::SourceFile::parse(&format!("type T = {};", link))
+ let ast_path = ast::SourceFile::parse(&format!("type T = {link};"))
.syntax_node()
.descendants()
.find_map(ast::Path::cast)?;
diff --git a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
index c5dc60f1e..54d43fa8d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/diagnostics.rs
@@ -10,7 +10,7 @@ use hir_def::path::ModPath;
use hir_expand::{name::Name, HirFileId, InFile};
use syntax::{ast, AstPtr, SyntaxNodePtr, TextRange};
-use crate::{MacroKind, Type};
+use crate::{AssocItem, Field, MacroKind, Type};
macro_rules! diagnostics {
($($diag:ident,)*) => {
@@ -41,6 +41,8 @@ diagnostics![
MissingMatchArms,
MissingUnsafe,
NoSuchField,
+ PrivateAssocItem,
+ PrivateField,
ReplaceFilterMapNextWithFindMap,
TypeMismatch,
UnimplementedBuiltinMacro,
@@ -122,6 +124,19 @@ pub struct NoSuchField {
}
#[derive(Debug)]
+pub struct PrivateAssocItem {
+ pub expr_or_pat:
+ InFile<Either<AstPtr<ast::Expr>, Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>>>,
+ pub item: AssocItem,
+}
+
+#[derive(Debug)]
+pub struct PrivateField {
+ pub expr: InFile<AstPtr<ast::Expr>>,
+ pub field: Field,
+}
+
+#[derive(Debug)]
pub struct BreakOutsideOfLoop {
pub expr: InFile<AstPtr<ast::Expr>>,
pub is_break: bool,
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 27b2f445d..5a4b2f334 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -79,7 +79,7 @@ impl HirDisplay for Function {
}
}
match name {
- Some(name) => write!(f, "{}: ", name)?,
+ Some(name) => write!(f, "{name}: ")?,
None => f.write_str("_: ")?,
}
// FIXME: Use resolved `param.ty` or raw `type_ref`?
@@ -327,7 +327,7 @@ fn write_generic_params(
continue;
}
delim(f)?;
- write!(f, "{}", name)?;
+ write!(f, "{name}")?;
if let Some(default) = &ty.default {
f.write_str(" = ")?;
default.hir_fmt(f)?;
@@ -335,7 +335,7 @@ fn write_generic_params(
}
TypeOrConstParamData::ConstParamData(c) => {
delim(f)?;
- write!(f, "const {}: ", name)?;
+ write!(f, "const {name}: ")?;
c.ty.hir_fmt(f)?;
}
}
@@ -372,7 +372,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter<'_>) -> Result<(),
WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f),
WherePredicateTypeTarget::TypeOrConstParam(id) => {
match &params.type_or_consts[*id].name() {
- Some(name) => write!(f, "{}", name),
+ Some(name) => write!(f, "{name}"),
None => f.write_str("{unnamed}"),
}
}
@@ -424,7 +424,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter<'_>) -> Result<(),
if idx != 0 {
f.write_str(", ")?;
}
- write!(f, "{}", lifetime)?;
+ write!(f, "{lifetime}")?;
}
f.write_str("> ")?;
write_target(target, f)?;
@@ -447,7 +447,7 @@ impl HirDisplay for Const {
let data = f.db.const_data(self.id);
f.write_str("const ")?;
match &data.name {
- Some(name) => write!(f, "{}: ", name)?,
+ Some(name) => write!(f, "{name}: ")?,
None => f.write_str("_: ")?,
}
data.type_ref.hir_fmt(f)?;
@@ -511,9 +511,9 @@ impl HirDisplay for Module {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
// FIXME: Module doesn't have visibility saved in data.
match self.name(f.db) {
- Some(name) => write!(f, "mod {}", name),
+ Some(name) => write!(f, "mod {name}"),
None if self.is_crate_root(f.db) => match self.krate(f.db).display_name(f.db) {
- Some(name) => write!(f, "extern crate {}", name),
+ Some(name) => write!(f, "extern crate {name}"),
None => f.write_str("extern crate {unknown}"),
},
None => f.write_str("mod {unnamed}"),
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index cbbcaebb4..08fd4453d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -39,12 +39,13 @@ use arrayvec::ArrayVec;
use base_db::{CrateDisplayName, CrateId, CrateOrigin, Edition, FileId, ProcMacroKind};
use either::Either;
use hir_def::{
- adt::{ReprData, VariantData},
+ adt::VariantData,
body::{BodyDiagnostic, SyntheticSyntax},
- expr::{BindingAnnotation, LabelId, Pat, PatId},
+ expr::{BindingAnnotation, ExprOrPatId, LabelId, Pat, PatId},
generics::{TypeOrConstParamData, TypeParamProvenance},
item_tree::ItemTreeNode,
lang_item::LangItemTarget,
+ layout::{Layout, LayoutError, ReprOptions},
nameres::{self, diagnostics::DefDiagnostic},
per_ns::PerNs,
resolver::{HasResolver, Resolver},
@@ -59,6 +60,7 @@ use hir_ty::{
all_super_traits, autoderef,
consteval::{unknown_const_as_generic, ComputedExpr, ConstEvalError, ConstExt},
diagnostics::BodyValidationDiagnostic,
+ layout::layout_of_ty,
method_resolution::{self, TyFingerprint},
primitive::UintTy,
traits::FnTrait,
@@ -72,7 +74,7 @@ use once_cell::unsync::Lazy;
use rustc_hash::FxHashSet;
use stdx::{impl_from, never};
use syntax::{
- ast::{self, Expr, HasAttrs as _, HasDocComments, HasName},
+ ast::{self, HasAttrs as _, HasDocComments, HasName},
AstNode, AstPtr, SmolStr, SyntaxNodePtr, TextRange, T,
};
@@ -83,9 +85,10 @@ pub use crate::{
diagnostics::{
AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, InvalidDeriveTarget,
MacroError, MalformedDerive, MismatchedArgCount, MissingFields, MissingMatchArms,
- MissingUnsafe, NoSuchField, ReplaceFilterMapNextWithFindMap, TypeMismatch,
- UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall,
- UnresolvedModule, UnresolvedProcMacro,
+ MissingUnsafe, NoSuchField, PrivateAssocItem, PrivateField,
+ ReplaceFilterMapNextWithFindMap, TypeMismatch, UnimplementedBuiltinMacro,
+ UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, UnresolvedModule,
+ UnresolvedProcMacro,
},
has_source::HasSource,
semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo, VisibleTraits},
@@ -112,12 +115,20 @@ pub use {
path::{ModPath, PathKind},
type_ref::{Mutability, TypeRef},
visibility::Visibility,
+ // FIXME: This is here since it is input of a method in `HirWrite`
+ // and things outside of hir need to implement that trait. We probably
+ // should move whole `hir_ty::display` to this crate so we will become
+ // able to use `ModuleDef` or `Definition` instead of `ModuleDefId`.
+ ModuleDefId,
},
hir_expand::{
name::{known, Name},
ExpandResult, HirFileId, InFile, MacroFile, Origin,
},
- hir_ty::{display::HirDisplay, PointerCast, Safety},
+ hir_ty::{
+ display::{HirDisplay, HirWrite},
+ PointerCast, Safety,
+ },
};
// These are negative re-exports: pub using these names is forbidden, they
@@ -597,7 +608,7 @@ impl Module {
pub fn legacy_macros(self, db: &dyn HirDatabase) -> Vec<Macro> {
let def_map = self.id.def_map(db.upcast());
let scope = &def_map[self.id.local_id].scope;
- scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| MacroId::from(it).into()).collect()
+ scope.legacy_macros().flat_map(|(_, it)| it).map(|&it| it.into()).collect()
}
pub fn impl_defs(self, db: &dyn HirDatabase) -> Vec<Impl> {
@@ -803,7 +814,7 @@ fn precise_macro_call_location(
.doc_comments_and_attrs()
.nth((*invoc_attr_index) as usize)
.and_then(Either::left)
- .unwrap_or_else(|| panic!("cannot find attribute #{}", invoc_attr_index));
+ .unwrap_or_else(|| panic!("cannot find attribute #{invoc_attr_index}"));
(
ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&attr))),
@@ -844,6 +855,10 @@ impl Field {
self.parent.variant_data(db).fields()[self.id].name.clone()
}
+ pub fn index(&self) -> usize {
+ 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.
@@ -859,6 +874,10 @@ impl Field {
Type::new(db, var_id, ty)
}
+ pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
+ layout_of_ty(db, &self.ty(db).ty, self.parent.module(db).krate().into())
+ }
+
pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
self.parent
}
@@ -900,7 +919,7 @@ impl Struct {
Type::from_def(db, self.id)
}
- pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprData> {
+ pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprOptions> {
db.struct_data(self.id).repr.clone()
}
@@ -984,8 +1003,30 @@ impl Enum {
Type::new_for_crate(
self.id.lookup(db.upcast()).container.krate(),
TyBuilder::builtin(match db.enum_data(self.id).variant_body_type() {
- Either::Left(builtin) => hir_def::builtin_type::BuiltinType::Int(builtin),
- Either::Right(builtin) => hir_def::builtin_type::BuiltinType::Uint(builtin),
+ hir_def::layout::IntegerType::Pointer(sign) => match sign {
+ true => hir_def::builtin_type::BuiltinType::Int(
+ hir_def::builtin_type::BuiltinInt::Isize,
+ ),
+ false => hir_def::builtin_type::BuiltinType::Uint(
+ hir_def::builtin_type::BuiltinUint::Usize,
+ ),
+ },
+ hir_def::layout::IntegerType::Fixed(i, sign) => match sign {
+ true => hir_def::builtin_type::BuiltinType::Int(match i {
+ hir_def::layout::Integer::I8 => hir_def::builtin_type::BuiltinInt::I8,
+ hir_def::layout::Integer::I16 => hir_def::builtin_type::BuiltinInt::I16,
+ hir_def::layout::Integer::I32 => hir_def::builtin_type::BuiltinInt::I32,
+ hir_def::layout::Integer::I64 => hir_def::builtin_type::BuiltinInt::I64,
+ hir_def::layout::Integer::I128 => hir_def::builtin_type::BuiltinInt::I128,
+ }),
+ false => hir_def::builtin_type::BuiltinType::Uint(match i {
+ hir_def::layout::Integer::I8 => hir_def::builtin_type::BuiltinUint::U8,
+ hir_def::layout::Integer::I16 => hir_def::builtin_type::BuiltinUint::U16,
+ hir_def::layout::Integer::I32 => hir_def::builtin_type::BuiltinUint::U32,
+ hir_def::layout::Integer::I64 => hir_def::builtin_type::BuiltinUint::U64,
+ hir_def::layout::Integer::I128 => hir_def::builtin_type::BuiltinUint::U128,
+ }),
+ },
}),
)
}
@@ -1042,7 +1083,7 @@ impl Variant {
db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
}
- pub fn value(self, db: &dyn HirDatabase) -> Option<Expr> {
+ pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
self.source(db)?.value.expr()
}
@@ -1076,6 +1117,13 @@ impl Adt {
})
}
+ pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> {
+ if db.generic_params(self.into()).iter().count() != 0 {
+ return Err(LayoutError::HasPlaceholder);
+ }
+ db.layout_of_adt(self.into(), Substitution::empty(Interner))
+ }
+
/// Turns this ADT into a type. Any type parameters of the ADT will be
/// turned into unknown types, which is good for e.g. finding the most
/// general set of completions, but will not look very nice when printed.
@@ -1306,6 +1354,25 @@ impl DefWithBody {
Err(SyntheticSyntax) => (),
}
}
+ &hir_ty::InferenceDiagnostic::PrivateField { expr, field } => {
+ let expr = source_map.expr_syntax(expr).expect("unexpected synthetic");
+ let field = field.into();
+ acc.push(PrivateField { expr, field }.into())
+ }
+ &hir_ty::InferenceDiagnostic::PrivateAssocItem { id, item } => {
+ let expr_or_pat = match id {
+ ExprOrPatId::ExprId(expr) => source_map
+ .expr_syntax(expr)
+ .expect("unexpected synthetic")
+ .map(Either::Left),
+ ExprOrPatId::PatId(pat) => source_map
+ .pat_syntax(pat)
+ .expect("unexpected synthetic")
+ .map(Either::Right),
+ };
+ let item = item.into();
+ acc.push(PrivateAssocItem { expr_or_pat, item }.into())
+ }
}
}
for (expr, mismatch) in infer.expr_type_mismatches() {
@@ -1492,7 +1559,7 @@ impl Function {
}
pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
- self.has_self_param(db).then(|| SelfParam { func: self.id })
+ self.has_self_param(db).then_some(SelfParam { func: self.id })
}
pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
@@ -2344,17 +2411,19 @@ pub struct DeriveHelper {
impl DeriveHelper {
pub fn derive(&self) -> Macro {
- Macro { id: self.derive.into() }
+ Macro { id: self.derive }
}
pub fn name(&self, db: &dyn HirDatabase) -> Name {
match self.derive {
- MacroId::Macro2Id(_) => None,
+ MacroId::Macro2Id(it) => {
+ db.macro2_data(it).helpers.as_deref().and_then(|it| it.get(self.idx)).cloned()
+ }
MacroId::MacroRulesId(_) => None,
MacroId::ProcMacroId(proc_macro) => db
.proc_macro_data(proc_macro)
.helpers
- .as_ref()
+ .as_deref()
.and_then(|it| it.get(self.idx))
.cloned(),
}
@@ -2712,7 +2781,7 @@ impl Impl {
pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
let krate = trait_.module(db).krate();
let mut all = Vec::new();
- for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter() {
+ for Crate { id } in krate.transitive_reverse_dependencies(db) {
let impls = db.trait_impls_in_crate(id);
all.extend(impls.for_trait(trait_.id).map(Self::from))
}
@@ -2857,6 +2926,13 @@ impl Type {
matches!(self.ty.kind(Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
}
+ pub fn is_int_or_uint(&self) -> bool {
+ match self.ty.kind(Interner) {
+ TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_)) => true,
+ _ => false,
+ }
+ }
+
pub fn remove_ref(&self) -> Option<Type> {
match &self.ty.kind(Interner) {
TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
@@ -3031,7 +3107,7 @@ impl Type {
let adt = adt_id.into();
match adt {
- Adt::Struct(s) => matches!(s.repr(db), Some(ReprData { packed: true, .. })),
+ Adt::Struct(s) => s.repr(db).unwrap_or_default().pack.is_some(),
_ => false,
}
}
@@ -3225,7 +3301,7 @@ impl Type {
with_local_impls.and_then(|b| b.id.containing_block()).into(),
name,
method_resolution::LookupMode::MethodCall,
- &mut |_adj, id| callback(id),
+ &mut |_adj, id, _| callback(id),
);
}
@@ -3650,6 +3726,13 @@ impl From<ItemInNs> for ScopeDef {
}
}
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Adjustment {
+ pub source: Type,
+ pub target: Type,
+ pub kind: Adjust,
+}
+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Adjust {
/// Go from ! to any type.
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index 2e1f88ba0..e0d261039 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -2,14 +2,17 @@
mod source_to_def;
-use std::{cell::RefCell, fmt, iter, ops};
+use std::{cell::RefCell, fmt, iter, mem, ops};
use base_db::{FileId, FileRange};
+use either::Either;
use hir_def::{
- body, macro_id_to_def_id,
+ body,
+ expr::Expr,
+ macro_id_to_def_id,
resolver::{self, HasResolver, Resolver, TypeNs},
type_ref::Mutability,
- AsMacroCall, FunctionId, MacroId, TraitId, VariantId,
+ AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
};
use hir_expand::{
db::AstDatabase,
@@ -29,7 +32,7 @@ use crate::{
db::HirDatabase,
semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
source_analyzer::{resolve_hir_path, SourceAnalyzer},
- Access, Adjust, AutoBorrow, BindingMode, BuiltinAttr, Callable, ConstParam, Crate,
+ Access, Adjust, Adjustment, AutoBorrow, BindingMode, BuiltinAttr, Callable, ConstParam, Crate,
DeriveHelper, Field, Function, HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local,
Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef, ToolModule, Trait, Type,
TypeAlias, TypeParam, VariantDef,
@@ -334,7 +337,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
self.imp.resolve_trait(trait_)
}
- pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
+ pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment>> {
self.imp.expr_adjustments(expr)
}
@@ -438,8 +441,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
}
pub fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
- let src = self.imp.find_file(src.syntax()).with_value(src).cloned();
- T::to_def(&self.imp, src)
+ self.imp.to_def(src)
}
pub fn to_module_def(&self, file: FileId) -> Option<Module> {
@@ -481,6 +483,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
pub fn is_unsafe_ident_pat(&self, ident_pat: &ast::IdentPat) -> bool {
self.imp.is_unsafe_ident_pat(ident_pat)
}
+
+ /// Returns `true` if the `node` is inside an `unsafe` context.
+ pub fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
+ self.imp.is_inside_unsafe(expr)
+ }
}
impl<'db> SemanticsImpl<'db> {
@@ -788,7 +795,7 @@ impl<'db> SemanticsImpl<'db> {
// requeue the tokens we got from mapping our current token down
stack.extend(mapped_tokens);
// if the length changed we have found a mapping for the token
- (stack.len() != len).then(|| ())
+ (stack.len() != len).then_some(())
};
// Remap the next token in the queue into a macro call its in, if it is not being remapped
@@ -840,7 +847,7 @@ impl<'db> SemanticsImpl<'db> {
}
};
process_expansion_for_token(&mut stack, file_id, None, token.as_ref())
- } else if let Some(meta) = ast::Meta::cast(parent.clone()) {
+ } else if let Some(meta) = ast::Meta::cast(parent) {
// attribute we failed expansion for earlier, this might be a derive invocation
// or derive helper attribute
let attr = meta.parent_attr()?;
@@ -1067,26 +1074,42 @@ impl<'db> SemanticsImpl<'db> {
}
}
- fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjust>> {
+ fn expr_adjustments(&self, expr: &ast::Expr) -> Option<Vec<Adjustment>> {
let mutability = |m| match m {
hir_ty::Mutability::Not => Mutability::Shared,
hir_ty::Mutability::Mut => Mutability::Mut,
};
- self.analyze(expr.syntax())?.expr_adjustments(self.db, expr).map(|it| {
+
+ let analyzer = self.analyze(expr.syntax())?;
+
+ let (mut source_ty, _) = analyzer.type_of_expr(self.db, expr)?;
+
+ analyzer.expr_adjustments(self.db, expr).map(|it| {
it.iter()
- .map(|adjust| match adjust.kind {
- hir_ty::Adjust::NeverToAny => Adjust::NeverToAny,
- hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => {
- Adjust::Deref(Some(OverloadedDeref(mutability(m))))
- }
- hir_ty::Adjust::Deref(None) => Adjust::Deref(None),
- hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::RawPtr(m)) => {
- Adjust::Borrow(AutoBorrow::RawPtr(mutability(m)))
- }
- hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(m)) => {
- Adjust::Borrow(AutoBorrow::Ref(mutability(m)))
- }
- hir_ty::Adjust::Pointer(pc) => Adjust::Pointer(pc),
+ .map(|adjust| {
+ let target =
+ Type::new_with_resolver(self.db, &analyzer.resolver, adjust.target.clone());
+ let kind = match adjust.kind {
+ hir_ty::Adjust::NeverToAny => Adjust::NeverToAny,
+ hir_ty::Adjust::Deref(Some(hir_ty::OverloadedDeref(m))) => {
+ Adjust::Deref(Some(OverloadedDeref(mutability(m))))
+ }
+ hir_ty::Adjust::Deref(None) => Adjust::Deref(None),
+ hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::RawPtr(m)) => {
+ Adjust::Borrow(AutoBorrow::RawPtr(mutability(m)))
+ }
+ hir_ty::Adjust::Borrow(hir_ty::AutoBorrow::Ref(m)) => {
+ Adjust::Borrow(AutoBorrow::Ref(mutability(m)))
+ }
+ hir_ty::Adjust::Pointer(pc) => Adjust::Pointer(pc),
+ };
+
+ // Update `source_ty` for the next adjustment
+ let source = mem::replace(&mut source_ty, target.clone());
+
+ let adjustment = Adjustment { source, target, kind };
+
+ adjustment
})
.collect()
})
@@ -1198,7 +1221,7 @@ impl<'db> SemanticsImpl<'db> {
krate
.dependencies(self.db)
.into_iter()
- .find_map(|dep| (dep.name == name).then(|| dep.krate))
+ .find_map(|dep| (dep.name == name).then_some(dep.krate))
}
fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> {
@@ -1223,10 +1246,15 @@ impl<'db> SemanticsImpl<'db> {
fn with_ctx<F: FnOnce(&mut SourceToDefCtx<'_, '_>) -> T, T>(&self, f: F) -> T {
let mut cache = self.s2d_cache.borrow_mut();
- let mut ctx = SourceToDefCtx { db: self.db, cache: &mut *cache };
+ let mut ctx = SourceToDefCtx { db: self.db, cache: &mut cache };
f(&mut ctx)
}
+ fn to_def<T: ToDef>(&self, src: &T) -> Option<T::Def> {
+ let src = self.find_file(src.syntax()).with_value(src).cloned();
+ T::to_def(self, src)
+ }
+
fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> {
self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
}
@@ -1350,7 +1378,7 @@ impl<'db> SemanticsImpl<'db> {
self.cache
.borrow()
.keys()
- .map(|it| format!("{:?}", it))
+ .map(|it| format!("{it:?}"))
.collect::<Vec<_>>()
.join(", ")
)
@@ -1442,6 +1470,56 @@ impl<'db> SemanticsImpl<'db> {
.map(|ty| ty.original.is_packed(self.db))
.unwrap_or(false)
}
+
+ fn is_inside_unsafe(&self, expr: &ast::Expr) -> bool {
+ let item_or_variant = |ancestor: SyntaxNode| {
+ if ast::Item::can_cast(ancestor.kind()) {
+ ast::Item::cast(ancestor).map(Either::Left)
+ } else {
+ ast::Variant::cast(ancestor).map(Either::Right)
+ }
+ };
+ let Some(enclosing_item) = expr.syntax().ancestors().find_map(item_or_variant) else { return false };
+
+ let def = match &enclosing_item {
+ Either::Left(ast::Item::Fn(it)) if it.unsafe_token().is_some() => return true,
+ Either::Left(ast::Item::Fn(it)) => {
+ self.to_def(it).map(<_>::into).map(DefWithBodyId::FunctionId)
+ }
+ Either::Left(ast::Item::Const(it)) => {
+ self.to_def(it).map(<_>::into).map(DefWithBodyId::ConstId)
+ }
+ Either::Left(ast::Item::Static(it)) => {
+ self.to_def(it).map(<_>::into).map(DefWithBodyId::StaticId)
+ }
+ Either::Left(_) => None,
+ Either::Right(it) => self.to_def(it).map(<_>::into).map(DefWithBodyId::VariantId),
+ };
+ let Some(def) = def else { return false };
+ let enclosing_node = enclosing_item.as_ref().either(|i| i.syntax(), |v| v.syntax());
+
+ let (body, source_map) = self.db.body_with_source_map(def);
+
+ let file_id = self.find_file(expr.syntax()).file_id;
+
+ let Some(mut parent) = expr.syntax().parent() else { return false };
+ loop {
+ if &parent == enclosing_node {
+ break false;
+ }
+
+ if let Some(parent) = ast::Expr::cast(parent.clone()) {
+ if let Some(expr_id) = source_map.node_expr(InFile { file_id, value: &parent }) {
+ if let Expr::Unsafe { .. } = body[expr_id] {
+ break true;
+ }
+ }
+ }
+
+ let Some(parent_) = parent.parent() else { break false };
+ parent = parent_;
+ }
+ }
}
fn macro_call_to_macro_id(
@@ -1600,7 +1678,7 @@ impl<'a> SemanticsScope<'a> {
self.db,
def,
resolution.in_type_ns()?,
- |name, _, id| cb(name, id.into()),
+ |name, id| cb(name, id.into()),
)
}
}
diff --git a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
index 91ea1c24d..059b80bcf 100644
--- a/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/source_analyzer.rs
@@ -21,8 +21,8 @@ use hir_def::{
path::{ModPath, Path, PathKind},
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
type_ref::Mutability,
- AsMacroCall, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, LocalFieldId,
- Lookup, ModuleDefId, TraitId, VariantId,
+ AsMacroCall, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, ItemContainerId,
+ LocalFieldId, Lookup, ModuleDefId, TraitId, VariantId,
};
use hir_expand::{
builtin_fn_macro::BuiltinFnLikeExpander,
@@ -118,7 +118,7 @@ impl SourceAnalyzer {
fn expr_id(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<ExprId> {
let src = match expr {
ast::Expr::MacroExpr(expr) => {
- self.expand_expr(db, InFile::new(self.file_id, expr.macro_call()?.clone()))?
+ self.expand_expr(db, InFile::new(self.file_id, expr.macro_call()?))?
}
_ => InFile::new(self.file_id, expr.clone()),
};
@@ -228,7 +228,7 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
pat: &ast::Pat,
) -> Option<SmallVec<[Type; 1]>> {
- let pat_id = self.pat_id(&pat)?;
+ let pat_id = self.pat_id(pat)?;
let infer = self.infer.as_ref()?;
Some(
infer
@@ -270,7 +270,7 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
await_expr: &ast::AwaitExpr,
) -> Option<FunctionId> {
- let mut ty = self.ty_of_expr(db, &await_expr.expr()?.into())?.clone();
+ let mut ty = self.ty_of_expr(db, &await_expr.expr()?)?.clone();
let into_future_trait = self
.resolver
@@ -316,7 +316,7 @@ impl SourceAnalyzer {
ast::UnaryOp::Not => name![not],
ast::UnaryOp::Neg => name![neg],
};
- let ty = self.ty_of_expr(db, &prefix_expr.expr()?.into())?;
+ let ty = self.ty_of_expr(db, &prefix_expr.expr()?)?;
let (op_trait, op_fn) = self.lang_trait_fn(db, &lang_item_name, &lang_item_name)?;
// HACK: subst for all methods coincides with that for their trait because the methods
@@ -331,8 +331,8 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
index_expr: &ast::IndexExpr,
) -> Option<FunctionId> {
- let base_ty = self.ty_of_expr(db, &index_expr.base()?.into())?;
- let index_ty = self.ty_of_expr(db, &index_expr.index()?.into())?;
+ let base_ty = self.ty_of_expr(db, &index_expr.base()?)?;
+ let index_ty = self.ty_of_expr(db, &index_expr.index()?)?;
let lang_item_name = name![index];
@@ -352,8 +352,8 @@ impl SourceAnalyzer {
binop_expr: &ast::BinExpr,
) -> Option<FunctionId> {
let op = binop_expr.op_kind()?;
- let lhs = self.ty_of_expr(db, &binop_expr.lhs()?.into())?;
- let rhs = self.ty_of_expr(db, &binop_expr.rhs()?.into())?;
+ let lhs = self.ty_of_expr(db, &binop_expr.lhs()?)?;
+ let rhs = self.ty_of_expr(db, &binop_expr.rhs()?)?;
let (op_trait, op_fn) = lang_names_for_bin_op(op)
.and_then(|(name, lang_item)| self.lang_trait_fn(db, &lang_item, &name))?;
@@ -372,7 +372,7 @@ impl SourceAnalyzer {
db: &dyn HirDatabase,
try_expr: &ast::TryExpr,
) -> Option<FunctionId> {
- let ty = self.ty_of_expr(db, &try_expr.expr()?.into())?;
+ let ty = self.ty_of_expr(db, &try_expr.expr()?)?;
let op_fn =
db.lang_item(self.resolver.krate(), name![branch].to_smol_str())?.as_function()?;
@@ -482,7 +482,7 @@ impl SourceAnalyzer {
let infer = self.infer.as_deref()?;
if let Some(path_expr) = parent().and_then(ast::PathExpr::cast) {
let expr_id = self.expr_id(db, &path_expr.into())?;
- if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
+ if let Some((assoc, subs)) = infer.assoc_resolutions_for_expr(expr_id) {
let assoc = match assoc {
AssocItemId::FunctionId(f_in_trait) => {
match infer.type_of_expr.get(expr_id) {
@@ -501,7 +501,9 @@ impl SourceAnalyzer {
}
}
}
-
+ AssocItemId::ConstId(const_id) => {
+ self.resolve_impl_const_or_trait_def(db, const_id, subs).into()
+ }
_ => assoc,
};
@@ -515,7 +517,7 @@ impl SourceAnalyzer {
prefer_value_ns = true;
} else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
let pat_id = self.pat_id(&path_pat.into())?;
- if let Some(assoc) = infer.assoc_resolutions_for_pat(pat_id) {
+ if let Some((assoc, _)) = infer.assoc_resolutions_for_pat(pat_id) {
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
}
if let Some(VariantId::EnumVariantId(variant)) =
@@ -792,6 +794,24 @@ impl SourceAnalyzer {
method_resolution::lookup_impl_method(db, env, func, substs)
}
+ fn resolve_impl_const_or_trait_def(
+ &self,
+ db: &dyn HirDatabase,
+ const_id: ConstId,
+ subs: Substitution,
+ ) -> ConstId {
+ let krate = self.resolver.krate();
+ let owner = match self.resolver.body_owner() {
+ Some(it) => it,
+ None => return const_id,
+ };
+ let env = owner.as_generic_def_id().map_or_else(
+ || Arc::new(hir_ty::TraitEnvironment::empty(krate)),
+ |d| db.trait_environment(d),
+ );
+ method_resolution::lookup_impl_const(db, env, const_id, subs)
+ }
+
fn lang_trait_fn(
&self,
db: &dyn HirDatabase,
@@ -804,7 +824,7 @@ impl SourceAnalyzer {
}
fn ty_of_expr(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<&Ty> {
- self.infer.as_ref()?.type_of_expr.get(self.expr_id(db, &expr)?)
+ self.infer.as_ref()?.type_of_expr.get(self.expr_id(db, expr)?)
}
}
@@ -967,7 +987,7 @@ fn resolve_hir_path_(
db,
def,
res.in_type_ns()?,
- |name, _, id| (name == unresolved.name).then(|| id),
+ |name, id| (name == unresolved.name).then_some(id),
)
})
.map(TypeAlias::from)