Fix span used for structured tuple struct suggestion
(And same for tuple variants.) Previously, the span was just for the constructor name, which meant it would result in syntactically-invalid code when applied. Now, the span is for the entire expression.
This commit is contained in:
parent
50171c310c
commit
d2b13ba466
6 changed files with 135 additions and 10 deletions
|
|
@ -1236,6 +1236,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
variant,
|
||||
fields,
|
||||
base_expr.is_none(),
|
||||
expr.span,
|
||||
);
|
||||
if let Some(base_expr) = base_expr {
|
||||
// If check_expr_struct_fields hit an error, do not attempt to populate
|
||||
|
|
@ -1283,6 +1284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
variant: &'tcx ty::VariantDef,
|
||||
ast_fields: &'tcx [hir::ExprField<'tcx>],
|
||||
check_completeness: bool,
|
||||
expr_span: Span,
|
||||
) -> bool {
|
||||
let tcx = self.tcx;
|
||||
|
||||
|
|
@ -1334,7 +1336,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ident,
|
||||
});
|
||||
} else {
|
||||
self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name, span);
|
||||
self.report_unknown_field(
|
||||
adt_ty, variant, field, ast_fields, kind_name, expr_span,
|
||||
);
|
||||
}
|
||||
|
||||
tcx.ty_error()
|
||||
|
|
@ -1467,7 +1471,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
field: &hir::ExprField<'_>,
|
||||
skip_fields: &[hir::ExprField<'_>],
|
||||
kind_name: &str,
|
||||
ty_span: Span,
|
||||
expr_span: Span,
|
||||
) {
|
||||
if variant.is_recovered() {
|
||||
self.set_tainted_by_errors();
|
||||
|
|
@ -1511,7 +1515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
);
|
||||
err.span_label(field.ident.span, "field does not exist");
|
||||
err.span_suggestion(
|
||||
ty_span,
|
||||
expr_span,
|
||||
&format!(
|
||||
"`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax",
|
||||
adt = ty,
|
||||
|
|
@ -1529,7 +1533,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty));
|
||||
err.span_label(field.ident.span, "field does not exist");
|
||||
err.span_suggestion(
|
||||
ty_span,
|
||||
expr_span,
|
||||
&format!(
|
||||
"`{adt}` is a tuple {kind_name}, use the appropriate syntax",
|
||||
adt = ty,
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ LL | struct NonCopyable(());
|
|||
| ----------- `NonCopyable` defined here
|
||||
...
|
||||
LL | let z = NonCopyable{ p: () };
|
||||
| ----------- ^ field does not exist
|
||||
| |
|
||||
| -------------^------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(/* fields */)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ LL | V1(i32),
|
|||
| -- `Enum::V1` defined here
|
||||
...
|
||||
LL | Enum::V1 { x }
|
||||
| -------- ^ field does not exist
|
||||
| |
|
||||
| -----------^--
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `Enum::V1` is a tuple variant, use the appropriate syntax: `Enum::V1(/* fields */)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ LL | struct S(u8, u16);
|
|||
| - `S` defined here
|
||||
...
|
||||
LL | let s = S{0b1: 10, 0: 11};
|
||||
| - ^^^ field does not exist
|
||||
| |
|
||||
| --^^^------------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)`
|
||||
|
||||
error[E0026]: struct `S` does not have a field named `0x1`
|
||||
|
|
|
|||
18
src/test/ui/suggestions/nested-non-tuple-tuple-struct.rs
Normal file
18
src/test/ui/suggestions/nested-non-tuple-tuple-struct.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
pub struct S(f32, f32);
|
||||
|
||||
pub enum E {
|
||||
V(f32, f32),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
||||
//~^ ERROR struct `S` has no field named `x`
|
||||
//~| ERROR struct `S` has no field named `y`
|
||||
//~| ERROR struct `S` has no field named `x`
|
||||
//~| ERROR struct `S` has no field named `y`
|
||||
let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
||||
//~^ ERROR variant `E::V` has no field named `x`
|
||||
//~| ERROR variant `E::V` has no field named `y`
|
||||
//~| ERROR variant `E::V` has no field named `x`
|
||||
//~| ERROR variant `E::V` has no field named `y`
|
||||
}
|
||||
100
src/test/ui/suggestions/nested-non-tuple-tuple-struct.stderr
Normal file
100
src/test/ui/suggestions/nested-non-tuple-tuple-struct.stderr
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
error[E0560]: struct `S` has no field named `x`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:8:19
|
||||
|
|
||||
LL | pub struct S(f32, f32);
|
||||
| - `S` defined here
|
||||
...
|
||||
LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
||||
| ----^---------------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)`
|
||||
|
||||
error[E0560]: struct `S` has no field named `y`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:8:27
|
||||
|
|
||||
LL | pub struct S(f32, f32);
|
||||
| - `S` defined here
|
||||
...
|
||||
LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
||||
| ------------^-------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)`
|
||||
|
||||
error[E0560]: struct `S` has no field named `x`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:8:41
|
||||
|
|
||||
LL | pub struct S(f32, f32);
|
||||
| - `S` defined here
|
||||
...
|
||||
LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
||||
| ----^---------------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)`
|
||||
|
||||
error[E0560]: struct `S` has no field named `y`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:8:49
|
||||
|
|
||||
LL | pub struct S(f32, f32);
|
||||
| - `S` defined here
|
||||
...
|
||||
LL | let _x = (S { x: 1.0, y: 2.0 }, S { x: 3.0, y: 4.0 });
|
||||
| ------------^-------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)`
|
||||
|
||||
error[E0559]: variant `E::V` has no field named `x`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:13:22
|
||||
|
|
||||
LL | V(f32, f32),
|
||||
| - `E::V` defined here
|
||||
...
|
||||
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
||||
| -------^---------------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `E::V` is a tuple variant, use the appropriate syntax: `E::V(/* fields */)`
|
||||
|
||||
error[E0559]: variant `E::V` has no field named `y`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:13:30
|
||||
|
|
||||
LL | V(f32, f32),
|
||||
| - `E::V` defined here
|
||||
...
|
||||
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
||||
| ---------------^-------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `E::V` is a tuple variant, use the appropriate syntax: `E::V(/* fields */)`
|
||||
|
||||
error[E0559]: variant `E::V` has no field named `x`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:13:47
|
||||
|
|
||||
LL | V(f32, f32),
|
||||
| - `E::V` defined here
|
||||
...
|
||||
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
||||
| -------^---------------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `E::V` is a tuple variant, use the appropriate syntax: `E::V(/* fields */)`
|
||||
|
||||
error[E0559]: variant `E::V` has no field named `y`
|
||||
--> $DIR/nested-non-tuple-tuple-struct.rs:13:55
|
||||
|
|
||||
LL | V(f32, f32),
|
||||
| - `E::V` defined here
|
||||
...
|
||||
LL | let _y = (E::V { x: 1.0, y: 2.0 }, E::V { x: 3.0, y: 4.0 });
|
||||
| ---------------^-------
|
||||
| | |
|
||||
| | field does not exist
|
||||
| help: `E::V` is a tuple variant, use the appropriate syntax: `E::V(/* fields */)`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0559, E0560.
|
||||
For more information about an error, try `rustc --explain E0559`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue