From 04298204ed17eeed4d23aaa45fb0db9336e6583c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Jul 2020 17:42:07 -0700 Subject: [PATCH] Suggest struct pat on incorrect unit or tuple pat When encountering a unit or tuple pattern for a struct-like item, suggest using the correct pattern. Use `insert_field_names_local` when evaluating variants and store field names even when the list is empty in order to produce accurate structured suggestions. --- src/librustc_resolve/build_reduced_graph.rs | 6 +- src/librustc_resolve/late.rs | 16 ++--- src/librustc_resolve/late/diagnostics.rs | 68 +++++++++++++++--- .../ui/empty/empty-struct-braces-expr.stderr | 60 ++++++++++------ .../ui/empty/empty-struct-braces-pat-1.stderr | 16 +++-- .../ui/empty/empty-struct-braces-pat-2.stderr | 72 ++++++++++--------- .../ui/empty/empty-struct-braces-pat-3.stderr | 42 +++++------ src/test/ui/error-codes/E0423.stderr | 15 ++-- src/test/ui/issues/issue-19086.stderr | 2 +- src/test/ui/issues/issue-34334.stderr | 2 +- src/test/ui/issues/issue-63983.stderr | 2 +- .../issue-64792-bad-unicode-ctor.stderr | 15 ++-- src/test/ui/namespace/namespace-mix.stderr | 12 +++- .../ui/parser/recover-from-bad-variant.stderr | 2 +- src/test/ui/resolve/issue-18252.stderr | 2 +- src/test/ui/resolve/issue-19452.stderr | 4 +- src/test/ui/resolve/issue-39226.stderr | 12 +++- src/test/ui/resolve/issue-6702.stderr | 2 +- src/test/ui/resolve/privacy-enum-ctor.stderr | 8 +-- .../ui/resolve/privacy-struct-ctor.stderr | 2 +- .../fn-or-tuple-struct-without-args.stderr | 14 ++-- src/test/ui/suggestions/issue-61226.stderr | 2 +- src/test/ui/xcrate/xcrate-unit-struct.stderr | 2 +- 23 files changed, 239 insertions(+), 139 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index bca65c63e9198..8db27babd058b 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -300,9 +300,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } fn insert_field_names(&mut self, def_id: DefId, field_names: Vec>) { - if !field_names.is_empty() { - self.r.field_names.insert(def_id, field_names); - } + self.r.field_names.insert(def_id, field_names); } fn block_needs_anonymous_module(&mut self, block: &Block) -> bool { @@ -1428,6 +1426,8 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { let ctor_kind = CtorKind::from_ast(&variant.data); let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); + // Record field names for error reporting. + self.insert_field_names_local(ctor_def_id, &variant.data); visit::walk_variant(self, variant); } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 679f5637686ff..71c71fe4ce665 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -184,7 +184,7 @@ crate enum PathSource<'a> { // Paths in struct expressions and patterns `Path { .. }`. Struct, // Paths in tuple struct patterns `Path(..)`. - TupleStruct, + TupleStruct(Span), // `m::A::B` in `::B::C`. TraitItem(Namespace), } @@ -193,7 +193,7 @@ impl<'a> PathSource<'a> { fn namespace(self) -> Namespace { match self { PathSource::Type | PathSource::Trait(_) | PathSource::Struct => TypeNS, - PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct => ValueNS, + PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct(_) => ValueNS, PathSource::TraitItem(ns) => ns, } } @@ -204,7 +204,7 @@ impl<'a> PathSource<'a> { | PathSource::Expr(..) | PathSource::Pat | PathSource::Struct - | PathSource::TupleStruct => true, + | PathSource::TupleStruct(_) => true, PathSource::Trait(_) | PathSource::TraitItem(..) => false, } } @@ -215,7 +215,7 @@ impl<'a> PathSource<'a> { PathSource::Trait(_) => "trait", PathSource::Pat => "unit struct, unit variant or constant", PathSource::Struct => "struct, variant or union type", - PathSource::TupleStruct => "tuple struct or tuple variant", + PathSource::TupleStruct(_) => "tuple struct or tuple variant", PathSource::TraitItem(ns) => match ns { TypeNS => "associated type", ValueNS => "method or associated constant", @@ -301,7 +301,7 @@ impl<'a> PathSource<'a> { | Res::SelfCtor(..) => true, _ => false, }, - PathSource::TupleStruct => match res { + PathSource::TupleStruct(_) => match res { Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) | Res::SelfCtor(..) => true, _ => false, }, @@ -336,8 +336,8 @@ impl<'a> PathSource<'a> { (PathSource::Struct, false) => error_code!(E0422), (PathSource::Expr(..), true) => error_code!(E0423), (PathSource::Expr(..), false) => error_code!(E0425), - (PathSource::Pat | PathSource::TupleStruct, true) => error_code!(E0532), - (PathSource::Pat | PathSource::TupleStruct, false) => error_code!(E0531), + (PathSource::Pat | PathSource::TupleStruct(_), true) => error_code!(E0532), + (PathSource::Pat | PathSource::TupleStruct(_), false) => error_code!(E0531), (PathSource::TraitItem(..), true) => error_code!(E0575), (PathSource::TraitItem(..), false) => error_code!(E0576), } @@ -1483,7 +1483,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.r.record_partial_res(pat.id, PartialRes::new(res)); } PatKind::TupleStruct(ref path, ..) => { - self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct); + self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct(pat.span)); } PatKind::Path(ref qself, ref path) => { self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat); diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index e469ca80c590a..06d683ef54765 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -482,10 +482,12 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { let mut bad_struct_syntax_suggestion = |def_id: DefId| { let (followed_by_brace, closing_brace) = self.followed_by_brace(span); - let mut suggested = false; + match source { - PathSource::Expr(Some(parent)) => { - suggested = path_sep(err, &parent); + PathSource::Expr(Some( + parent @ Expr { kind: ExprKind::Field(..) | ExprKind::MethodCall(..), .. }, + )) => { + path_sep(err, &parent); } PathSource::Expr(None) if followed_by_brace => { if let Some(sp) = closing_brace { @@ -507,15 +509,56 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { ), ); } - suggested = true; } - _ => {} - } - if !suggested { - if let Some(span) = self.r.opt_span(def_id) { - err.span_label(span, &format!("`{}` defined here", path_str)); + PathSource::Expr( + None | Some(Expr { kind: ExprKind::Call(..) | ExprKind::Path(..), .. }), + ) + | PathSource::TupleStruct(_) + | PathSource::Pat => { + let span = match &source { + PathSource::Expr(Some(Expr { + span, kind: ExprKind::Call(_, _), .. + })) + | PathSource::TupleStruct(span) => { + // We want the main underline to cover the suggested code as well for + // cleaner output. + err.set_span(*span); + *span + } + _ => span, + }; + if let Some(span) = self.r.opt_span(def_id) { + err.span_label(span, &format!("`{}` defined here", path_str)); + } + let (tail, descr, applicability) = match source { + PathSource::Pat | PathSource::TupleStruct(_) => { + ("", "pattern", Applicability::MachineApplicable) + } + _ => (": val", "literal", Applicability::HasPlaceholders), + }; + let (fields, applicability) = match self.r.field_names.get(&def_id) { + Some(fields) => ( + fields + .iter() + .map(|f| format!("{}{}", f.node, tail)) + .collect::>() + .join(", "), + applicability, + ), + None => ("/* fields */".to_string(), Applicability::HasPlaceholders), + }; + let pad = match self.r.field_names.get(&def_id) { + Some(fields) if fields.is_empty() => "", + _ => " ", + }; + err.span_suggestion( + span, + &format!("use struct {} syntax instead", descr), + format!("{} {{{pad}{}{pad}}}", path_str, fields, pad = pad), + applicability, + ); } - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str)); + _ => {} } }; @@ -548,7 +591,10 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { return false; } } - (Res::Def(DefKind::Enum, def_id), PathSource::TupleStruct | PathSource::Expr(..)) => { + ( + Res::Def(DefKind::Enum, def_id), + PathSource::TupleStruct(_) | PathSource::Expr(..), + ) => { if let Some(variants) = self.collect_enum_variants(def_id) { if !variants.is_empty() { let msg = if variants.len() == 1 { diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index 9da3a5f5bdb3d..c0ba9716fb001 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -6,14 +6,20 @@ LL | struct Empty1 {} ... LL | let e1 = Empty1; | ^^^^^^ - | | - | did you mean `Empty1 { /* fields */ }`? - | help: a unit struct with a similar name exists: `XEmpty2` | ::: $DIR/auxiliary/empty-struct.rs:2:1 | LL | pub struct XEmpty2; | ------------------- similarly named unit struct `XEmpty2` defined here + | +help: a unit struct with a similar name exists + | +LL | let e1 = XEmpty2; + | ^^^^^^^ +help: use struct literal syntax instead + | +LL | let e1 = Empty1 {}; + | ^^^^^^^^^ error[E0423]: expected function, tuple struct or tuple variant, found struct `Empty1` --> $DIR/empty-struct-braces-expr.rs:16:14 @@ -22,15 +28,16 @@ LL | struct Empty1 {} | ---------------- `Empty1` defined here ... LL | let e1 = Empty1(); - | ^^^^^^ - | | - | did you mean `Empty1 { /* fields */ }`? - | help: a unit struct with a similar name exists: `XEmpty2` - | - ::: $DIR/auxiliary/empty-struct.rs:2:1 + | ^^^^^^^^ | -LL | pub struct XEmpty2; - | ------------------- similarly named unit struct `XEmpty2` defined here +help: a unit struct with a similar name exists + | +LL | let e1 = XEmpty2(); + | ^^^^^^^ +help: use struct literal syntax instead + | +LL | let e1 = Empty1 {}; + | ^^^^^^^^^ error[E0423]: expected value, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-expr.rs:18:14 @@ -39,7 +46,7 @@ LL | Empty3 {} | --------- `E::Empty3` defined here ... LL | let e3 = E::Empty3; - | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? + | ^^^^^^^^^ help: use struct literal syntax instead: `E::Empty3 {}` error[E0423]: expected function, tuple struct or tuple variant, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-expr.rs:19:14 @@ -48,35 +55,42 @@ LL | Empty3 {} | --------- `E::Empty3` defined here ... LL | let e3 = E::Empty3(); - | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? + | ^^^^^^^^^^^ help: use struct literal syntax instead: `E::Empty3 {}` error[E0423]: expected value, found struct `XEmpty1` --> $DIR/empty-struct-braces-expr.rs:22:15 | LL | let xe1 = XEmpty1; | ^^^^^^^ - | | - | did you mean `XEmpty1 { /* fields */ }`? - | help: a unit struct with a similar name exists: `XEmpty2` | ::: $DIR/auxiliary/empty-struct.rs:2:1 | LL | pub struct XEmpty2; | ------------------- similarly named unit struct `XEmpty2` defined here + | +help: a unit struct with a similar name exists + | +LL | let xe1 = XEmpty2; + | ^^^^^^^ +help: use struct literal syntax instead + | +LL | let xe1 = XEmpty1 {}; + | ^^^^^^^^^^ error[E0423]: expected function, tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-expr.rs:23:15 | LL | let xe1 = XEmpty1(); + | ^^^^^^^^^ + | +help: a unit struct with a similar name exists + | +LL | let xe1 = XEmpty2(); | ^^^^^^^ - | | - | did you mean `XEmpty1 { /* fields */ }`? - | help: a unit struct with a similar name exists: `XEmpty2` - | - ::: $DIR/auxiliary/empty-struct.rs:2:1 +help: use struct literal syntax instead | -LL | pub struct XEmpty2; - | ------------------- similarly named unit struct `XEmpty2` defined here +LL | let xe1 = XEmpty1 {}; + | ^^^^^^^^^^ error[E0599]: no variant or associated item named `Empty3` found for enum `empty_struct::XE` in the current scope --> $DIR/empty-struct-braces-expr.rs:25:19 diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr index 0ff21c91b78fd..b027c82f7dd37 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr @@ -5,21 +5,27 @@ LL | Empty3 {} | --------- `E::Empty3` defined here ... LL | E::Empty3 => () - | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? + | ^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}` error[E0532]: expected unit struct, unit variant or constant, found struct variant `XE::XEmpty3` --> $DIR/empty-struct-braces-pat-1.rs:31:9 | LL | XE::XEmpty3 => () - | ^^^^------- - | | | - | | help: a unit variant with a similar name exists: `XEmpty4` - | did you mean `XE::XEmpty3 { /* fields */ }`? + | ^^^^^^^^^^^ | ::: $DIR/auxiliary/empty-struct.rs:7:5 | LL | XEmpty4, | ------- similarly named unit variant `XEmpty4` defined here + | +help: a unit variant with a similar name exists + | +LL | XE::XEmpty4 => () + | ^^^^^^^ +help: use struct pattern syntax instead + | +LL | XE::XEmpty3 { /* fields */ } => () + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/empty/empty-struct-braces-pat-2.stderr b/src/test/ui/empty/empty-struct-braces-pat-2.stderr index 80c29db8d9b77..a53b88db7d1ed 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-2.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-2.stderr @@ -5,29 +5,31 @@ LL | struct Empty1 {} | ---------------- `Empty1` defined here ... LL | Empty1() => () - | ^^^^^^ - | | - | did you mean `Empty1 { /* fields */ }`? - | help: a tuple struct with a similar name exists: `XEmpty6` - | - ::: $DIR/auxiliary/empty-struct.rs:3:1 - | -LL | pub struct XEmpty6(); - | --------------------- similarly named tuple struct `XEmpty6` defined here + | ^^^^^^^^ + | +help: a tuple struct with a similar name exists + | +LL | XEmpty6() => () + | ^^^^^^^ +help: use struct pattern syntax instead + | +LL | Empty1 {} => () + | ^^^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-pat-2.rs:18:9 | LL | XEmpty1() => () + | ^^^^^^^^^ + | +help: a tuple struct with a similar name exists + | +LL | XEmpty6() => () | ^^^^^^^ - | | - | did you mean `XEmpty1 { /* fields */ }`? - | help: a tuple struct with a similar name exists: `XEmpty6` - | - ::: $DIR/auxiliary/empty-struct.rs:3:1 - | -LL | pub struct XEmpty6(); - | --------------------- similarly named tuple struct `XEmpty6` defined here +help: use struct pattern syntax instead + | +LL | XEmpty1 {} => () + | ^^^^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct `Empty1` --> $DIR/empty-struct-braces-pat-2.rs:21:9 @@ -36,29 +38,31 @@ LL | struct Empty1 {} | ---------------- `Empty1` defined here ... LL | Empty1(..) => () - | ^^^^^^ - | | - | did you mean `Empty1 { /* fields */ }`? - | help: a tuple struct with a similar name exists: `XEmpty6` - | - ::: $DIR/auxiliary/empty-struct.rs:3:1 - | -LL | pub struct XEmpty6(); - | --------------------- similarly named tuple struct `XEmpty6` defined here + | ^^^^^^^^^^ + | +help: a tuple struct with a similar name exists + | +LL | XEmpty6(..) => () + | ^^^^^^^ +help: use struct pattern syntax instead + | +LL | Empty1 {} => () + | ^^^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct `XEmpty1` --> $DIR/empty-struct-braces-pat-2.rs:24:9 | LL | XEmpty1(..) => () + | ^^^^^^^^^^^ + | +help: a tuple struct with a similar name exists + | +LL | XEmpty6(..) => () | ^^^^^^^ - | | - | did you mean `XEmpty1 { /* fields */ }`? - | help: a tuple struct with a similar name exists: `XEmpty6` - | - ::: $DIR/auxiliary/empty-struct.rs:3:1 - | -LL | pub struct XEmpty6(); - | --------------------- similarly named tuple struct `XEmpty6` defined here +help: use struct pattern syntax instead + | +LL | XEmpty1 {} => () + | ^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr index 05439b39ea39d..93ace3eccef91 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr @@ -5,21 +5,22 @@ LL | Empty3 {} | --------- `E::Empty3` defined here ... LL | E::Empty3() => () - | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? + | ^^^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}` error[E0532]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3` --> $DIR/empty-struct-braces-pat-3.rs:21:9 | LL | XE::XEmpty3() => () - | ^^^^------- - | | | - | | help: a tuple variant with a similar name exists: `XEmpty5` - | did you mean `XE::XEmpty3 { /* fields */ }`? - | - ::: $DIR/auxiliary/empty-struct.rs:8:5 - | -LL | XEmpty5(), - | --------- similarly named tuple variant `XEmpty5` defined here + | ^^^^^^^^^^^^^ + | +help: a tuple variant with a similar name exists + | +LL | XE::XEmpty5() => () + | ^^^^^^^ +help: use struct pattern syntax instead + | +LL | XE::XEmpty3 { /* fields */ } => () + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3` --> $DIR/empty-struct-braces-pat-3.rs:25:9 @@ -28,21 +29,22 @@ LL | Empty3 {} | --------- `E::Empty3` defined here ... LL | E::Empty3(..) => () - | ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`? + | ^^^^^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}` error[E0532]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3` --> $DIR/empty-struct-braces-pat-3.rs:29:9 | LL | XE::XEmpty3(..) => () - | ^^^^------- - | | | - | | help: a tuple variant with a similar name exists: `XEmpty5` - | did you mean `XE::XEmpty3 { /* fields */ }`? - | - ::: $DIR/auxiliary/empty-struct.rs:8:5 - | -LL | XEmpty5(), - | --------- similarly named tuple variant `XEmpty5` defined here + | ^^^^^^^^^^^^^^^ + | +help: a tuple variant with a similar name exists + | +LL | XE::XEmpty5(..) => () + | ^^^^^^^ +help: use struct pattern syntax instead + | +LL | XE::XEmpty3 { /* fields */ } => () + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index d4860394259b7..077367de9d847 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -33,13 +33,16 @@ LL | struct Foo { a: bool }; | ---------------------- `Foo` defined here LL | LL | let f = Foo(); + | ^^^^^ + | +help: a function with a similar name exists + | +LL | let f = foo(); | ^^^ - | | - | did you mean `Foo { /* fields */ }`? - | help: a function with a similar name exists (notice the capitalization): `foo` -... -LL | fn foo() { - | -------- similarly named function `foo` defined here +help: use struct literal syntax instead + | +LL | let f = Foo { a: val }; + | ^^^^^^^^^^^^^^ error[E0423]: expected value, found struct `T` --> $DIR/E0423.rs:14:8 diff --git a/src/test/ui/issues/issue-19086.stderr b/src/test/ui/issues/issue-19086.stderr index 27992da0ebd2f..a54f1008e4ba9 100644 --- a/src/test/ui/issues/issue-19086.stderr +++ b/src/test/ui/issues/issue-19086.stderr @@ -5,7 +5,7 @@ LL | FooB { x: i32, y: i32 } | ----------------------- `FooB` defined here ... LL | FooB(a, b) => println!("{} {}", a, b), - | ^^^^ did you mean `FooB { /* fields */ }`? + | ^^^^^^^^^^ help: use struct pattern syntax instead: `FooB { x, y }` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr index c68b271807b99..5f157f6e3c089 100644 --- a/src/test/ui/issues/issue-34334.stderr +++ b/src/test/ui/issues/issue-34334.stderr @@ -23,7 +23,7 @@ error[E0423]: expected value, found struct `Vec` --> $DIR/issue-34334.rs:2:13 | LL | let sr: Vec<(u32, _, _) = vec![]; - | ^^^ did you mean `Vec { /* fields */ }`? + | ^^^ help: use struct literal syntax instead: `Vec { buf: val, len: val }` error[E0308]: mismatched types --> $DIR/issue-34334.rs:2:31 diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr index e54466faedde6..771a5c285aff8 100644 --- a/src/test/ui/issues/issue-63983.stderr +++ b/src/test/ui/issues/issue-63983.stderr @@ -14,7 +14,7 @@ LL | Struct{ s: i32 }, | ---------------- `MyEnum::Struct` defined here ... LL | MyEnum::Struct => "", - | ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`? + | ^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `MyEnum::Struct { s }` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr b/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr index 44e5d38abbc54..12053d8a1291c 100644 --- a/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr +++ b/src/test/ui/issues/issue-64792-bad-unicode-ctor.stderr @@ -5,11 +5,16 @@ LL | struct X {} | ----------- `X` defined here LL | LL | const Y: X = X("ö"); - | -------------^------ - | | | - | | did you mean `X { /* fields */ }`? - | | help: a constant with a similar name exists: `Y` - | similarly named constant `Y` defined here + | ^^^^^^ + | +help: a constant with a similar name exists + | +LL | const Y: X = Y("ö"); + | ^ +help: use struct literal syntax instead + | +LL | const Y: X = X {}; + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index ee730910ee441..636789c9cc300 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -51,12 +51,16 @@ LL | TV(), | ---- similarly named tuple variant `TV` defined here ... LL | check(m7::V); - | ^^^^^ did you mean `m7::V { /* fields */ }`? + | ^^^^^ | help: a tuple variant with a similar name exists | LL | check(m7::TV); | ^^ +help: use struct literal syntax instead + | +LL | check(m7::V {}); + | ^^^^^^^^ help: consider importing one of these items instead | LL | use m8::V; @@ -68,7 +72,7 @@ error[E0423]: expected value, found struct variant `xm7::V` --> $DIR/namespace-mix.rs:106:11 | LL | check(xm7::V); - | ^^^^^^ did you mean `xm7::V { /* fields */ }`? + | ^^^^^^ | ::: $DIR/auxiliary/namespace-mix.rs:7:9 | @@ -79,6 +83,10 @@ help: a tuple variant with a similar name exists | LL | check(xm7::TV); | ^^ +help: use struct literal syntax instead + | +LL | check(xm7::V { /* fields */ }); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider importing one of these items instead | LL | use m8::V; diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr index 0272326c7bc4f..6986d966d69ec 100644 --- a/src/test/ui/parser/recover-from-bad-variant.stderr +++ b/src/test/ui/parser/recover-from-bad-variant.stderr @@ -16,7 +16,7 @@ LL | Foo { a: usize, b: usize }, | -------------------------- `Enum::Foo` defined here ... LL | Enum::Foo(a, b) => {} - | ^^^^^^^^^ did you mean `Enum::Foo { /* fields */ }`? + | ^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `Enum::Foo { a, b }` error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr index 39b444498102c..13e7a59732db1 100644 --- a/src/test/ui/resolve/issue-18252.stderr +++ b/src/test/ui/resolve/issue-18252.stderr @@ -5,7 +5,7 @@ LL | Variant { x: usize } | -------------------- `Foo::Variant` defined here ... LL | let f = Foo::Variant(42); - | ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`? + | ^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `Foo::Variant { x: val }` error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr index 4d20f1580264c..d1690d4eef7ef 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -5,13 +5,13 @@ LL | Madoka { age: u32 } | ------------------- `Homura::Madoka` defined here ... LL | let homura = Homura::Madoka; - | ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`? + | ^^^^^^^^^^^^^^ help: use struct literal syntax instead: `Homura::Madoka { age: val }` error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka` --> $DIR/issue-19452.rs:13:18 | LL | let homura = issue_19452_aux::Homura::Madoka; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `issue_19452_aux::Homura::Madoka { /* fields */ }` error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr index d9a28e63dce8b..c9b9aeb45ba42 100644 --- a/src/test/ui/resolve/issue-39226.stderr +++ b/src/test/ui/resolve/issue-39226.stderr @@ -6,9 +6,15 @@ LL | struct Handle {} ... LL | handle: Handle | ^^^^^^ - | | - | did you mean `Handle { /* fields */ }`? - | help: a local variable with a similar name exists: `handle` + | +help: a local variable with a similar name exists + | +LL | handle: handle + | ^^^^^^ +help: use struct literal syntax instead + | +LL | handle: Handle {} + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/resolve/issue-6702.stderr b/src/test/ui/resolve/issue-6702.stderr index 252d50c70f8c4..a118f94191df3 100644 --- a/src/test/ui/resolve/issue-6702.stderr +++ b/src/test/ui/resolve/issue-6702.stderr @@ -7,7 +7,7 @@ LL | | } | |_- `Monster` defined here ... LL | let _m = Monster(); - | ^^^^^^^ did you mean `Monster { /* fields */ }`? + | ^^^^^^^^^ help: use struct literal syntax instead: `Monster { damage: val }` error: aborting due to previous error diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 16baa6c9b6233..3904a00dde1dd 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -44,7 +44,7 @@ LL | | }, | |_____________- `Z::Struct` defined here ... LL | let _: Z = Z::Struct; - | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`? + | ^^^^^^^^^ help: use struct literal syntax instead: `Z::Struct { s: val }` error[E0423]: expected value, found enum `m::E` --> $DIR/privacy-enum-ctor.rs:41:16 @@ -83,7 +83,7 @@ LL | | }, | |_________- `m::E::Struct` defined here ... LL | let _: E = m::E::Struct; - | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`? + | ^^^^^^^^^^^^ help: use struct literal syntax instead: `m::E::Struct { s: val }` error[E0423]: expected value, found enum `E` --> $DIR/privacy-enum-ctor.rs:49:16 @@ -115,7 +115,7 @@ LL | | }, | |_________- `E::Struct` defined here ... LL | let _: E = E::Struct; - | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`? + | ^^^^^^^^^ help: use struct literal syntax instead: `E::Struct { s: val }` error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:57:12 @@ -195,7 +195,7 @@ LL | | }, | |_____________- `m::n::Z::Struct` defined here ... LL | let _: Z = m::n::Z::Struct; - | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`? + | ^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `m::n::Z::Struct { s: val }` error[E0412]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:68:12 diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index e0305b129a881..a72f69cf1cd8d 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -25,7 +25,7 @@ LL | | } | |_____- `S2` defined here ... LL | S2; - | ^^ did you mean `S2 { /* fields */ }`? + | ^^ help: use struct literal syntax instead: `S2 { s: val }` error[E0423]: expected value, found struct `xcrate::S` --> $DIR/privacy-struct-ctor.rs:43:5 diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr index b03bea1eddbf0..45309486db46f 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -7,10 +7,16 @@ LL | B { a: usize }, | -------------- `E::B` defined here ... LL | let _: E = E::B; - | ^^^- - | | | - | | help: a tuple variant with a similar name exists: `A` - | did you mean `E::B { /* fields */ }`? + | ^^^^ + | +help: a tuple variant with a similar name exists + | +LL | let _: E = E::A; + | ^ +help: use struct literal syntax instead + | +LL | let _: E = E::B { a: val }; + | ^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/fn-or-tuple-struct-without-args.rs:29:20 diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr index fbcfba6653f27..7f6f082d7a8d7 100644 --- a/src/test/ui/suggestions/issue-61226.stderr +++ b/src/test/ui/suggestions/issue-61226.stderr @@ -5,7 +5,7 @@ LL | struct X {} | ----------- `X` defined here LL | fn main() { LL | vec![X]; //… - | ^ did you mean `X { /* fields */ }`? + | ^ help: use struct literal syntax instead: `X {}` error: aborting due to previous error diff --git a/src/test/ui/xcrate/xcrate-unit-struct.stderr b/src/test/ui/xcrate/xcrate-unit-struct.stderr index e4a4b9c580602..813d5d4fdb12b 100644 --- a/src/test/ui/xcrate/xcrate-unit-struct.stderr +++ b/src/test/ui/xcrate/xcrate-unit-struct.stderr @@ -2,7 +2,7 @@ error[E0423]: expected value, found struct `xcrate_unit_struct::StructWithFields --> $DIR/xcrate-unit-struct.rs:9:13 | LL | let _ = xcrate_unit_struct::StructWithFields; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `xcrate_unit_struct::StructWithFields { /* fields */ }`? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `xcrate_unit_struct::StructWithFields { foo: val }` error: aborting due to previous error