-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
added missing implementation hint #50161
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @michaelwoerister (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
r? @estebank |
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.
Great work! Would you be able to address the nitpicks? If not, we can merge as is, but it'd be great if we could add the suggestions to avoid spamming too much diagnostic information in trivial cases.
"cannot apply unary operator `{}` to type `{}`", | ||
op.as_str(), actual).emit(); | ||
op.as_str(), actual); |
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.
Could you add here the following?
err.span_label(ex.span, format!("cannot apply unary operator `{}`", op.as_str()));
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.
Fixed
src/librustc_typeck/check/op.rs
Outdated
hir::UnDeref => "std::ops::UnDerf" | ||
}; | ||
err.note(&format!("an implementation of `{}` might be missing for `{}`", | ||
missing_trait, operand_ty)); |
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.
It would be interesting to check wether actual
is an unsigned numeric value, !
, ()
or str
to avoid showing this note, maybe even emitting a note explaining that unsigned numeric values cannot be negative when missing_trait == hir::UnNeg
.
src/test/ui/issue-5239-1.stderr
Outdated
@@ -5,6 +5,8 @@ LL | let x = |ref x: isize| { x += 1; }; | |||
| -^^^^^ | |||
| | | |||
| cannot use `+=` on type `&isize` | |||
| | |||
= note: an implementation of `std::ops::AddAssign` might be missing for `&isize` |
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.
If you add a check for wether *actual
could have op
applied, I would point that out with a span_suggestion
:
error[E0368]: binary assignment operation `+=` cannot be applied to type `&isize`
--> $DIR/issue-5239-1.rs:14:30
|
LL | let x = |ref x: isize| { x += 1; };
| -^^^^^
| |
| cannot use `+=` on type `&isize`
| help: `+=` can be used on `isize`, you can dereference `x`: `&x`
I will try to allly this suggestions |
Ping from triage @rizakrko ! Will you have time soon to apply the review suggestions? |
@shepmaster Sorry for being late. I'l fix this tomorrow |
Ping @estebank |
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.
Great improvements! A bunch of suggestions inline.
src/librustc_typeck/check/op.rs
Outdated
to; you need to dereference this variable once for this \ | ||
operation to work", | ||
op.node.as_str())); | ||
match is_assign{ |
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.
[nitpick] space after is_assign
src/librustc_typeck/check/op.rs
Outdated
} { | ||
let codemap = self.tcx.sess.codemap(); | ||
match codemap.span_to_snippet(lhs_expr.span) { | ||
Ok(lstring) =>{ |
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.
[nitpick] space between =>
and {
src/librustc_typeck/check/op.rs
Outdated
.is_ok() | ||
} { | ||
let codemap = self.tcx.sess.codemap(); | ||
match codemap.span_to_snippet(lhs_expr.span) { |
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 can instead be the following to avoid one level of indentation:
if let Ok(lstring) = codemap.span_to_snippet(lhs_expr.span) {
// ...
}
src/librustc_typeck/check/op.rs
Outdated
err.note( | ||
&format!("an implementation of `{}` might \ | ||
be missing for `{}`", | ||
missing_trait, lhs_ty)); |
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.
[nitpick] indentation
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 was not sure about this, so formatted according to the rustfmt
src/librustc_typeck/check/op.rs
Outdated
// FIXME: point to span of param | ||
err.note( | ||
&format!("`{}` might need a bound for `{}`", | ||
lhs_ty, missing_trait)); |
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.
Missing test for this case.
Also, wording. I'm not a native speaker, but "might need to be bound" sounds slightly better to me.
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.
Not sure about correct wording, so i left it as it was before
| ^^ | ||
| ^^ cannot apply unary operator `-` | ||
| | ||
= note: unsigned values cannot be negated |
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.
😍
src/librustc_typeck/check/op.rs
Outdated
} { | ||
let codemap = self.tcx.sess.codemap(); | ||
match codemap.span_to_snippet(lhs_expr.span) { | ||
Ok(lstring) =>{ |
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.
if let Ok(lstring) = codemap.span_to_snippet(lhs_expr.span) {
instead.
src/librustc_typeck/check/op.rs
Outdated
Op::Binary(op, is_assign)) | ||
.is_ok() | ||
} { | ||
let codemap = self.tcx.sess.codemap(); |
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.
You're assigning codemap
in two places, do it once in the innermost common scope instead.
src/librustc_typeck/check/op.rs
Outdated
} | ||
if let Some(missing_trait) = missing_trait { | ||
if missing_trait == "std::ops::AddAssign" && |
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.
Comparing op.node == hir::BiAdd
would be faster than comparing strings.
src/librustc_typeck/check/op.rs
Outdated
&format!("`{}` might need a bound for `{}`", | ||
lhs_ty, missing_trait)); | ||
} else { | ||
if !suggested_deref{ |
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 can be } else if !suggested_deref {
without the need of an extra indentation level.
Thanks, @estebank! I'll fix this asap. |
@bors r+ |
📌 Commit fa8ac4a has been approved by |
⌛ Testing commit fa8ac4a with merge a854d3e0993ff9f23ec8100f400c5d0b101b69a8... |
💔 Test failed - status-appveyor |
added missing implementation hint Fixes [rust-lang#50151](rust-lang#50151). Actually, i don't know, should following code `let x = |ref x: isize| { x += 1; };` emit `note: an implementation of std::ops::AddAssign might be missing for &isize` or `note: this is a reference to a type that + can be applied to; you need to dereference this variable once for this operation to work` or both
☔ The latest upstream changes (presumably #50395) made this pull request unmergeable. Please resolve the merge conflicts. |
Rollup of 18 pull requests Successful merges: - #49423 (Extend tests for RFC1598 (GAT)) - #50010 (Give SliceIndex impls a test suite of girth befitting the implementation (and fix a UTF8 boundary check)) - #50447 (Fix update-references for tests within subdirectories.) - #50514 (Pull in a wasm fix from LLVM upstream) - #50524 (Make DepGraph::previous_work_products immutable) - #50532 (Don't use Lock for heavily accessed CrateMetadata::cnum_map.) - #50538 ( Make CrateNum allocation more thread-safe. ) - #50564 (Inline `Span` methods.) - #50565 (Use SmallVec for DepNodeIndex within dep_graph.) - #50569 (Allow for specifying a linker plugin for cross-language LTO) - #50572 (Clarify in the docs that `mul_add` is not always faster.) - #50574 (add fn `into_inner(self) -> (Idx, Idx)` to RangeInclusive (#49022)) - #50575 (std: Avoid `ptr::copy` if unnecessary in `vec::Drain`) - #50588 (Move "See also" disambiguation links for primitive types to top) - #50590 (Fix tuple struct field spans) - #50591 (Restore RawVec::reserve* documentation) - #50598 (Remove unnecessary mutable borrow and resizing in DepGraph::serialize) - #50606 (Retry when downloading the Docker cache.) Failed merges: - #50161 (added missing implementation hint) - #50558 (Remove all reference to DepGraph::work_products)
@bors r+ |
📌 Commit 17c56d4 has been approved by |
added missing implementation hint Fixes [#50151](#50151). Actually, i don't know, should following code `let x = |ref x: isize| { x += 1; };` emit `note: an implementation of std::ops::AddAssign might be missing for &isize` or `note: this is a reference to a type that + can be applied to; you need to dereference this variable once for this operation to work` or both
☀️ Test successful - status-appveyor, status-travis |
Fixes #50151.
Actually, i don't know, should following code
let x = |ref x: isize| { x += 1; };
emit
note: an implementation of std::ops::AddAssign might be missing for &isize
or
note: this is a reference to a type that + can be applied to; you need to dereference this variable once for this operation to work
or both