-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not suggest unresolvable builder methods #125397
Conversation
&& self | ||
.probe_for_name( | ||
Mode::Path, | ||
item.ident(self.tcx), | ||
None, | ||
IsSuggestion(false), | ||
rcvr_ty, | ||
expr_id, | ||
ProbeScope::TraitsInScope, | ||
) | ||
.is_ok() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the extra check I have added. Hopefully it isn't a performance concern as it will run only during diagnostics and only for builder methods not all the assoc items of an impl.
@@ -191,6 +191,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||
rcvr_opt: Option<&'tcx hir::Expr<'tcx>>, | |||
rcvr_ty: Ty<'tcx>, | |||
item_name: Ident, | |||
expr_id: hir::HirId, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we're just passing in the expr id, I feel like rcvr_opt: Option<_>
, SelfSource: _
, args: Option<_>
are all redundant, since they can all be derived from the expression pointed to by the expr_id
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And the span too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into it. Not much is derivable from expr_id
.
These are the two calls to report_method_error
:
rust/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Lines 835 to 845 in 9cdfe28
if let Some(e) = self.report_method_error( | |
span, | |
None, | |
ty.normalized, | |
item_name, | |
SelfSource::QPath(qself), | |
error, | |
args, | |
Expectation::NoExpectation, | |
trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 | |
) { |
rust/compiler/rustc_hir_typeck/src/expr.rs
Lines 1347 to 1357 in 9cdfe28
if let Some(err) = self.report_method_error( | |
span, | |
Some(rcvr), | |
rcvr_t, | |
segment.ident, | |
SelfSource::MethodCall(rcvr), | |
error, | |
Some(args), | |
expected, | |
false, | |
) { |
As you can see rcvr_opt
(second arg) is being explicitly passed as None
in one case and Some(rcvr)
in the other. Similarly rcvr_ty
(third arg) is ty.normalized
in one case and rcvr_ty
in the other and both are obtained in different ways. source
(fifth arg) too has different values with somewhat convoluted provenance and the same can be said of args
(seventh arg).
So I don't feel we should change any of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SelfSource
, rcvr_opt
, and args
are all a property of whether the expr_id
(which really should be passed in as a whole hir::Expr
) is ExprKind::MethodCall
or ExprKind::Path
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, segment.ident
should be derivable from that expression (it's directly stored in the MethodCall
and is also as the final segment in ExprKind::Path
, or something like that).
I don't think I said to touch rcvr_ty
, which can continue to be passed in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, span
can be derived from the expression without much trouble as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, let me have another look at it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SelfSource, rcvr_opt, and args are all a property of whether the expr_id (which really should be passed in as a whole hir::Expr) is ExprKind::MethodCall or ExprKind::Path.
@compiler-errors Turns out the expr_id
isn't necessarily pointing to an Expr
always. it could also be a Pat
because check_pat
also calls report_method_error
(check_pat
->resolve_ty_and_res_fully_qualified_call
->report_method_error
) . So if I were to derive all these bits from expr_id
I'll have to take Pat
into account in addition to Expr
, which means I might have to repeat code like this from resolve_ty_and_res_fully_qualified_call
:
rust/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Lines 749 to 772 in 78dd504
let (ty, qself, item_segment) = match *qpath { | |
QPath::Resolved(ref opt_qself, path) => { | |
return ( | |
path.res, | |
opt_qself.as_ref().map(|qself| self.lower_ty(qself)), | |
path.segments, | |
); | |
} | |
QPath::TypeRelative(ref qself, ref segment) => { | |
// Don't use `self.lower_ty`, since this will register a WF obligation. | |
// If we're trying to call a nonexistent method on a trait | |
// (e.g. `MyTrait::missing_method`), then resolution will | |
// give us a `QPath::TypeRelative` with a trait object as | |
// `qself`. In that case, we want to avoid registering a WF obligation | |
// for `dyn MyTrait`, since we don't actually need the trait | |
// to be object-safe. | |
// We manually call `register_wf_obligation` in the success path | |
// below. | |
let ty = self.lowerer().lower_ty_in_path(qself); | |
(LoweredTy::from_raw(self, span, ty), qself, segment) | |
} | |
QPath::LangItem(..) => { | |
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`") | |
} |
within
report_method_error
. I have a feeling that complicates things instead of making them simpler 😫
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That didn't end up being too complicated, for the record: 2227c1f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs IsSuggestion
set to true
(or needs to use lookup_method_for_diagnostic
or something diagnostic-flavored instead), and I encourage you to also look into cleaning up redundant args (it's nice to leave code better than you found it)
@rustbot author |
e27fc27
to
273a78b
Compare
@rustbot ready |
@rustbot author |
@rustbot ready The suggested cleanup seems a bit convoluted. Please see my comment here: #125397 (comment) |
I'll do the cleanup myself I guess @bors r+ rollup |
☀️ Test successful - checks-actions |
Finished benchmarking commit (865eaf9): comparison URL. Overall result: ❌ regressions - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)Results (primary -3.4%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 667.872s -> 667.71s (-0.02%) |
…ror-args, r=fmease Remove a bunch of redundant args from `report_method_error` Rebased on top of rust-lang#125397 because I had originally asked there (rust-lang#125397 (comment)) for this change to be made, but I just chose to do it myself. r? fmease
Rollup merge of rust-lang#125906 - compiler-errors:simplify-method-error-args, r=fmease Remove a bunch of redundant args from `report_method_error` Rebased on top of rust-lang#125397 because I had originally asked there (rust-lang#125397 (comment)) for this change to be made, but I just chose to do it myself. r? fmease
… r=fmease Remove a bunch of redundant args from `report_method_error` Rebased on top of #125397 because I had originally asked there (rust-lang/rust#125397 (comment)) for this change to be made, but I just chose to do it myself. r? fmease
Fixes #125303
The issue was that when a builder method cannot be resolved we are suggesting alternatives that themselves cannot be resolved. This PR adds a check that filters them from the list of suggestions.