Skip to content
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

suggest binding site when issuing "try using a local type parameter instead" err msg #14844

Closed
pnkfelix opened this issue Jun 12, 2014 · 8 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics

Comments

@pnkfelix
Copy link
Member

pnkfelix commented Jun 12, 2014

UPDATE: Mentoring instructions below.

--

Here is some code:

pub trait Bar { fn m(&self); }

pub fn foo<T>() {
    struct S<T>;
    impl Bar for S<T> {
        fn m(&self) { println!("Hello World"); }
    }
    let s = S::<T>;
    s.m();
}

pub fn main() {
    foo::<int>();
}

Here is a transcript of a compilation attempt:

% rustc /tmp/bar.rs
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
/tmp/bar.rs:9:7: 9:10 error: type `foo::S<T>` does not implement any method in scope named `m`
/tmp/bar.rs:9     s.m();
                    ^~~
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `fn(&foo::S<T>)`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `fn(&foo::S<T>)`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
error: can't use type parameters from outer function in the substitution of `foo::S<T>`; try using a local type parameter instead
error: aborting due to 11 previous errors
% 

First off, maybe we should be aborting the compilation a little sooner rather than emitting so many seemingly redundant error messages.

Second, I was scratching my head for a little while because I was saying to myself "T is a local type parameter". Of course, it is not local enough; one needs to change the impl Bar for S<T> to impl<T> Bar for S<T>.

So, I think it would be good if the error message suggested this; e.g.:

error: can't use type parameters from outer function in the substitution of foo::S<T>; try adding a local type parameter to the impl

or

error: can't use type parameters from outer function in the substitution of foo::S<T>; try using a local type parameter like impl<T> Bar for ...

@oli-obk
Copy link
Contributor

oli-obk commented Feb 27, 2015

Same error, different situation:

struct A<T> {
    inner: T,
}

impl<T> Iterator for A<T> {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        fn helper(sel: &Self) -> u8 {
            unimplemented!();
        }
        Some(helper(self))
    }
}

fn main() {
}

yields

<anon>:6:24: 6:25 error: can't use type parameters from outer function; try using a local type parameter instead
<anon>:6 impl<T> Iterator for A<T> {
                                ^
<anon>:6:24: 6:25 error: use of undeclared type name `T`
<anon>:6 impl<T> Iterator for A<T> {
                                ^

changing the inner function to

struct A<T> {
    inner: T,
}

impl<T> Iterator for A<T> {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        fn helper<U>(sel: &A<U>) -> u8 {
            unimplemented!();
        }
        Some(helper(self))
    }
}

fn main() {
}

solves the problem

@steveklabnik
Copy link
Member

Triage: @pnkfelix 's example now produces the same error as @oli-obk 's.

@pnkfelix
Copy link
Member Author

Yes the number of errors reported is now reasonable, but it still leads to head scratching because it doesn't make it clear that one needs a binding on the impl block

@steveklabnik steveklabnik added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 9, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 21, 2017
@estebank
Copy link
Contributor

Current output:

error[E0401]: can't use type parameters from outer function; try using a local type parameter instead
 --> src/main.rs:5:20
  |
5 |     impl Bar for S<T> {
  |                    ^ use of type variable from outer function

error[E0392]: parameter `T` is never used
 --> src/main.rs:4:14
  |
4 |     struct S<T>;
  |              ^ unused type parameter
  |
  = help: consider removing `T` or using a marker such as `std::marker::PhantomData`

adjust_local_def, when checking the type parameters we should look at the current scope (I believe it is the rib's scope, the def's scope is the type argument) to get the span for it and point at the definition. I believe the ideal output is the following:

error[E0401]: can't use type parameters from outer function
  --> src/main.rs:5:20
3 | pub fn foo<T>() {
  |            - type variable from outer function
...
5 |     impl Bar for S<T> {
  |                    ^ use of type variable from outer function
note: try using a local type parameter instead
  |
5 |     impl<T> Bar for S<T> {
  |         ^^^

Implementing the suggestion might be slightly harder than just pointing out at the outer type parameter.

@estebank estebank added E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. WG-diagnostics Working group: Diagnostics labels Sep 22, 2017
@zilbuz
Copy link
Contributor

zilbuz commented Jan 16, 2018

I'll try to tackle that. @estebank Where should I contact you if I have some questions ?

@zilbuz
Copy link
Contributor

zilbuz commented Jan 17, 2018

So I poked around, and the rib variable doesn't have any span informations: its bindings member is empty and the kind member doesn't carry any additionnal informations. How should I retrieve the span?

@estebank
Copy link
Contributor

@zilbuz sorry for not getting back to you yesterday. As mentioned in passing in #47319 (comment), we probably should modify ParamTy to include its span, so that we can use it here. This will require you to modify several files to pass in the span to it and to ignore it on usages, but it should be straightforward.

You can keep updating this ticket, and once you've created a PR move the conversation there. Make sure to include "r? @estebank" in the description so that I review it.

@zilbuz
Copy link
Contributor

zilbuz commented Jan 17, 2018

Won't the ParamTy here contain the span for the T in impl Bar for S<T> (the one we already have)? I'm a bit confused about what the ParamTy represents here I think. Anyway I'll try to modify the ParamTy and get back to you in the PR.

bors added a commit that referenced this issue Mar 10, 2018
Show the used type variable when issuing a "can't use type parameters from outer function" error message

Fix #14844

r? @estebank
bors added a commit to rust-lang-ci/rust that referenced this issue Jun 5, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Jun 5, 2023
Evaluate `UnevalutedConst` before trait solving

cc rust-lang#14844
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-diagnostics Working group: Diagnostics
Projects
None yet
Development

No branches or pull requests

7 participants