mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-01 12:24:29 +00:00
Make higher levels adapt Bodys exprs having ExprOrPatId values
This commit is contained in:
parent
06097c3388
commit
d8779b4a0e
8 changed files with 32 additions and 33 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
|
body::ExprOrPatPtr,
|
||||||
hir::ExprOrPatId,
|
hir::ExprOrPatId,
|
||||||
path::{hir_segment_to_ast_segment, ModPath},
|
path::{hir_segment_to_ast_segment, ModPath},
|
||||||
type_ref::TypesSourceMap,
|
type_ref::TypesSourceMap,
|
||||||
|
|
@ -115,14 +116,14 @@ diagnostics![
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BreakOutsideOfLoop {
|
pub struct BreakOutsideOfLoop {
|
||||||
pub expr: InFile<AstPtr<ast::Expr>>,
|
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub is_break: bool,
|
pub is_break: bool,
|
||||||
pub bad_value_break: bool,
|
pub bad_value_break: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TypedHole {
|
pub struct TypedHole {
|
||||||
pub expr: InFile<AstPtr<ast::Expr>>,
|
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub expected: Type,
|
pub expected: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,13 +235,13 @@ pub struct MismatchedTupleStructPatArgCount {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExpectedFunction {
|
pub struct ExpectedFunction {
|
||||||
pub call: InFile<AstPtr<ast::Expr>>,
|
pub call: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub found: Type,
|
pub found: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UnresolvedField {
|
pub struct UnresolvedField {
|
||||||
pub expr: InFile<AstPtr<ast::Expr>>,
|
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub receiver: Type,
|
pub receiver: Type,
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
pub method_with_same_name_exists: bool,
|
pub method_with_same_name_exists: bool,
|
||||||
|
|
@ -248,7 +249,7 @@ pub struct UnresolvedField {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UnresolvedMethodCall {
|
pub struct UnresolvedMethodCall {
|
||||||
pub expr: InFile<AstPtr<ast::Expr>>,
|
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub receiver: Type,
|
pub receiver: Type,
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
pub field_with_same_name: Option<Type>,
|
pub field_with_same_name: Option<Type>,
|
||||||
|
|
@ -267,7 +268,7 @@ pub struct UnresolvedIdent {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PrivateField {
|
pub struct PrivateField {
|
||||||
pub expr: InFile<AstPtr<ast::Expr>>,
|
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub field: Field,
|
pub field: Field,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -302,7 +303,7 @@ pub struct ReplaceFilterMapNextWithFindMap {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MismatchedArgCount {
|
pub struct MismatchedArgCount {
|
||||||
pub call_expr: InFile<AstPtr<ast::Expr>>,
|
pub call_expr: InFile<ExprOrPatPtr>,
|
||||||
pub expected: usize,
|
pub expected: usize,
|
||||||
pub found: usize,
|
pub found: usize,
|
||||||
}
|
}
|
||||||
|
|
@ -395,13 +396,13 @@ pub struct RemoveUnnecessaryElse {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CastToUnsized {
|
pub struct CastToUnsized {
|
||||||
pub expr: InFile<AstPtr<ast::Expr>>,
|
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub cast_ty: Type,
|
pub cast_ty: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InvalidCast {
|
pub struct InvalidCast {
|
||||||
pub expr: InFile<AstPtr<ast::Expr>>,
|
pub expr: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
pub error: CastError,
|
pub error: CastError,
|
||||||
pub expr_ty: Type,
|
pub expr_ty: Type,
|
||||||
pub cast_ty: Type,
|
pub cast_ty: Type,
|
||||||
|
|
@ -428,9 +429,7 @@ impl AnyDiagnostic {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let record = match record {
|
let record = match record {
|
||||||
Either::Left(record_expr) => {
|
Either::Left(record_expr) => source_map.expr_syntax(record_expr).ok()?,
|
||||||
source_map.expr_syntax(record_expr).ok()?.map(AstPtr::wrap_left)
|
|
||||||
}
|
|
||||||
Either::Right(record_pat) => source_map.pat_syntax(record_pat).ok()?,
|
Either::Right(record_pat) => source_map.pat_syntax(record_pat).ok()?,
|
||||||
};
|
};
|
||||||
let file = record.file_id;
|
let file = record.file_id;
|
||||||
|
|
@ -474,7 +473,7 @@ impl AnyDiagnostic {
|
||||||
return Some(
|
return Some(
|
||||||
ReplaceFilterMapNextWithFindMap {
|
ReplaceFilterMapNextWithFindMap {
|
||||||
file: next_source_ptr.file_id,
|
file: next_source_ptr.file_id,
|
||||||
next_expr: next_source_ptr.value,
|
next_expr: next_source_ptr.value.cast()?,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -484,7 +483,9 @@ impl AnyDiagnostic {
|
||||||
match source_map.expr_syntax(match_expr) {
|
match source_map.expr_syntax(match_expr) {
|
||||||
Ok(source_ptr) => {
|
Ok(source_ptr) => {
|
||||||
let root = source_ptr.file_syntax(db.upcast());
|
let root = source_ptr.file_syntax(db.upcast());
|
||||||
if let ast::Expr::MatchExpr(match_expr) = &source_ptr.value.to_node(&root) {
|
if let Either::Left(ast::Expr::MatchExpr(match_expr)) =
|
||||||
|
&source_ptr.value.to_node(&root)
|
||||||
|
{
|
||||||
match match_expr.expr() {
|
match match_expr.expr() {
|
||||||
Some(scrut_expr) if match_expr.match_arm_list().is_some() => {
|
Some(scrut_expr) if match_expr.match_arm_list().is_some() => {
|
||||||
return Some(
|
return Some(
|
||||||
|
|
@ -561,7 +562,7 @@ impl AnyDiagnostic {
|
||||||
let pat_syntax =
|
let pat_syntax =
|
||||||
|pat| source_map.pat_syntax(pat).inspect_err(|_| stdx::never!("synthetic syntax")).ok();
|
|pat| source_map.pat_syntax(pat).inspect_err(|_| stdx::never!("synthetic syntax")).ok();
|
||||||
let expr_or_pat_syntax = |id| match id {
|
let expr_or_pat_syntax = |id| match id {
|
||||||
ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(|it| it.map(AstPtr::wrap_left)),
|
ExprOrPatId::ExprId(expr) => expr_syntax(expr),
|
||||||
ExprOrPatId::PatId(pat) => pat_syntax(pat),
|
ExprOrPatId::PatId(pat) => pat_syntax(pat),
|
||||||
};
|
};
|
||||||
Some(match d {
|
Some(match d {
|
||||||
|
|
@ -633,7 +634,7 @@ impl AnyDiagnostic {
|
||||||
&InferenceDiagnostic::UnresolvedIdent { id } => {
|
&InferenceDiagnostic::UnresolvedIdent { id } => {
|
||||||
let node = match id {
|
let node = match id {
|
||||||
ExprOrPatId::ExprId(id) => match source_map.expr_syntax(id) {
|
ExprOrPatId::ExprId(id) => match source_map.expr_syntax(id) {
|
||||||
Ok(syntax) => syntax.map(|it| (it.wrap_left(), None)),
|
Ok(syntax) => syntax.map(|it| (it, None)),
|
||||||
Err(SyntheticSyntax) => source_map
|
Err(SyntheticSyntax) => source_map
|
||||||
.format_args_implicit_capture(id)?
|
.format_args_implicit_capture(id)?
|
||||||
.map(|(node, range)| (node.wrap_left(), Some(range))),
|
.map(|(node, range)| (node.wrap_left(), Some(range))),
|
||||||
|
|
@ -652,7 +653,7 @@ impl AnyDiagnostic {
|
||||||
}
|
}
|
||||||
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
|
&InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
|
||||||
let expr_or_pat = match pat {
|
let expr_or_pat = match pat {
|
||||||
ExprOrPatId::ExprId(expr) => expr_syntax(expr)?.map(AstPtr::wrap_left),
|
ExprOrPatId::ExprId(expr) => expr_syntax(expr)?,
|
||||||
ExprOrPatId::PatId(pat) => {
|
ExprOrPatId::PatId(pat) => {
|
||||||
let InFile { file_id, value } = pat_syntax(pat)?;
|
let InFile { file_id, value } = pat_syntax(pat)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ impl HasSource for Param {
|
||||||
let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?;
|
let ast @ InFile { file_id, value } = source_map.expr_syntax(expr_id).ok()?;
|
||||||
let root = db.parse_or_expand(file_id);
|
let root = db.parse_or_expand(file_id);
|
||||||
match value.to_node(&root) {
|
match value.to_node(&root) {
|
||||||
ast::Expr::ClosureExpr(it) => it
|
Either::Left(ast::Expr::ClosureExpr(it)) => it
|
||||||
.param_list()?
|
.param_list()?
|
||||||
.params()
|
.params()
|
||||||
.nth(self.idx)
|
.nth(self.idx)
|
||||||
|
|
@ -301,7 +301,7 @@ impl HasSource for InlineAsmOperand {
|
||||||
let root = src.file_syntax(db.upcast());
|
let root = src.file_syntax(db.upcast());
|
||||||
return src
|
return src
|
||||||
.map(|ast| match ast.to_node(&root) {
|
.map(|ast| match ast.to_node(&root) {
|
||||||
ast::Expr::AsmExpr(asm) => asm
|
Either::Left(ast::Expr::AsmExpr(asm)) => asm
|
||||||
.asm_pieces()
|
.asm_pieces()
|
||||||
.filter_map(|it| match it {
|
.filter_map(|it| match it {
|
||||||
ast::AsmPiece::AsmOperandNamed(it) => Some(it),
|
ast::AsmPiece::AsmOperandNamed(it) => Some(it),
|
||||||
|
|
|
||||||
|
|
@ -1957,7 +1957,7 @@ impl DefWithBody {
|
||||||
ExprOrPatId::PatId(pat) => source_map.pat_syntax(pat).map(Either::Right),
|
ExprOrPatId::PatId(pat) => source_map.pat_syntax(pat).map(Either::Right),
|
||||||
};
|
};
|
||||||
let expr_or_pat = match expr_or_pat {
|
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 })) => {
|
Ok(Either::Right(InFile { file_id, value: pat })) => {
|
||||||
// cast from Either<Pat, SelfParam> -> Either<_, Pat>
|
// cast from Either<Pat, SelfParam> -> Either<_, Pat>
|
||||||
let Some(ptr) = AstPtr::try_from_raw(pat.syntax_node_ptr()) else {
|
let Some(ptr) = AstPtr::try_from_raw(pat.syntax_node_ptr()) else {
|
||||||
|
|
@ -4592,10 +4592,7 @@ impl CaptureUsages {
|
||||||
match span {
|
match span {
|
||||||
mir::MirSpan::ExprId(expr) => {
|
mir::MirSpan::ExprId(expr) => {
|
||||||
if let Ok(expr) = source_map.expr_syntax(expr) {
|
if let Ok(expr) = source_map.expr_syntax(expr) {
|
||||||
result.push(CaptureUsageSource {
|
result.push(CaptureUsageSource { is_ref, source: expr })
|
||||||
is_ref,
|
|
||||||
source: expr.map(AstPtr::wrap_left),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mir::MirSpan::PatId(pat) => {
|
mir::MirSpan::PatId(pat) => {
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ impl SourceToDefCtx<'_, '_> {
|
||||||
let src = src.cloned().map(ast::Pat::from);
|
let src = src.cloned().map(ast::Pat::from);
|
||||||
let pat_id = source_map.node_pat(src.as_ref())?;
|
let pat_id = source_map.node_pat(src.as_ref())?;
|
||||||
// the pattern could resolve to a constant, verify that this is not the case
|
// the pattern could resolve to a constant, verify that this is not the case
|
||||||
if let crate::Pat::Bind { id, .. } = body[pat_id] {
|
if let crate::Pat::Bind { id, .. } = body[pat_id.as_pat()?] {
|
||||||
Some((container, id))
|
Some((container, id))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ impl SourceAnalyzer {
|
||||||
fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
|
fn pat_id(&self, pat: &ast::Pat) -> Option<PatId> {
|
||||||
// FIXME: macros, see `expr_id`
|
// FIXME: macros, see `expr_id`
|
||||||
let src = InFile { file_id: self.file_id, value: pat };
|
let src = InFile { file_id: self.file_id, value: pat };
|
||||||
self.body_source_map()?.node_pat(src)
|
self.body_source_map()?.node_pat(src).and_then(ExprOrPatId::as_pat)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binding_id_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingId> {
|
fn binding_id_of_pat(&self, pat: &ast::IdentPat) -> Option<BindingId> {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ pub(crate) fn mismatched_arg_count(
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
DiagnosticCode::RustcHardError("E0107"),
|
DiagnosticCode::RustcHardError("E0107"),
|
||||||
message,
|
message,
|
||||||
invalid_args_range(ctx, d.call_expr.map(AstPtr::wrap_left), d.expected, d.found),
|
invalid_args_range(ctx, d.call_expr, d.expected, d.found),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
use either::Either;
|
||||||
use hir::{db::ExpandDatabase, Adt, FileRange, HasSource, HirDisplay, InFile, Struct, Union};
|
use hir::{db::ExpandDatabase, Adt, FileRange, HasSource, HirDisplay, InFile, Struct, Union};
|
||||||
use ide_db::text_edit::TextEdit;
|
use ide_db::text_edit::TextEdit;
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
|
|
@ -41,7 +42,7 @@ pub(crate) fn unresolved_field(
|
||||||
),
|
),
|
||||||
adjusted_display_range(ctx, d.expr, &|expr| {
|
adjusted_display_range(ctx, d.expr, &|expr| {
|
||||||
Some(
|
Some(
|
||||||
match expr {
|
match expr.left()? {
|
||||||
ast::Expr::MethodCallExpr(it) => it.name_ref(),
|
ast::Expr::MethodCallExpr(it) => it.name_ref(),
|
||||||
ast::Expr::FieldExpr(it) => it.name_ref(),
|
ast::Expr::FieldExpr(it) => it.name_ref(),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
@ -72,7 +73,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option<Vec<A
|
||||||
fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option<Assist> {
|
fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option<Assist> {
|
||||||
// Get the FileRange of the invalid field access
|
// Get the FileRange of the invalid field access
|
||||||
let root = ctx.sema.db.parse_or_expand(d.expr.file_id);
|
let root = ctx.sema.db.parse_or_expand(d.expr.file_id);
|
||||||
let expr = d.expr.value.to_node(&root);
|
let expr = d.expr.value.to_node(&root).left()?;
|
||||||
|
|
||||||
let error_range = ctx.sema.original_range_opt(expr.syntax())?;
|
let error_range = ctx.sema.original_range_opt(expr.syntax())?;
|
||||||
let field_name = d.name.as_str();
|
let field_name = d.name.as_str();
|
||||||
|
|
@ -263,7 +264,7 @@ fn record_field_layout(
|
||||||
// FIXME: We should fill out the call here, move the cursor and trigger signature help
|
// FIXME: We should fill out the call here, move the cursor and trigger signature help
|
||||||
fn method_fix(
|
fn method_fix(
|
||||||
ctx: &DiagnosticsContext<'_>,
|
ctx: &DiagnosticsContext<'_>,
|
||||||
expr_ptr: &InFile<AstPtr<ast::Expr>>,
|
expr_ptr: &InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
|
||||||
) -> Option<Assist> {
|
) -> Option<Assist> {
|
||||||
let root = ctx.sema.db.parse_or_expand(expr_ptr.file_id);
|
let root = ctx.sema.db.parse_or_expand(expr_ptr.file_id);
|
||||||
let expr = expr_ptr.value.to_node(&root);
|
let expr = expr_ptr.value.to_node(&root);
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ pub(crate) fn unresolved_method(
|
||||||
),
|
),
|
||||||
adjusted_display_range(ctx, d.expr, &|expr| {
|
adjusted_display_range(ctx, d.expr, &|expr| {
|
||||||
Some(
|
Some(
|
||||||
match expr {
|
match expr.left()? {
|
||||||
ast::Expr::MethodCallExpr(it) => it.name_ref(),
|
ast::Expr::MethodCallExpr(it) => it.name_ref(),
|
||||||
ast::Expr::FieldExpr(it) => it.name_ref(),
|
ast::Expr::FieldExpr(it) => it.name_ref(),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
@ -85,7 +85,7 @@ fn field_fix(
|
||||||
let expr_ptr = &d.expr;
|
let expr_ptr = &d.expr;
|
||||||
let root = ctx.sema.db.parse_or_expand(expr_ptr.file_id);
|
let root = ctx.sema.db.parse_or_expand(expr_ptr.file_id);
|
||||||
let expr = expr_ptr.value.to_node(&root);
|
let expr = expr_ptr.value.to_node(&root);
|
||||||
let (file_id, range) = match expr {
|
let (file_id, range) = match expr.left()? {
|
||||||
ast::Expr::MethodCallExpr(mcall) => {
|
ast::Expr::MethodCallExpr(mcall) => {
|
||||||
let FileRange { range, file_id } =
|
let FileRange { range, file_id } =
|
||||||
ctx.sema.original_range_opt(mcall.receiver()?.syntax())?;
|
ctx.sema.original_range_opt(mcall.receiver()?.syntax())?;
|
||||||
|
|
@ -117,7 +117,7 @@ fn assoc_func_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) -
|
||||||
|
|
||||||
let expr_ptr = &d.expr;
|
let expr_ptr = &d.expr;
|
||||||
let root = db.parse_or_expand(expr_ptr.file_id);
|
let root = db.parse_or_expand(expr_ptr.file_id);
|
||||||
let expr: ast::Expr = expr_ptr.value.to_node(&root);
|
let expr: ast::Expr = expr_ptr.value.to_node(&root).left()?;
|
||||||
|
|
||||||
let call = ast::MethodCallExpr::cast(expr.syntax().clone())?;
|
let call = ast::MethodCallExpr::cast(expr.syntax().clone())?;
|
||||||
let range = InFile::new(expr_ptr.file_id, call.syntax().text_range())
|
let range = InFile::new(expr_ptr.file_id, call.syntax().text_range())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue