Rollup merge of #99350 - compiler-errors:issue-99240, r=fee1-dead
Be more precise when suggesting removal of parens on unit ctor * Fixes #99240 by only suggesting to remove parens on path exprs, not arbitrary expressions with enum type * Generalizes by suggesting removal of parens on unit struct, too, because why not?
This commit is contained in:
commit
cc35c787aa
20 changed files with 136 additions and 52 deletions
|
@ -211,6 +211,10 @@ pub fn path_to_string(segment: &hir::Path<'_>) -> String {
|
|||
to_string(NO_ANN, |s| s.print_path(segment, false))
|
||||
}
|
||||
|
||||
pub fn qpath_to_string(segment: &hir::QPath<'_>) -> String {
|
||||
to_string(NO_ANN, |s| s.print_qpath(segment, false))
|
||||
}
|
||||
|
||||
pub fn fn_to_string(
|
||||
decl: &hir::FnDecl<'_>,
|
||||
header: hir::FnHeader,
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::type_error_struct;
|
|||
|
||||
use rustc_errors::{struct_span_err, Applicability, Diagnostic};
|
||||
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_infer::{
|
||||
infer,
|
||||
|
@ -390,17 +390,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
(fn_sig, Some(def_id))
|
||||
}
|
||||
ty::FnPtr(sig) => (sig, None),
|
||||
ref t => {
|
||||
_ => {
|
||||
let mut unit_variant = None;
|
||||
let mut removal_span = call_expr.span;
|
||||
if let ty::Adt(adt_def, ..) = t
|
||||
&& adt_def.is_enum()
|
||||
&& let hir::ExprKind::Call(expr, _) = call_expr.kind
|
||||
if let hir::ExprKind::Path(qpath) = &callee_expr.kind
|
||||
&& let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _)
|
||||
= self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
|
||||
// Only suggest removing parens if there are no arguments
|
||||
&& arg_exprs.is_empty()
|
||||
{
|
||||
removal_span =
|
||||
expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
|
||||
let descr = match kind {
|
||||
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 =
|
||||
self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
|
||||
Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(qpath)));
|
||||
}
|
||||
|
||||
let callee_ty = self.resolve_vars_if_possible(callee_ty);
|
||||
|
@ -410,8 +415,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
callee_ty,
|
||||
E0618,
|
||||
"expected function, found {}",
|
||||
match unit_variant {
|
||||
Some(ref path) => format!("enum variant `{path}`"),
|
||||
match &unit_variant {
|
||||
Some((_, kind, path)) => format!("{kind} `{path}`"),
|
||||
None => format!("`{callee_ty}`"),
|
||||
}
|
||||
);
|
||||
|
@ -423,11 +428,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
callee_expr.span,
|
||||
);
|
||||
|
||||
if let Some(ref path) = unit_variant {
|
||||
if let Some((removal_span, kind, path)) = &unit_variant {
|
||||
err.span_suggestion_verbose(
|
||||
removal_span,
|
||||
*removal_span,
|
||||
&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,
|
||||
|
@ -470,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if let Some(span) = self.tcx.hir().res_span(def) {
|
||||
let callee_ty = callee_ty.to_string();
|
||||
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
|
||||
.tcx
|
||||
.sess
|
||||
|
|
|
@ -531,7 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
tcx.ty_error()
|
||||
}
|
||||
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
|
||||
report_unexpected_variant_res(tcx, res, expr.span);
|
||||
report_unexpected_variant_res(tcx, res, qpath, expr.span);
|
||||
tcx.ty_error()
|
||||
}
|
||||
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
|
||||
|
|
|
@ -863,17 +863,14 @@ fn bad_non_zero_sized_fields<'tcx>(
|
|||
err.emit();
|
||||
}
|
||||
|
||||
fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
|
||||
fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'_>, span: Span) {
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
E0533,
|
||||
"expected unit struct, unit variant or constant, found {}{}",
|
||||
"expected unit struct, unit variant or constant, found {} `{}`",
|
||||
res.descr(),
|
||||
tcx.sess
|
||||
.source_map()
|
||||
.span_to_snippet(span)
|
||||
.map_or_else(|_| String::new(), |s| format!(" `{s}`",)),
|
||||
rustc_hir_pretty::qpath_to_string(qpath),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
|
|
@ -183,7 +183,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
|
||||
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti)
|
||||
}
|
||||
PatKind::Path(_) => self.check_pat_path(pat, path_res.unwrap(), expected, ti),
|
||||
PatKind::Path(ref qpath) => {
|
||||
self.check_pat_path(pat, qpath, path_res.unwrap(), expected, ti)
|
||||
}
|
||||
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
|
||||
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, def_bm, ti)
|
||||
}
|
||||
|
@ -800,6 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
fn check_pat_path<'b>(
|
||||
&self,
|
||||
pat: &Pat<'_>,
|
||||
qpath: &hir::QPath<'_>,
|
||||
path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment<'b>]),
|
||||
expected: Ty<'tcx>,
|
||||
ti: TopInfo<'tcx>,
|
||||
|
@ -814,7 +817,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
return tcx.ty_error();
|
||||
}
|
||||
Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
|
||||
report_unexpected_variant_res(tcx, res, pat.span);
|
||||
report_unexpected_variant_res(tcx, res, qpath, pat.span);
|
||||
return tcx.ty_error();
|
||||
}
|
||||
Res::SelfCtor(..)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue