Skip to content

Report a targeted note for generic parameters that are missing a trait bound #46403

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

Merged
merged 2 commits into from
Dec 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1176,13 +1176,6 @@ impl RegionKind {

/// Type utilities
impl<'a, 'gcx, 'tcx> TyS<'tcx> {
pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
match self.sty {
ty::TyParam(ref d) => Some(d.clone()),
_ => None,
}
}

pub fn is_nil(&self) -> bool {
match self.sty {
TyTuple(ref tys, _) => tys.is_empty(),
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_typeck/check/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// This has nothing here because it means we did string
// concatenation (e.g. "Hello " + "World!"). This means
// we don't want the note in the else clause to be emitted
} else if let ty::TyParam(_) = lhs_ty.sty {
// FIXME: point to span of param
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not been able to figure out how to get the span of T in the generic argument list in order to create a suggestion. The FnCtxt doesn't seem to store the generics or the DefId or the BodyId of the function it's currently checking.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. Presumably we could thread this information down.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I'll do that in a separate PR. This one already improves the message imo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to solve this though, I'd really like to find a way to remove the Name from the ty::ParamIdx -- which presumably would require storing the set of in-scope generics into TLS somewhere (though that would possibly only be used by the Debug and Display impls).

err.note(
&format!("`{}` might need a bound for `{}`",
lhs_ty, missing_trait));
} else {
err.note(
&format!("an implementation of `{}` might be missing for `{}`",
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/type-check/missing_trait_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
}

fn foo<T>(x: T, y: T) {
let z = x + y; //~ ERROR binary operation `+` cannot be applied to type `T`
//~^ NOTE `T` might need a bound for `std::ops::Add`
}
10 changes: 10 additions & 0 deletions src/test/ui/type-check/missing_trait_impl.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error[E0369]: binary operation `+` cannot be applied to type `T`
--> $DIR/missing_trait_impl.rs:15:13
|
15 | let z = x + y; //~ ERROR binary operation `+` cannot be applied to type `T`
| ^^^^^
|
= note: `T` might need a bound for `std::ops::Add`

error: aborting due to previous error