From 9bab0f09d30c90126993fa824171925a8fa579a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 31 Dec 2017 16:35:52 -0800 Subject: [PATCH 1/8] Hide suggestion to use struct ctor when it is not visible --- src/librustc_resolve/lib.rs | 16 +++++++++++----- src/test/ui/resolve/privacy-struct-ctor.stderr | 11 ++--------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0a29441cef7ef..d67578e8c06d8 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2568,7 +2568,8 @@ impl<'a> Resolver<'a> { let code = source.error_code(def.is_some()); let (base_msg, fallback_label, base_span) = if let Some(def) = def { (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), - format!("not a {}", expected), span) + format!("not a {}", expected), + span) } else { let item_str = path[path.len() - 1].node; let item_span = path[path.len() - 1].span; @@ -2585,7 +2586,8 @@ impl<'a> Resolver<'a> { (mod_prefix, format!("`{}`", names_to_string(mod_path))) }; (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), - format!("not found in {}", mod_str), item_span) + format!("not found in {}", mod_str), + item_span) }; let code = DiagnosticId::Error(code.into()); let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code); @@ -2701,17 +2703,21 @@ impl<'a> Resolver<'a> { return (err, candidates); }, _ if ns == ValueNS && is_struct_like(def) => { + let mut accessible_ctor = true; if let Def::Struct(def_id) = def { if let Some((ctor_def, ctor_vis)) = this.struct_constructors.get(&def_id).cloned() { - if is_expected(ctor_def) && !this.is_accessible(ctor_vis) { + accessible_ctor = this.is_accessible(ctor_vis); + if is_expected(ctor_def) && !accessible_ctor { err.span_label(span, format!("constructor is not visible \ here due to private fields")); } } } - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", - path_str)); + if accessible_ctor { + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); + } return (err, candidates); } _ => {} diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index 39bedf59641a8..b688d2fc95baf 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -6,7 +6,6 @@ error[E0423]: expected value, found struct `Z` | | | did you mean `S`? | constructor is not visible here due to private fields - | did you mean `Z { /* fields */ }`? help: possible better candidate is found in another module, you can import it into scope | 22 | use m::n::Z; @@ -16,10 +15,7 @@ error[E0423]: expected value, found struct `S` --> $DIR/privacy-struct-ctor.rs:35:5 | 35 | S; - | ^ - | | - | constructor is not visible here due to private fields - | did you mean `S { /* fields */ }`? + | ^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | 31 | use m::S; @@ -29,10 +25,7 @@ error[E0423]: expected value, found struct `xcrate::S` --> $DIR/privacy-struct-ctor.rs:40:5 | 40 | xcrate::S; - | ^^^^^^^^^ - | | - | constructor is not visible here due to private fields - | did you mean `xcrate::S { /* fields */ }`? + | ^^^^^^^^^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | 31 | use m::S; From a317da42b16ffe4d06c12ab795aef3cbc0859de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jan 2018 15:29:50 -0800 Subject: [PATCH 2/8] Suggest the correct syntax for different struct types --- src/librustc_resolve/lib.rs | 34 +++++++++----- src/test/ui/resolve/issue-18252.stderr | 2 +- src/test/ui/resolve/issue-19452.stderr | 4 +- src/test/ui/resolve/privacy-struct-ctor.rs | 7 +++ .../ui/resolve/privacy-struct-ctor.stderr | 46 +++++++++++-------- src/test/ui/resolve/tuple-struct-alias.stderr | 14 ++---- 6 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index d67578e8c06d8..29ca160fac0db 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2702,19 +2702,29 @@ impl<'a> Resolver<'a> { } return (err, candidates); }, - _ if ns == ValueNS && is_struct_like(def) => { - let mut accessible_ctor = true; - if let Def::Struct(def_id) = def { - if let Some((ctor_def, ctor_vis)) - = this.struct_constructors.get(&def_id).cloned() { - accessible_ctor = this.is_accessible(ctor_vis); - if is_expected(ctor_def) && !accessible_ctor { - err.span_label(span, format!("constructor is not visible \ - here due to private fields")); - } + (Def::Struct(def_id), _) if ns == ValueNS && is_struct_like(def) => { + if let Some((ctor_def, ctor_vis)) + = this.struct_constructors.get(&def_id).cloned() { + let accessible_ctor = this.is_accessible(ctor_vis); + if is_expected(ctor_def) && !accessible_ctor { + err.span_label(span, format!("constructor is not visible \ + here due to private fields")); + } else if accessible_ctor { + let block = match ctor_def { + Def::StructCtor(_, CtorKind::Fn) | + Def::VariantCtor(_, CtorKind::Fn) => "(/* fields */)", + Def::StructCtor(_, CtorKind::Fictive) | + Def::VariantCtor(_, CtorKind::Fictive) => { + " { /* fields */ }" + } + def => bug!("found def `{:?}` when looking for a ctor", + def), + }; + err.span_label(span, format!("did you mean `{}{}`?", + path_str, + block)); } - } - if accessible_ctor { + } else { err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str)); } diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr index edc7196d84645..f93007c8b6144 100644 --- a/src/test/ui/resolve/issue-18252.stderr +++ b/src/test/ui/resolve/issue-18252.stderr @@ -2,7 +2,7 @@ error[E0423]: expected function, found struct variant `Foo::Variant` --> $DIR/issue-18252.rs:16:13 | 16 | let f = Foo::Variant(42); - | ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`? + | ^^^^^^^^^^^^ not a function 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 7b14d49af51dd..44690158b587f 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -2,13 +2,13 @@ error[E0423]: expected value, found struct variant `Homura::Madoka` --> $DIR/issue-19452.rs:19:18 | 19 | let homura = Homura::Madoka; - | ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`? + | ^^^^^^^^^^^^^^ not a value error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka` --> $DIR/issue-19452.rs:22:18 | 22 | let homura = issue_19452_aux::Homura::Madoka; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`? + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/privacy-struct-ctor.rs b/src/test/ui/resolve/privacy-struct-ctor.rs index eb6edae738133..821a51e9427d3 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.rs +++ b/src/test/ui/resolve/privacy-struct-ctor.rs @@ -14,6 +14,9 @@ extern crate privacy_struct_ctor as xcrate; mod m { pub struct S(u8); + pub struct S2 { + s: u8 + } pub mod n { pub(in m) struct Z(pub(in m::n) u8); @@ -29,6 +32,7 @@ mod m { } use m::S; // OK, only the type is imported +use m::S2; // OK, only the type is imported fn main() { m::S; //~ ERROR tuple struct `S` is private @@ -36,6 +40,9 @@ fn main() { //~^ ERROR expected value, found struct `S` m::n::Z; //~ ERROR tuple struct `Z` is private + S2; + //~^ ERROR expected value, found struct `S2` + xcrate::m::S; //~ ERROR tuple struct `S` is private xcrate::S; //~^ ERROR expected value, found struct `xcrate::S` diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index b688d2fc95baf..e274ac02c5739 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -1,65 +1,71 @@ error[E0423]: expected value, found struct `Z` - --> $DIR/privacy-struct-ctor.rs:26:9 + --> $DIR/privacy-struct-ctor.rs:29:9 | -26 | Z; +29 | Z; | ^ | | | did you mean `S`? | constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | -22 | use m::n::Z; +25 | use m::n::Z; | error[E0423]: expected value, found struct `S` - --> $DIR/privacy-struct-ctor.rs:35:5 + --> $DIR/privacy-struct-ctor.rs:39:5 | -35 | S; +39 | S; | ^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | -31 | use m::S; +34 | use m::S; + | + +error[E0423]: expected value, found struct `S2` + --> $DIR/privacy-struct-ctor.rs:43:5 | +43 | S2; + | ^^ did you mean `S2 { /* fields */ }`? error[E0423]: expected value, found struct `xcrate::S` - --> $DIR/privacy-struct-ctor.rs:40:5 + --> $DIR/privacy-struct-ctor.rs:47:5 | -40 | xcrate::S; +47 | xcrate::S; | ^^^^^^^^^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | -31 | use m::S; +34 | use m::S; | error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:25:9 + --> $DIR/privacy-struct-ctor.rs:28:9 | -25 | n::Z; //~ ERROR tuple struct `Z` is private +28 | n::Z; //~ ERROR tuple struct `Z` is private | ^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:34:5 + --> $DIR/privacy-struct-ctor.rs:38:5 | -34 | m::S; //~ ERROR tuple struct `S` is private +38 | m::S; //~ ERROR tuple struct `S` is private | ^^^^ error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:37:5 + --> $DIR/privacy-struct-ctor.rs:41:5 | -37 | m::n::Z; //~ ERROR tuple struct `Z` is private +41 | m::n::Z; //~ ERROR tuple struct `Z` is private | ^^^^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:39:5 + --> $DIR/privacy-struct-ctor.rs:46:5 | -39 | xcrate::m::S; //~ ERROR tuple struct `S` is private +46 | xcrate::m::S; //~ ERROR tuple struct `S` is private | ^^^^^^^^^^^^ error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:42:5 + --> $DIR/privacy-struct-ctor.rs:49:5 | -42 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private +49 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private | ^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr index aea9fc356bf2e..3b89c87b36f27 100644 --- a/src/test/ui/resolve/tuple-struct-alias.stderr +++ b/src/test/ui/resolve/tuple-struct-alias.stderr @@ -2,31 +2,25 @@ error[E0423]: expected function, found self type `Self` --> $DIR/tuple-struct-alias.rs:16:17 | 16 | let s = Self(0, 1); //~ ERROR expected function - | ^^^^ did you mean `Self { /* fields */ }`? + | ^^^^ not a function error[E0532]: expected tuple struct/variant, found self type `Self` --> $DIR/tuple-struct-alias.rs:18:13 | 18 | Self(..) => {} //~ ERROR expected tuple struct/variant - | ^^^^ did you mean `Self { /* fields */ }`? + | ^^^^ not a tuple struct/variant error[E0423]: expected function, found type alias `A` --> $DIR/tuple-struct-alias.rs:24:13 | 24 | let s = A(0, 1); //~ ERROR expected function - | ^ - | | - | did you mean `S`? - | did you mean `A { /* fields */ }`? + | ^ did you mean `S`? error[E0532]: expected tuple struct/variant, found type alias `A` --> $DIR/tuple-struct-alias.rs:26:9 | 26 | A(..) => {} //~ ERROR expected tuple struct/variant - | ^ - | | - | did you mean `S`? - | did you mean `A { /* fields */ }`? + | ^ did you mean `S`? error: aborting due to 4 previous errors From ce9ef37fe682e2677f19a73d6a90d34b6085ebdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jan 2018 16:37:14 -0800 Subject: [PATCH 3/8] Readd suggestion in enum variants with incorrect args --- src/librustc_resolve/lib.rs | 12 ++++++++++++ src/test/ui/resolve/issue-18252.stderr | 2 +- src/test/ui/resolve/issue-19452.stderr | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 29ca160fac0db..e21f619d6c37c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2730,6 +2730,18 @@ impl<'a> Resolver<'a> { } return (err, candidates); } + (Def::VariantCtor(_, ctor_kind), _) if ns == ValueNS && is_struct_like(def) => { + let block = match ctor_kind { + CtorKind::Fn => "(/* fields */)", + CtorKind::Fictive => " { /* fields */ }", + def => bug!("found def `{:?}` when looking for a ctor", + def), + }; + err.span_label(span, format!("did you mean `{}{}`?", + path_str, + block)); + return (err, candidates); + } _ => {} } } diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr index f93007c8b6144..edc7196d84645 100644 --- a/src/test/ui/resolve/issue-18252.stderr +++ b/src/test/ui/resolve/issue-18252.stderr @@ -2,7 +2,7 @@ error[E0423]: expected function, found struct variant `Foo::Variant` --> $DIR/issue-18252.rs:16:13 | 16 | let f = Foo::Variant(42); - | ^^^^^^^^^^^^ not a function + | ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`? 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 44690158b587f..7b14d49af51dd 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -2,13 +2,13 @@ error[E0423]: expected value, found struct variant `Homura::Madoka` --> $DIR/issue-19452.rs:19:18 | 19 | let homura = Homura::Madoka; - | ^^^^^^^^^^^^^^ not a value + | ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`? error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka` --> $DIR/issue-19452.rs:22:18 | 22 | let homura = issue_19452_aux::Homura::Madoka; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`? error: aborting due to 2 previous errors From 38546ba9fa5678755c03721efe83425911812ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 1 Jan 2018 21:21:11 -0800 Subject: [PATCH 4/8] Add note when trying to use `Self` as a ctor --- src/librustc_resolve/lib.rs | 6 +++++- src/test/ui/resolve/tuple-struct-alias.stderr | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e21f619d6c37c..d64c3832935c2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -898,7 +898,7 @@ impl<'a> LexicalScopeBinding<'a> { } } -#[derive(Clone)] +#[derive(Clone, Debug)] enum PathResult<'a> { Module(Module<'a>), NonModule(PathResolution), @@ -2742,6 +2742,10 @@ impl<'a> Resolver<'a> { block)); return (err, candidates); } + (Def::SelfTy(_, _), _) if ns == ValueNS && is_struct_like(def) => { + err.note("can't instantiate `Self`, you must use the implemented struct \ + directly"); + } _ => {} } } diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr index 3b89c87b36f27..b5122e04a136c 100644 --- a/src/test/ui/resolve/tuple-struct-alias.stderr +++ b/src/test/ui/resolve/tuple-struct-alias.stderr @@ -3,12 +3,16 @@ error[E0423]: expected function, found self type `Self` | 16 | let s = Self(0, 1); //~ ERROR expected function | ^^^^ not a function + | + = note: can't instantiate `Self`, you must use the implemented struct directly error[E0532]: expected tuple struct/variant, found self type `Self` --> $DIR/tuple-struct-alias.rs:18:13 | 18 | Self(..) => {} //~ ERROR expected tuple struct/variant | ^^^^ not a tuple struct/variant + | + = note: can't instantiate `Self`, you must use the implemented struct directly error[E0423]: expected function, found type alias `A` --> $DIR/tuple-struct-alias.rs:24:13 From 445f339ba95572231d769ee8a2f3b8dc8fff16bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Jan 2018 02:00:56 -0800 Subject: [PATCH 5/8] address review comments --- src/librustc_resolve/lib.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index d64c3832935c2..ca40780bd8103 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2702,7 +2702,7 @@ impl<'a> Resolver<'a> { } return (err, candidates); }, - (Def::Struct(def_id), _) if ns == ValueNS && is_struct_like(def) => { + (Def::Struct(def_id), _) if ns == ValueNS => { if let Some((ctor_def, ctor_vis)) = this.struct_constructors.get(&def_id).cloned() { let accessible_ctor = this.is_accessible(ctor_vis); @@ -2711,14 +2711,10 @@ impl<'a> Resolver<'a> { here due to private fields")); } else if accessible_ctor { let block = match ctor_def { - Def::StructCtor(_, CtorKind::Fn) | - Def::VariantCtor(_, CtorKind::Fn) => "(/* fields */)", - Def::StructCtor(_, CtorKind::Fictive) | - Def::VariantCtor(_, CtorKind::Fictive) => { - " { /* fields */ }" - } - def => bug!("found def `{:?}` when looking for a ctor", - def), + Def::StructCtor(_, CtorKind::Fn) => "(/* fields */)", + Def::StructCtor(_, CtorKind::Const) => "", + Def::Struct(..) => " { /* fields */ }", + def => bug!("found def `{:?}` when looking for a ctor", def), }; err.span_label(span, format!("did you mean `{}{}`?", path_str, @@ -2730,9 +2726,10 @@ impl<'a> Resolver<'a> { } return (err, candidates); } - (Def::VariantCtor(_, ctor_kind), _) if ns == ValueNS && is_struct_like(def) => { + (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { let block = match ctor_kind { CtorKind::Fn => "(/* fields */)", + CtorKind::Const => "", CtorKind::Fictive => " { /* fields */ }", def => bug!("found def `{:?}` when looking for a ctor", def), @@ -2742,9 +2739,9 @@ impl<'a> Resolver<'a> { block)); return (err, candidates); } - (Def::SelfTy(_, _), _) if ns == ValueNS && is_struct_like(def) => { - err.note("can't instantiate `Self`, you must use the implemented struct \ - directly"); + (Def::SelfTy(..), _) if ns == ValueNS { + err.note("can't use `Self` as a constructor, you must use the \ + implemented struct"); } _ => {} } From 4a7691692c517da9a28c1682c48af0d64891c9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Jan 2018 05:18:06 -0800 Subject: [PATCH 6/8] Further tweaks to the output - Properly address Variant Ctors - Show signature if span of trait method without `self` is not available --- src/librustc_resolve/lib.rs | 35 ++- src/librustc_typeck/check/callee.rs | 34 ++- src/librustc_typeck/check/compare_method.rs | 8 +- src/test/compile-fail/E0185.rs | 8 +- src/test/compile-fail/E0618.rs | 6 +- src/test/ui/block-result/issue-20862.stderr | 2 +- src/test/ui/empty-struct-unit-expr.rs | 4 +- src/test/ui/empty-struct-unit-expr.stderr | 37 ++- src/test/ui/issue-10969.stderr | 20 +- src/test/ui/resolve/privacy-enum-ctor.rs | 81 +++++++ src/test/ui/resolve/privacy-enum-ctor.stderr | 225 ++++++++++++++++++ src/test/ui/resolve/privacy-struct-ctor.rs | 17 +- .../ui/resolve/privacy-struct-ctor.stderr | 46 ++-- src/test/ui/resolve/tuple-struct-alias.stderr | 8 +- 14 files changed, 431 insertions(+), 100 deletions(-) create mode 100644 src/test/ui/resolve/privacy-enum-ctor.rs create mode 100644 src/test/ui/resolve/privacy-enum-ctor.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ca40780bd8103..a665caefbc50a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2726,23 +2726,27 @@ impl<'a> Resolver<'a> { } return (err, candidates); } - (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { - let block = match ctor_kind { - CtorKind::Fn => "(/* fields */)", - CtorKind::Const => "", - CtorKind::Fictive => " { /* fields */ }", - def => bug!("found def `{:?}` when looking for a ctor", - def), - }; - err.span_label(span, format!("did you mean `{}{}`?", - path_str, - block)); + (Def::VariantCtor(_, CtorKind::Const), _) => { + err.span_label(span, format!("did you mean `{}`?", path_str)); + return (err, candidates); + } + (Def::VariantCtor(_, CtorKind::Fn), _) => { + err.span_label(span, format!("did you mean `{}( /* fields */ )`?", + path_str)); + return (err, candidates); + } + (Def::VariantCtor(_, CtorKind::Fictive), _) => { + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); return (err, candidates); } - (Def::SelfTy(..), _) if ns == ValueNS { + (Def::SelfTy(..), _) if ns == ValueNS => { err.note("can't use `Self` as a constructor, you must use the \ implemented struct"); } + (Def::TyAlias(_def_id), _) => { + err.note("can't use a type alias as a constructor"); + } _ => {} } } @@ -3994,13 +3998,6 @@ impl<'a> Resolver<'a> { } } -fn is_struct_like(def: Def) -> bool { - match def { - Def::VariantCtor(_, CtorKind::Fictive) => true, - _ => PathSource::Struct.is_expected(def), - } -} - fn is_self_type(path: &[SpannedIdent], namespace: Namespace) -> bool { namespace == TypeNS && path.len() == 1 && path[0].node.name == keywords::SelfType.name() } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index df1694a601056..5c5e5f2735b71 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -210,15 +210,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - let mut err = type_error_struct!(self.tcx.sess, call_expr.span, callee_ty, E0618, - "expected function, found `{}`", - if let Some(ref path) = unit_variant { - path.to_string() - } else { - callee_ty.to_string() - }); - if let Some(path) = unit_variant { - err.help(&format!("did you mean to write `{}`?", path)); + + let mut err = type_error_struct!( + self.tcx.sess, + call_expr.span, + callee_ty, + E0618, + "expected function, found {}", + match unit_variant { + Some(ref path) => format!("enum variant `{}`", path), + None => format!("`{}`", callee_ty), + }); + + err.span_label(call_expr.span, "not a function"); + + if let Some(ref path) = unit_variant { + err.span_suggestion(call_expr.span, + &format!("`{}` is a unit variant, you need to write it \ + without the parenthesis", path), + path.to_string()); } if let hir::ExprCall(ref expr, _) = call_expr.node { @@ -235,7 +245,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => self.tcx.hir.span_if_local(def.def_id()) }; if let Some(span) = def_span { - err.span_note(span, "defined here"); + let name = match unit_variant { + Some(path) => path, + None => callee_ty.to_string(), + }; + err.span_label(span, format!("`{}` defined here", name)); } } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 734287f5f7d29..570eecfc267de 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -518,7 +518,10 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, self_descr); err.span_label(impl_m_span, format!("`{}` used in impl", self_descr)); if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) { - err.span_label(span, format!("trait declared without `{}`", self_descr)); + err.span_label(span, format!("trait method declared without `{}`", self_descr)); + } else { + err.note_trait_signature(trait_m.name.to_string(), + trait_m.signature(&tcx)); } err.emit(); return Err(ErrorReported); @@ -533,8 +536,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, not in the impl", trait_m.name, self_descr); - err.span_label(impl_m_span, - format!("expected `{}` in impl", self_descr)); + err.span_label(impl_m_span, format!("expected `{}` in impl", self_descr)); if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) { err.span_label(span, format!("`{}` used in trait", self_descr)); } else { diff --git a/src/test/compile-fail/E0185.rs b/src/test/compile-fail/E0185.rs index be54c3754ea1f..0cd3d00a73576 100644 --- a/src/test/compile-fail/E0185.rs +++ b/src/test/compile-fail/E0185.rs @@ -9,14 +9,16 @@ // except according to those terms. trait Foo { - fn foo(); //~ trait declared without `&self` + fn foo(); + //~^ NOTE trait method declared without `&self` } struct Bar; impl Foo for Bar { - fn foo(&self) {} //~ ERROR E0185 - //~^ `&self` used in impl + fn foo(&self) {} + //~^ ERROR E0185 + //~| NOTE `&self` used in impl } fn main() { diff --git a/src/test/compile-fail/E0618.rs b/src/test/compile-fail/E0618.rs index f28ac200dea5a..f46bdb9980142 100644 --- a/src/test/compile-fail/E0618.rs +++ b/src/test/compile-fail/E0618.rs @@ -13,7 +13,9 @@ enum X { } fn main() { - X::Entry(); //~ ERROR expected function, found `X::Entry` [E0618] + X::Entry(); + //~^ ERROR expected function, found enum variant `X::Entry` [E0618] let x = 0i32; - x(); //~ ERROR expected function, found `i32` [E0618] + x(); + //~^ ERROR expected function, found `i32` [E0618] } diff --git a/src/test/ui/block-result/issue-20862.stderr b/src/test/ui/block-result/issue-20862.stderr index 7c88d789fd36e..3b4f514de7dca 100644 --- a/src/test/ui/block-result/issue-20862.stderr +++ b/src/test/ui/block-result/issue-20862.stderr @@ -13,7 +13,7 @@ error[E0618]: expected function, found `()` --> $DIR/issue-20862.rs:17:13 | 17 | let x = foo(5)(2); - | ^^^^^^^^^ + | ^^^^^^^^^ not a function error: aborting due to 2 previous errors diff --git a/src/test/ui/empty-struct-unit-expr.rs b/src/test/ui/empty-struct-unit-expr.rs index c33960193b052..941292a7ec27d 100644 --- a/src/test/ui/empty-struct-unit-expr.rs +++ b/src/test/ui/empty-struct-unit-expr.rs @@ -24,8 +24,8 @@ enum E { fn main() { let e2 = Empty2(); //~ ERROR expected function, found `Empty2` let e4 = E::Empty4(); - //~^ ERROR expected function, found `E::Empty4` [E0618] + //~^ ERROR expected function, found enum variant `E::Empty4` [E0618] let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2` let xe4 = XE::XEmpty4(); - //~^ ERROR expected function, found `XE::XEmpty4` [E0618] + //~^ ERROR expected function, found enum variant `XE::XEmpty4` [E0618] } diff --git a/src/test/ui/empty-struct-unit-expr.stderr b/src/test/ui/empty-struct-unit-expr.stderr index 3ce63ed9f423b..aa242a530d0e3 100644 --- a/src/test/ui/empty-struct-unit-expr.stderr +++ b/src/test/ui/empty-struct-unit-expr.stderr @@ -1,41 +1,40 @@ error[E0618]: expected function, found `Empty2` --> $DIR/empty-struct-unit-expr.rs:25:14 | -25 | let e2 = Empty2(); //~ ERROR expected function, found `Empty2` - | ^^^^^^^^ - | -note: defined here - --> $DIR/empty-struct-unit-expr.rs:18:1 - | 18 | struct Empty2; - | ^^^^^^^^^^^^^^ + | -------------- `Empty2` defined here +... +25 | let e2 = Empty2(); //~ ERROR expected function, found `Empty2` + | ^^^^^^^^ not a function -error[E0618]: expected function, found `E::Empty4` +error[E0618]: expected function, found enum variant `E::Empty4` --> $DIR/empty-struct-unit-expr.rs:26:14 | +21 | Empty4 + | ------ `E::Empty4` defined here +... 26 | let e4 = E::Empty4(); - | ^^^^^^^^^^^ - | - = help: did you mean to write `E::Empty4`? -note: defined here - --> $DIR/empty-struct-unit-expr.rs:21:5 + | ^^^^^^^^^^^ not a function +help: `E::Empty4` is a unit variant, you need to write it without the parenthesis | -21 | Empty4 - | ^^^^^^ +26 | let e4 = E::Empty4; + | ^^^^^^^^^ error[E0618]: expected function, found `empty_struct::XEmpty2` --> $DIR/empty-struct-unit-expr.rs:28:15 | 28 | let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2` - | ^^^^^^^^^ + | ^^^^^^^^^ not a function -error[E0618]: expected function, found `XE::XEmpty4` +error[E0618]: expected function, found enum variant `XE::XEmpty4` --> $DIR/empty-struct-unit-expr.rs:29:15 | 29 | let xe4 = XE::XEmpty4(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a function +help: `XE::XEmpty4` is a unit variant, you need to write it without the parenthesis | - = help: did you mean to write `XE::XEmpty4`? +29 | let xe4 = XE::XEmpty4; + | ^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/issue-10969.stderr b/src/test/ui/issue-10969.stderr index 8aea63e0bbdaa..68127b282ed54 100644 --- a/src/test/ui/issue-10969.stderr +++ b/src/test/ui/issue-10969.stderr @@ -1,26 +1,18 @@ error[E0618]: expected function, found `i32` --> $DIR/issue-10969.rs:12:5 | -12 | i(); //~ERROR expected function, found `i32` - | ^^^ - | -note: defined here - --> $DIR/issue-10969.rs:11:9 - | 11 | fn func(i: i32) { - | ^ + | - `i32` defined here +12 | i(); //~ERROR expected function, found `i32` + | ^^^ not a function error[E0618]: expected function, found `i32` --> $DIR/issue-10969.rs:16:5 | -16 | i(); //~ERROR expected function, found `i32` - | ^^^ - | -note: defined here - --> $DIR/issue-10969.rs:15:9 - | 15 | let i = 0i32; - | ^ + | - `i32` defined here +16 | i(); //~ERROR expected function, found `i32` + | ^^^ not a function error: aborting due to 2 previous errors diff --git a/src/test/ui/resolve/privacy-enum-ctor.rs b/src/test/ui/resolve/privacy-enum-ctor.rs new file mode 100644 index 0000000000000..08480a0e1faa8 --- /dev/null +++ b/src/test/ui/resolve/privacy-enum-ctor.rs @@ -0,0 +1,81 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod m { + pub enum E { + Fn(u8), + Struct { + s: u8, + }, + Unit, + } + + pub mod n { + pub(in m) enum Z { + Fn(u8), + Struct { + s: u8, + }, + Unit, + } + } + + use m::n::Z; // OK, only the type is imported + + fn f() { + n::Z; + //~^ ERROR expected value, found enum `n::Z` + Z; + //~^ ERROR expected value, found enum `Z` + let _: Z = Z::Fn; + //~^ ERROR mismatched types + let _: Z = Z::Struct; + //~^ ERROR expected value, found struct variant `Z::Struct` + let _ = Z::Unit(); + //~^ ERROR expected function, found enum variant `Z::Unit` + let _ = Z::Unit {}; + // This is ok, it is equivalent to not having braces + } +} + +use m::E; // OK, only the type is imported + +fn main() { + let _: E = m::E; + //~^ ERROR expected value, found enum `m::E` + let _: E = m::E::Fn; + //~^ ERROR mismatched types + let _: E = m::E::Struct; + //~^ ERROR expected value, found struct variant `m::E::Struct` + let _: E = m::E::Unit(); + //~^ ERROR expected function, found enum variant `m::E::Unit` + let _: E = E; + //~^ ERROR expected value, found enum `E` + let _: E = E::Fn; + //~^ ERROR mismatched types + let _: E = E::Struct; + //~^ ERROR expected value, found struct variant `E::Struct` + let _: E = E::Unit(); + //~^ ERROR expected function, found enum variant `E::Unit` + let _: Z = m::n::Z; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR expected value, found enum `m::n::Z` + //~| ERROR enum `Z` is private + let _: Z = m::n::Z::Fn; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR enum `Z` is private + let _: Z = m::n::Z::Struct; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR expected value, found struct variant `m::n::Z::Struct` + //~| ERROR enum `Z` is private + let _: Z = m::n::Z::Unit {}; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR enum `Z` is private +} diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr new file mode 100644 index 0000000000000..c4f6d1f5b7407 --- /dev/null +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -0,0 +1,225 @@ +error[E0423]: expected value, found enum `n::Z` + --> $DIR/privacy-enum-ctor.rs:33:9 + | +33 | n::Z; + | ^^^^ + | + = note: did you mean to use one of the following variants? + - `m::Z::Fn` + - `m::Z::Struct` + - `m::Z::Unit` + +error[E0423]: expected value, found enum `Z` + --> $DIR/privacy-enum-ctor.rs:35:9 + | +35 | Z; + | ^ did you mean `f`? + | + = note: did you mean to use one of the following variants? + - `m::Z::Fn` + - `m::Z::Struct` + - `m::Z::Unit` + +error[E0423]: expected value, found struct variant `Z::Struct` + --> $DIR/privacy-enum-ctor.rs:39:20 + | +39 | let _: Z = Z::Struct; + | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`? + +error[E0423]: expected value, found enum `m::E` + --> $DIR/privacy-enum-ctor.rs:51:16 + | +51 | let _: E = m::E; + | ^^^- + | | + | did you mean `f`? + | + = note: did you mean to use one of the following variants? + - `E::Fn` + - `E::Struct` + - `E::Unit` +help: possible better candidates are found in other modules, you can import them into scope + | +48 | use std::f32::consts::E; + | +48 | use std::f64::consts::E; + | + +error[E0423]: expected value, found struct variant `m::E::Struct` + --> $DIR/privacy-enum-ctor.rs:55:16 + | +55 | let _: E = m::E::Struct; + | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`? + +error[E0423]: expected value, found enum `E` + --> $DIR/privacy-enum-ctor.rs:59:16 + | +59 | let _: E = E; + | ^ + | + = note: did you mean to use one of the following variants? + - `E::Fn` + - `E::Struct` + - `E::Unit` +help: possible better candidates are found in other modules, you can import them into scope + | +48 | use std::f32::consts::E; + | +48 | use std::f64::consts::E; + | + +error[E0423]: expected value, found struct variant `E::Struct` + --> $DIR/privacy-enum-ctor.rs:63:16 + | +63 | let _: E = E::Struct; + | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`? + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:67:12 + | +67 | let _: Z = m::n::Z; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0423]: expected value, found enum `m::n::Z` + --> $DIR/privacy-enum-ctor.rs:67:16 + | +67 | let _: Z = m::n::Z; + | ^^^^^^^ + | + = note: did you mean to use one of the following variants? + - `m::Z::Fn` + - `m::Z::Struct` + - `m::Z::Unit` + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:71:12 + | +71 | let _: Z = m::n::Z::Fn; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:74:12 + | +74 | let _: Z = m::n::Z::Struct; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0423]: expected value, found struct variant `m::n::Z::Struct` + --> $DIR/privacy-enum-ctor.rs:74:16 + | +74 | let _: Z = m::n::Z::Struct; + | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`? + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:78:12 + | +78 | let _: Z = m::n::Z::Unit {}; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:67:16 + | +67 | let _: Z = m::n::Z; + | ^^^^^^^ + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:71:16 + | +71 | let _: Z = m::n::Z::Fn; + | ^^^^^^^^^^^ + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:74:16 + | +74 | let _: Z = m::n::Z::Struct; + | ^^^^^^^^^^^^^^^ + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:78:16 + | +78 | let _: Z = m::n::Z::Unit {}; + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/privacy-enum-ctor.rs:37:20 + | +37 | let _: Z = Z::Fn; + | ^^^^^ expected enum `m::n::Z`, found fn item + | + = note: expected type `m::n::Z` + found type `fn(u8) -> m::n::Z {m::n::Z::Fn}` + +error[E0618]: expected function, found enum variant `Z::Unit` + --> $DIR/privacy-enum-ctor.rs:41:17 + | +26 | Unit, + | ---- `Z::Unit` defined here +... +41 | let _ = Z::Unit(); + | ^^^^^^^^^ not a function +help: `Z::Unit` is a unit variant, you need to write it without the parenthesis + | +41 | let _ = Z::Unit; + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/privacy-enum-ctor.rs:53:16 + | +53 | let _: E = m::E::Fn; + | ^^^^^^^^ expected enum `m::E`, found fn item + | + = note: expected type `m::E` + found type `fn(u8) -> m::E {m::E::Fn}` + +error[E0618]: expected function, found enum variant `m::E::Unit` + --> $DIR/privacy-enum-ctor.rs:57:16 + | +17 | Unit, + | ---- `m::E::Unit` defined here +... +57 | let _: E = m::E::Unit(); + | ^^^^^^^^^^^^ not a function +help: `m::E::Unit` is a unit variant, you need to write it without the parenthesis + | +57 | let _: E = m::E::Unit; + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/privacy-enum-ctor.rs:61:16 + | +61 | let _: E = E::Fn; + | ^^^^^ expected enum `m::E`, found fn item + | + = note: expected type `m::E` + found type `fn(u8) -> m::E {m::E::Fn}` + +error[E0618]: expected function, found enum variant `E::Unit` + --> $DIR/privacy-enum-ctor.rs:65:16 + | +17 | Unit, + | ---- `E::Unit` defined here +... +65 | let _: E = E::Unit(); + | ^^^^^^^^^ not a function +help: `E::Unit` is a unit variant, you need to write it without the parenthesis + | +65 | let _: E = E::Unit; + | ^^^^^^^ + +error: aborting due to 23 previous errors + diff --git a/src/test/ui/resolve/privacy-struct-ctor.rs b/src/test/ui/resolve/privacy-struct-ctor.rs index 821a51e9427d3..9029eeb22cd27 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.rs +++ b/src/test/ui/resolve/privacy-struct-ctor.rs @@ -25,7 +25,8 @@ mod m { use m::n::Z; // OK, only the type is imported fn f() { - n::Z; //~ ERROR tuple struct `Z` is private + n::Z; + //~^ ERROR tuple struct `Z` is private Z; //~^ ERROR expected value, found struct `Z` } @@ -35,16 +36,22 @@ use m::S; // OK, only the type is imported use m::S2; // OK, only the type is imported fn main() { - m::S; //~ ERROR tuple struct `S` is private + m::S; + //~^ ERROR tuple struct `S` is private + let _: S = m::S(2); + //~^ ERROR tuple struct `S` is private S; //~^ ERROR expected value, found struct `S` - m::n::Z; //~ ERROR tuple struct `Z` is private + m::n::Z; + //~^ ERROR tuple struct `Z` is private S2; //~^ ERROR expected value, found struct `S2` - xcrate::m::S; //~ ERROR tuple struct `S` is private + xcrate::m::S; + //~^ ERROR tuple struct `S` is private xcrate::S; //~^ ERROR expected value, found struct `xcrate::S` - xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private + xcrate::m::n::Z; + //~^ ERROR tuple struct `Z` is private } diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index e274ac02c5739..e97a4e4143cc3 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -1,7 +1,7 @@ error[E0423]: expected value, found struct `Z` - --> $DIR/privacy-struct-ctor.rs:29:9 + --> $DIR/privacy-struct-ctor.rs:30:9 | -29 | Z; +30 | Z; | ^ | | | did you mean `S`? @@ -12,60 +12,66 @@ help: possible better candidate is found in another module, you can import it in | error[E0423]: expected value, found struct `S` - --> $DIR/privacy-struct-ctor.rs:39:5 + --> $DIR/privacy-struct-ctor.rs:43:5 | -39 | S; +43 | S; | ^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | -34 | use m::S; +35 | use m::S; | error[E0423]: expected value, found struct `S2` - --> $DIR/privacy-struct-ctor.rs:43:5 + --> $DIR/privacy-struct-ctor.rs:48:5 | -43 | S2; +48 | S2; | ^^ did you mean `S2 { /* fields */ }`? error[E0423]: expected value, found struct `xcrate::S` - --> $DIR/privacy-struct-ctor.rs:47:5 + --> $DIR/privacy-struct-ctor.rs:53:5 | -47 | xcrate::S; +53 | xcrate::S; | ^^^^^^^^^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | -34 | use m::S; +35 | use m::S; | error[E0603]: tuple struct `Z` is private --> $DIR/privacy-struct-ctor.rs:28:9 | -28 | n::Z; //~ ERROR tuple struct `Z` is private +28 | n::Z; | ^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:38:5 + --> $DIR/privacy-struct-ctor.rs:39:5 | -38 | m::S; //~ ERROR tuple struct `S` is private +39 | m::S; | ^^^^ +error[E0603]: tuple struct `S` is private + --> $DIR/privacy-struct-ctor.rs:41:16 + | +41 | let _: S = m::S(2); + | ^^^^ + error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:41:5 + --> $DIR/privacy-struct-ctor.rs:45:5 | -41 | m::n::Z; //~ ERROR tuple struct `Z` is private +45 | m::n::Z; | ^^^^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:46:5 + --> $DIR/privacy-struct-ctor.rs:51:5 | -46 | xcrate::m::S; //~ ERROR tuple struct `S` is private +51 | xcrate::m::S; | ^^^^^^^^^^^^ error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:49:5 + --> $DIR/privacy-struct-ctor.rs:55:5 | -49 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private +55 | xcrate::m::n::Z; | ^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr index b5122e04a136c..843d7c20ffd2c 100644 --- a/src/test/ui/resolve/tuple-struct-alias.stderr +++ b/src/test/ui/resolve/tuple-struct-alias.stderr @@ -4,7 +4,7 @@ error[E0423]: expected function, found self type `Self` 16 | let s = Self(0, 1); //~ ERROR expected function | ^^^^ not a function | - = note: can't instantiate `Self`, you must use the implemented struct directly + = note: can't use `Self` as a constructor, you must use the implemented struct error[E0532]: expected tuple struct/variant, found self type `Self` --> $DIR/tuple-struct-alias.rs:18:13 @@ -12,19 +12,23 @@ error[E0532]: expected tuple struct/variant, found self type `Self` 18 | Self(..) => {} //~ ERROR expected tuple struct/variant | ^^^^ not a tuple struct/variant | - = note: can't instantiate `Self`, you must use the implemented struct directly + = note: can't use `Self` as a constructor, you must use the implemented struct error[E0423]: expected function, found type alias `A` --> $DIR/tuple-struct-alias.rs:24:13 | 24 | let s = A(0, 1); //~ ERROR expected function | ^ did you mean `S`? + | + = note: can't use a type alias as a constructor error[E0532]: expected tuple struct/variant, found type alias `A` --> $DIR/tuple-struct-alias.rs:26:9 | 26 | A(..) => {} //~ ERROR expected tuple struct/variant | ^ did you mean `S`? + | + = note: can't use a type alias as a constructor error: aborting due to 4 previous errors From 282f75a4ced2b859b10779ea91d7e889ddfdc659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Jan 2018 15:02:53 -0800 Subject: [PATCH 7/8] Review comments: remove enum suggestion --- src/librustc_resolve/lib.rs | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a665caefbc50a..889b6de7bfa81 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2709,16 +2709,6 @@ impl<'a> Resolver<'a> { if is_expected(ctor_def) && !accessible_ctor { err.span_label(span, format!("constructor is not visible \ here due to private fields")); - } else if accessible_ctor { - let block = match ctor_def { - Def::StructCtor(_, CtorKind::Fn) => "(/* fields */)", - Def::StructCtor(_, CtorKind::Const) => "", - Def::Struct(..) => " { /* fields */ }", - def => bug!("found def `{:?}` when looking for a ctor", def), - }; - err.span_label(span, format!("did you mean `{}{}`?", - path_str, - block)); } } else { err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", @@ -2726,26 +2716,14 @@ impl<'a> Resolver<'a> { } return (err, candidates); } - (Def::VariantCtor(_, CtorKind::Const), _) => { - err.span_label(span, format!("did you mean `{}`?", path_str)); - return (err, candidates); - } - (Def::VariantCtor(_, CtorKind::Fn), _) => { - err.span_label(span, format!("did you mean `{}( /* fields */ )`?", - path_str)); - return (err, candidates); - } - (Def::VariantCtor(_, CtorKind::Fictive), _) => { - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", - path_str)); - return (err, candidates); - } (Def::SelfTy(..), _) if ns == ValueNS => { err.note("can't use `Self` as a constructor, you must use the \ implemented struct"); + return (err, candidates); } - (Def::TyAlias(_def_id), _) => { + (Def::TyAlias(_), _) if ns == ValueNS => { err.note("can't use a type alias as a constructor"); + return (err, candidates); } _ => {} } From 067405044cb682f1d01c8665e81287c23dd3655f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 20 Jan 2018 12:02:40 -0800 Subject: [PATCH 8/8] Fix tests by keepeing needed suggestions --- src/librustc_resolve/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 889b6de7bfa81..dcd9d3e871323 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2716,12 +2716,20 @@ impl<'a> Resolver<'a> { } return (err, candidates); } + (Def::Union(..), _) | + (Def::Variant(..), _) | + (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); + return (err, candidates); + } (Def::SelfTy(..), _) if ns == ValueNS => { + err.span_label(span, fallback_label); err.note("can't use `Self` as a constructor, you must use the \ implemented struct"); return (err, candidates); } - (Def::TyAlias(_), _) if ns == ValueNS => { + (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { err.note("can't use a type alias as a constructor"); return (err, candidates); }