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

Error message when using inner static with type parameters is misleading #48427

Closed
malbarbo opened this issue Feb 22, 2018 · 2 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@malbarbo
Copy link
Contributor

This code

fn x<T: Default>() {
    static a: T = T::default();
}

generates this error:

error[E0401]: can't use type parameters from outer function; try using a local type parameter instead
 --> src/main.rs:2:15
  |
2 |     static a: T = T::default();
  |               ^ use of type variable from outer function

error[E0401]: can't use type parameters from outer function; try using a local type parameter instead
 --> src/main.rs:2:19
  |
2 |     static a: T = T::default();
  |                   ^^^^^^^^^^ use of type variable from outer function

error: aborting due to 2 previous errors

which is misleading because a local type parameter is being used.

The original message was different.

I have one question: why this is forbidden? There is an issue with some discussion but I do not see why this is not possible.

Using static with type parameters is very useful, for example, defining thread local buffer for store temporary results (like in a sorting algorithm).

@oli-obk
Copy link
Contributor

oli-obk commented Feb 22, 2018

I think the big problem would be crate A instantiating static a by invoking crate B's x function. If then crate C also instantiates static a by invoking crate B's x function, you end up with two different a. So if crate D depends on A and C, you'll get very weird behaviour. Might be solvable with MIR only rlibs, but it's generally really easy to get this wrong.

Note that you can get around this limitation by creating another trait bound on T:

trait Foo: 'static {
    fn singleton() -> &'static Self {
        unimplemented!()
    }
}

fn x<T: Default + Foo>() {
    let a = T::singleton();
}

Side-note: you won't be able to call T::default() in a static constructor anyway

@pietroalbini pietroalbini added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 27, 2018
@estebank
Copy link
Contributor

Current output is buggy (the spans pointing at x shouldn't be there at all):

error[E0401]: can't use generic parameters from outer function
 --> src/lib.rs:2:15
  |
1 | fn x<T: Default>() {
  |    - - type parameter from outer function
  |    |
  |    try adding a local generic parameter in this method instead
2 |     static a: T = T::default();
  |               ^ use of generic parameter from outer function

error[E0401]: can't use generic parameters from outer function
 --> src/lib.rs:2:19
  |
1 | fn x<T: Default>() {
  |    - - type parameter from outer function
  |    |
  |    try adding a local generic parameter in this method instead
2 |     static a: T = T::default();
  |                   ^^^^^^^^^^ use of generic parameter from outer function

Closing in lieu of newer ticket #57775, which has more conversation.

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. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants