mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-02 12:59:12 +00:00
Check if PatPtr resolves to ExprId
This commit is contained in:
parent
76b93c0d1f
commit
97251b3e28
4 changed files with 49 additions and 48 deletions
|
|
@ -6,7 +6,7 @@
|
|||
use cfg::{CfgExpr, CfgOptions};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
body::ExprOrPatPtr,
|
||||
expr_store::ExprOrPatPtr,
|
||||
hir::ExprOrPatId,
|
||||
path::{hir_segment_to_ast_segment, ModPath},
|
||||
type_ref::TypesSourceMap,
|
||||
|
|
@ -116,14 +116,14 @@ diagnostics![
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct BreakOutsideOfLoop {
|
||||
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr: InFile<ExprOrPatPtr>,
|
||||
pub is_break: bool,
|
||||
pub bad_value_break: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TypedHole {
|
||||
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr: InFile<ExprOrPatPtr>,
|
||||
pub expected: Type,
|
||||
}
|
||||
|
||||
|
|
@ -222,26 +222,26 @@ pub struct NoSuchField {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct PrivateAssocItem {
|
||||
pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr_or_pat: InFile<ExprOrPatPtr>,
|
||||
pub item: AssocItem,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MismatchedTupleStructPatArgCount {
|
||||
pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr_or_pat: InFile<ExprOrPatPtr>,
|
||||
pub expected: usize,
|
||||
pub found: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExpectedFunction {
|
||||
pub call: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub call: InFile<ExprOrPatPtr>,
|
||||
pub found: Type,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnresolvedField {
|
||||
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr: InFile<ExprOrPatPtr>,
|
||||
pub receiver: Type,
|
||||
pub name: Name,
|
||||
pub method_with_same_name_exists: bool,
|
||||
|
|
@ -249,7 +249,7 @@ pub struct UnresolvedField {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct UnresolvedMethodCall {
|
||||
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr: InFile<ExprOrPatPtr>,
|
||||
pub receiver: Type,
|
||||
pub name: Name,
|
||||
pub field_with_same_name: Option<Type>,
|
||||
|
|
@ -258,17 +258,17 @@ pub struct UnresolvedMethodCall {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct UnresolvedAssocItem {
|
||||
pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr_or_pat: InFile<ExprOrPatPtr>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnresolvedIdent {
|
||||
pub node: InFile<(AstPtr<Either<ast::Expr, ast::Pat>>, Option<TextRange>)>,
|
||||
pub node: InFile<(ExprOrPatPtr, Option<TextRange>)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrivateField {
|
||||
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr: InFile<ExprOrPatPtr>,
|
||||
pub field: Field,
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ pub enum UnsafeLint {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct MissingUnsafe {
|
||||
pub node: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub node: InFile<ExprOrPatPtr>,
|
||||
pub lint: UnsafeLint,
|
||||
pub reason: UnsafetyReason,
|
||||
}
|
||||
|
|
@ -322,7 +322,7 @@ pub struct NonExhaustiveLet {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct TypeMismatch {
|
||||
pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr_or_pat: InFile<ExprOrPatPtr>,
|
||||
pub expected: Type,
|
||||
pub actual: Type,
|
||||
}
|
||||
|
|
@ -396,13 +396,13 @@ pub struct RemoveUnnecessaryElse {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct CastToUnsized {
|
||||
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr: InFile<ExprOrPatPtr>,
|
||||
pub cast_ty: Type,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InvalidCast {
|
||||
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||
pub expr: InFile<ExprOrPatPtr>,
|
||||
pub error: CastError,
|
||||
pub expr_ty: Type,
|
||||
pub cast_ty: Type,
|
||||
|
|
|
|||
|
|
@ -2003,7 +2003,7 @@ impl DefWithBody {
|
|||
match source_map.expr_syntax(node) {
|
||||
Ok(node) => acc.push(
|
||||
MissingUnsafe {
|
||||
node: node.map(|it| it.wrap_left()),
|
||||
node,
|
||||
lint: UnsafeLint::DeprecatedSafe2024,
|
||||
reason: UnsafetyReason::UnsafeFnCall,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,13 +210,20 @@ impl SourceAnalyzer {
|
|||
db: &dyn HirDatabase,
|
||||
pat: &ast::Pat,
|
||||
) -> Option<(Type, Option<Type>)> {
|
||||
let pat_id = self.pat_id(pat)?;
|
||||
let expr_or_pat_id = self.pat_id(pat)?;
|
||||
let infer = self.infer.as_ref()?;
|
||||
let coerced = infer
|
||||
.pat_adjustments
|
||||
.get(&pat_id.as_pat()?)
|
||||
.and_then(|adjusts| adjusts.last().cloned());
|
||||
let ty = infer[pat_id].clone();
|
||||
let coerced = match expr_or_pat_id {
|
||||
ExprOrPatId::ExprId(idx) => infer
|
||||
.expr_adjustments
|
||||
.get(&idx)
|
||||
.and_then(|adjusts| adjusts.last().cloned())
|
||||
.map(|adjust| adjust.target),
|
||||
ExprOrPatId::PatId(idx) => {
|
||||
infer.pat_adjustments.get(&idx).and_then(|adjusts| adjusts.last().cloned())
|
||||
}
|
||||
};
|
||||
|
||||
let ty = infer[expr_or_pat_id].clone();
|
||||
let mk_ty = |ty| Type::new_with_resolver(db, &self.resolver, ty);
|
||||
Some((mk_ty(ty), coerced.map(mk_ty)))
|
||||
}
|
||||
|
|
@ -684,19 +691,18 @@ impl SourceAnalyzer {
|
|||
db: &dyn HirDatabase,
|
||||
pat: &ast::IdentPat,
|
||||
) -> Option<ModuleDef> {
|
||||
let pat_id = self.pat_id(&pat.clone().into())?;
|
||||
let expr_or_pat_id = self.pat_id(&pat.clone().into())?;
|
||||
let body = self.body()?;
|
||||
|
||||
let path = if pat_id.is_pat() {
|
||||
match &body[pat_id.as_pat()?] {
|
||||
Pat::Path(path) => path,
|
||||
_ => return None,
|
||||
}
|
||||
} else {
|
||||
match &body[pat_id.as_expr()?] {
|
||||
let path = match expr_or_pat_id {
|
||||
ExprOrPatId::ExprId(idx) => match &body[idx] {
|
||||
Expr::Path(path) => path,
|
||||
_ => return None,
|
||||
}
|
||||
},
|
||||
ExprOrPatId::PatId(idx) => match &body[idx] {
|
||||
Pat::Path(path) => path,
|
||||
_ => return None,
|
||||
},
|
||||
};
|
||||
|
||||
let res = resolve_hir_path(db, &self.resolver, path, HygieneId::ROOT, TypesMap::EMPTY)?;
|
||||
|
|
@ -793,8 +799,9 @@ 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, subs)) = infer.assoc_resolutions_for_pat(pat_id.as_pat()?) {
|
||||
let expr_or_pat_id = self.pat_id(&path_pat.into())?;
|
||||
if let Some((assoc, subs)) = infer.assoc_resolutions_for_expr_or_pat(expr_or_pat_id)
|
||||
{
|
||||
let (assoc, subst) = match assoc {
|
||||
AssocItemId::ConstId(const_id) => {
|
||||
let (konst, subst) =
|
||||
|
|
@ -818,7 +825,7 @@ impl SourceAnalyzer {
|
|||
return Some((PathResolution::Def(AssocItem::from(assoc).into()), Some(subst)));
|
||||
}
|
||||
if let Some(VariantId::EnumVariantId(variant)) =
|
||||
infer.variant_resolution_for_pat(pat_id.as_pat()?)
|
||||
infer.variant_resolution_for_expr_or_pat(expr_or_pat_id)
|
||||
{
|
||||
return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue