Be more precise when suggesting removal of parens on unit adt ctor
This commit is contained in:
parent
7210e46dc6
commit
04c590b7ef
12 changed files with 86 additions and 39 deletions
|
@ -4,7 +4,7 @@ use crate::type_error_struct;
|
||||||
|
|
||||||
use rustc_errors::{struct_span_err, Applicability, Diagnostic};
|
use rustc_errors::{struct_span_err, Applicability, Diagnostic};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{Namespace, Res};
|
use rustc_hir::def::{self, Namespace, Res};
|
||||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc_infer::{
|
use rustc_infer::{
|
||||||
infer,
|
infer,
|
||||||
|
@ -390,17 +390,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
(fn_sig, Some(def_id))
|
(fn_sig, Some(def_id))
|
||||||
}
|
}
|
||||||
ty::FnPtr(sig) => (sig, None),
|
ty::FnPtr(sig) => (sig, None),
|
||||||
ref t => {
|
_ => {
|
||||||
let mut unit_variant = None;
|
let mut unit_variant = None;
|
||||||
let mut removal_span = call_expr.span;
|
if let hir::ExprKind::Path(qpath) = &callee_expr.kind
|
||||||
if let ty::Adt(adt_def, ..) = t
|
&& let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _)
|
||||||
&& adt_def.is_enum()
|
= self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
|
||||||
&& let hir::ExprKind::Call(expr, _) = call_expr.kind
|
// Only suggest removing parens if there are no arguments
|
||||||
|
&& arg_exprs.is_empty()
|
||||||
|
&& let Ok(path) = self.tcx.sess.source_map().span_to_snippet(callee_expr.span)
|
||||||
{
|
{
|
||||||
removal_span =
|
let descr = match kind {
|
||||||
expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
|
def::CtorOf::Struct => "struct",
|
||||||
|
def::CtorOf::Variant => "enum variant",
|
||||||
|
};
|
||||||
|
let removal_span =
|
||||||
|
callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
|
||||||
unit_variant =
|
unit_variant =
|
||||||
self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
|
Some((removal_span, descr, path));
|
||||||
}
|
}
|
||||||
|
|
||||||
let callee_ty = self.resolve_vars_if_possible(callee_ty);
|
let callee_ty = self.resolve_vars_if_possible(callee_ty);
|
||||||
|
@ -410,8 +416,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
callee_ty,
|
callee_ty,
|
||||||
E0618,
|
E0618,
|
||||||
"expected function, found {}",
|
"expected function, found {}",
|
||||||
match unit_variant {
|
match &unit_variant {
|
||||||
Some(ref path) => format!("enum variant `{path}`"),
|
Some((_, kind, path)) => format!("{kind} `{path}`"),
|
||||||
None => format!("`{callee_ty}`"),
|
None => format!("`{callee_ty}`"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -423,11 +429,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
callee_expr.span,
|
callee_expr.span,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(ref path) = unit_variant {
|
if let Some((removal_span, kind, path)) = &unit_variant {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
removal_span,
|
*removal_span,
|
||||||
&format!(
|
&format!(
|
||||||
"`{path}` is a unit variant, you need to write it without the parentheses",
|
"`{path}` is a unit {kind}, and does not take parentheses to be constructed",
|
||||||
),
|
),
|
||||||
"",
|
"",
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
|
@ -470,7 +476,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
if let Some(span) = self.tcx.hir().res_span(def) {
|
if let Some(span) = self.tcx.hir().res_span(def) {
|
||||||
let callee_ty = callee_ty.to_string();
|
let callee_ty = callee_ty.to_string();
|
||||||
let label = match (unit_variant, inner_callee_path) {
|
let label = match (unit_variant, inner_callee_path) {
|
||||||
(Some(path), _) => Some(format!("`{path}` defined here")),
|
(Some((_, kind, path)), _) => Some(format!("{kind} `{path}` defined here")),
|
||||||
(_, Some(hir::QPath::Resolved(_, path))) => self
|
(_, Some(hir::QPath::Resolved(_, path))) => self
|
||||||
.tcx
|
.tcx
|
||||||
.sess
|
.sess
|
||||||
|
|
|
@ -12,10 +12,10 @@ enum E {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let e2 = Empty2(); //~ ERROR expected function, found `Empty2`
|
let e2 = Empty2(); //~ ERROR expected function, found struct `Empty2`
|
||||||
let e4 = E::Empty4();
|
let e4 = E::Empty4();
|
||||||
//~^ ERROR expected function, found enum variant `E::Empty4` [E0618]
|
//~^ ERROR expected function, found enum variant `E::Empty4` [E0618]
|
||||||
let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2`
|
let xe2 = XEmpty2(); //~ ERROR expected function, found struct `XEmpty2`
|
||||||
let xe4 = XE::XEmpty4();
|
let xe4 = XE::XEmpty4();
|
||||||
//~^ ERROR expected function, found enum variant `XE::XEmpty4` [E0618]
|
//~^ ERROR expected function, found enum variant `XE::XEmpty4` [E0618]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,50 @@
|
||||||
error[E0618]: expected function, found `Empty2`
|
error[E0618]: expected function, found struct `Empty2`
|
||||||
--> $DIR/empty-struct-unit-expr.rs:15:14
|
--> $DIR/empty-struct-unit-expr.rs:15:14
|
||||||
|
|
|
|
||||||
LL | struct Empty2;
|
LL | struct Empty2;
|
||||||
| ------------- `Empty2` defined here
|
| ------------- struct `Empty2` defined here
|
||||||
...
|
...
|
||||||
LL | let e2 = Empty2();
|
LL | let e2 = Empty2();
|
||||||
| ^^^^^^--
|
| ^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
||||||
|
help: `Empty2` is a unit struct, and does not take parentheses to be constructed
|
||||||
|
|
|
||||||
|
LL - let e2 = Empty2();
|
||||||
|
LL + let e2 = Empty2;
|
||||||
|
|
|
||||||
|
|
||||||
error[E0618]: expected function, found enum variant `E::Empty4`
|
error[E0618]: expected function, found enum variant `E::Empty4`
|
||||||
--> $DIR/empty-struct-unit-expr.rs:16:14
|
--> $DIR/empty-struct-unit-expr.rs:16:14
|
||||||
|
|
|
|
||||||
LL | Empty4
|
LL | Empty4
|
||||||
| ------ `E::Empty4` defined here
|
| ------ enum variant `E::Empty4` defined here
|
||||||
...
|
...
|
||||||
LL | let e4 = E::Empty4();
|
LL | let e4 = E::Empty4();
|
||||||
| ^^^^^^^^^--
|
| ^^^^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
|
||||||
help: `E::Empty4` is a unit variant, you need to write it without the parentheses
|
help: `E::Empty4` is a unit enum variant, and does not take parentheses to be constructed
|
||||||
|
|
|
|
||||||
LL - let e4 = E::Empty4();
|
LL - let e4 = E::Empty4();
|
||||||
LL + let e4 = E::Empty4;
|
LL + let e4 = E::Empty4;
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0618]: expected function, found `empty_struct::XEmpty2`
|
error[E0618]: expected function, found struct `XEmpty2`
|
||||||
--> $DIR/empty-struct-unit-expr.rs:18:15
|
--> $DIR/empty-struct-unit-expr.rs:18:15
|
||||||
|
|
|
|
||||||
LL | let xe2 = XEmpty2();
|
LL | let xe2 = XEmpty2();
|
||||||
| ^^^^^^^--
|
| ^^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
||||||
|
help: `XEmpty2` is a unit struct, and does not take parentheses to be constructed
|
||||||
|
|
|
||||||
|
LL - let xe2 = XEmpty2();
|
||||||
|
LL + let xe2 = XEmpty2;
|
||||||
|
|
|
||||||
|
|
||||||
error[E0618]: expected function, found enum variant `XE::XEmpty4`
|
error[E0618]: expected function, found enum variant `XE::XEmpty4`
|
||||||
--> $DIR/empty-struct-unit-expr.rs:19:15
|
--> $DIR/empty-struct-unit-expr.rs:19:15
|
||||||
|
@ -42,7 +54,7 @@ LL | let xe4 = XE::XEmpty4();
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
|
||||||
help: `XE::XEmpty4` is a unit variant, you need to write it without the parentheses
|
help: `XE::XEmpty4` is a unit enum variant, and does not take parentheses to be constructed
|
||||||
|
|
|
|
||||||
LL - let xe4 = XE::XEmpty4();
|
LL - let xe4 = XE::XEmpty4();
|
||||||
LL + let xe4 = XE::XEmpty4;
|
LL + let xe4 = XE::XEmpty4;
|
||||||
|
|
|
@ -2,14 +2,14 @@ error[E0618]: expected function, found enum variant `X::Entry`
|
||||||
--> $DIR/E0618.rs:6:5
|
--> $DIR/E0618.rs:6:5
|
||||||
|
|
|
|
||||||
LL | Entry,
|
LL | Entry,
|
||||||
| ----- `X::Entry` defined here
|
| ----- enum variant `X::Entry` defined here
|
||||||
...
|
...
|
||||||
LL | X::Entry();
|
LL | X::Entry();
|
||||||
| ^^^^^^^^--
|
| ^^^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
|
||||||
help: `X::Entry` is a unit variant, you need to write it without the parentheses
|
help: `X::Entry` is a unit enum variant, and does not take parentheses to be constructed
|
||||||
|
|
|
|
||||||
LL - X::Entry();
|
LL - X::Entry();
|
||||||
LL + X::Entry;
|
LL + X::Entry;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
struct G;
|
struct G;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let g = G(); //~ ERROR: expected function, found `G`
|
let g = G(); //~ ERROR: expected function, found struct `G`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
error[E0618]: expected function, found `G`
|
error[E0618]: expected function, found struct `G`
|
||||||
--> $DIR/issue-20714.rs:4:13
|
--> $DIR/issue-20714.rs:4:13
|
||||||
|
|
|
|
||||||
LL | struct G;
|
LL | struct G;
|
||||||
| -------- `G` defined here
|
| -------- struct `G` defined here
|
||||||
...
|
...
|
||||||
LL | let g = G();
|
LL | let g = G();
|
||||||
| ^--
|
| ^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
||||||
|
help: `G` is a unit struct, and does not take parentheses to be constructed
|
||||||
|
|
|
||||||
|
LL - let g = G();
|
||||||
|
LL + let g = G;
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct Bar;
|
||||||
|
|
||||||
pub fn some_func() {
|
pub fn some_func() {
|
||||||
let f = Bar();
|
let f = Bar();
|
||||||
//~^ ERROR: expected function, found `Bar`
|
//~^ ERROR: expected function, found struct `Bar`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -8,16 +8,22 @@ LL | let y = t();
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
||||||
error[E0618]: expected function, found `Bar`
|
error[E0618]: expected function, found struct `Bar`
|
||||||
--> $DIR/issue-21701.rs:9:13
|
--> $DIR/issue-21701.rs:9:13
|
||||||
|
|
|
|
||||||
LL | struct Bar;
|
LL | struct Bar;
|
||||||
| ---------- `Bar` defined here
|
| ---------- struct `Bar` defined here
|
||||||
...
|
...
|
||||||
LL | let f = Bar();
|
LL | let f = Bar();
|
||||||
| ^^^--
|
| ^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
||||||
|
help: `Bar` is a unit struct, and does not take parentheses to be constructed
|
||||||
|
|
|
||||||
|
LL - let f = Bar();
|
||||||
|
LL + let f = Bar;
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -336,14 +336,14 @@ error[E0618]: expected function, found enum variant `Z::Unit`
|
||||||
--> $DIR/privacy-enum-ctor.rs:31:17
|
--> $DIR/privacy-enum-ctor.rs:31:17
|
||||||
|
|
|
|
||||||
LL | Unit,
|
LL | Unit,
|
||||||
| ---- `Z::Unit` defined here
|
| ---- enum variant `Z::Unit` defined here
|
||||||
...
|
...
|
||||||
LL | let _ = Z::Unit();
|
LL | let _ = Z::Unit();
|
||||||
| ^^^^^^^--
|
| ^^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
|
||||||
help: `Z::Unit` is a unit variant, you need to write it without the parentheses
|
help: `Z::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
||||||
|
|
|
|
||||||
LL - let _ = Z::Unit();
|
LL - let _ = Z::Unit();
|
||||||
LL + let _ = Z::Unit;
|
LL + let _ = Z::Unit;
|
||||||
|
@ -371,14 +371,14 @@ error[E0618]: expected function, found enum variant `m::E::Unit`
|
||||||
--> $DIR/privacy-enum-ctor.rs:47:16
|
--> $DIR/privacy-enum-ctor.rs:47:16
|
||||||
|
|
|
|
||||||
LL | Unit,
|
LL | Unit,
|
||||||
| ---- `m::E::Unit` defined here
|
| ---- enum variant `m::E::Unit` defined here
|
||||||
...
|
...
|
||||||
LL | let _: E = m::E::Unit();
|
LL | let _: E = m::E::Unit();
|
||||||
| ^^^^^^^^^^--
|
| ^^^^^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
|
||||||
help: `m::E::Unit` is a unit variant, you need to write it without the parentheses
|
help: `m::E::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
||||||
|
|
|
|
||||||
LL - let _: E = m::E::Unit();
|
LL - let _: E = m::E::Unit();
|
||||||
LL + let _: E = m::E::Unit;
|
LL + let _: E = m::E::Unit;
|
||||||
|
@ -406,14 +406,14 @@ error[E0618]: expected function, found enum variant `E::Unit`
|
||||||
--> $DIR/privacy-enum-ctor.rs:55:16
|
--> $DIR/privacy-enum-ctor.rs:55:16
|
||||||
|
|
|
|
||||||
LL | Unit,
|
LL | Unit,
|
||||||
| ---- `E::Unit` defined here
|
| ---- enum variant `E::Unit` defined here
|
||||||
...
|
...
|
||||||
LL | let _: E = E::Unit();
|
LL | let _: E = E::Unit();
|
||||||
| ^^^^^^^--
|
| ^^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
|
||||||
help: `E::Unit` is a unit variant, you need to write it without the parentheses
|
help: `E::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
||||||
|
|
|
|
||||||
LL - let _: E = E::Unit();
|
LL - let _: E = E::Unit();
|
||||||
LL + let _: E = E::Unit;
|
LL + let _: E = E::Unit;
|
||||||
|
|
6
src/test/ui/suggestions/issue-99240.rs
Normal file
6
src/test/ui/suggestions/issue-99240.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn fmt(it: &(std::cell::Cell<Option<impl FnOnce()>>,)) {
|
||||||
|
(it.0.take())()
|
||||||
|
//~^ ERROR expected function
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
11
src/test/ui/suggestions/issue-99240.stderr
Normal file
11
src/test/ui/suggestions/issue-99240.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
error[E0618]: expected function, found `Option<impl FnOnce()>`
|
||||||
|
--> $DIR/issue-99240.rs:2:5
|
||||||
|
|
|
||||||
|
LL | (it.0.take())()
|
||||||
|
| ^^^^^^^^^^^^^--
|
||||||
|
| |
|
||||||
|
| call expression requires function
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0618`.
|
|
@ -20,14 +20,14 @@ error[E0618]: expected function, found enum variant `Alias::Unit`
|
||||||
--> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5
|
--> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5
|
||||||
|
|
|
|
||||||
LL | enum Enum { Braced {}, Unit, Tuple() }
|
LL | enum Enum { Braced {}, Unit, Tuple() }
|
||||||
| ---- `Alias::Unit` defined here
|
| ---- enum variant `Alias::Unit` defined here
|
||||||
...
|
...
|
||||||
LL | Alias::Unit();
|
LL | Alias::Unit();
|
||||||
| ^^^^^^^^^^^--
|
| ^^^^^^^^^^^--
|
||||||
| |
|
| |
|
||||||
| call expression requires function
|
| call expression requires function
|
||||||
|
|
|
|
||||||
help: `Alias::Unit` is a unit variant, you need to write it without the parentheses
|
help: `Alias::Unit` is a unit enum variant, and does not take parentheses to be constructed
|
||||||
|
|
|
|
||||||
LL - Alias::Unit();
|
LL - Alias::Unit();
|
||||||
LL + Alias::Unit;
|
LL + Alias::Unit;
|
||||||
|
|
Loading…
Add table
Reference in a new issue