Skip to content

Using type with local type parameters has confusing error #37892

Closed

Description

@bluss

Using type with local type parameters or Self should have a clearer error.

Reproduce with: (playpen link)

struct Foo;

impl Foo {
    fn method<T>(&self) {
        type X = (Self, T);
    }
}

Current errors have a suggestion ("try..") that doesn't apply.

error[E0401]: can't use type parameters from outer function; try using a local type parameter instead
 --> <anon>:6:19
  |
6 |         type X = (Self, T);
  |                   ^^^^ use of type variable from outer function

error[E0401]: can't use type parameters from outer function; try using a local type parameter instead
 --> <anon>:6:25
  |
6 |         type X = (Self, T);
  |                         ^ use of type variable from outer function

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    on Nov 20, 2016
  2. KalitaAlexey commented on Dec 5, 2016

    @KalitaAlexey
    Contributor

    Why is this disallowed?

  3. arielb1 commented on Dec 5, 2016

    @arielb1
    Contributor

    @KalitaAlexey

    Nested items are independent from their parent item for everything except for privacy and name resolution. This includes type parameters.

    The suggestion is in fact correct - this can be fixed by something like

    struct Foo;
    
    impl Foo {
        fn method<T>(&self) {
            type X<This, T> = (This, T);
        }
    }
     
    fn main() { }
  4. bluss commented on Dec 5, 2016

    @bluss
    ContributorAuthor

    I don't think the user will understand This in type X<This> to be a "local type parameter"; I didn't. If that's just the issue, it could call it something else.

  5. KalitaAlexey commented on Dec 5, 2016

    @KalitaAlexey
    Contributor

    Hi @arielb1,
    I meant that I think that type X = (Self, T) in a function's body can be useful.
    You said that nested items are independent. What's a reason?

  6. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Mar 9, 2017
  7. csmoe commented on Sep 17, 2018

    @csmoe
    Contributor

    cc #47574
    current error message:

    error[E0401]: can't use type parameters from outer function
     --> src/main.rs:6:19
      |
    4 | impl Foo {
      | ---- `Self` type implicitly declared here, by this `impl`
    5 |     fn method<T>(&self) {
    6 |         type X = (Self, T);
      |                   ^^^^
      |                   |
      |                   use of type variable from outer function
      |                   use a type here instead
    
    error[E0401]: can't use type parameters from outer function
     --> src/main.rs:6:25
      |
    5 |     fn method<T>(&self) {
      |        ------ - type variable from outer function
      |        |
      |        try adding a local type parameter in this method instead
    6 |         type X = (Self, T);
      |                         ^ use of type variable from outer function
    
    error: aborting due to 2 previous errors
  8. added
    D-papercutDiagnostics: An error or lint that needs small tweaks.
    on Oct 11, 2019
  9. estebank commented on Oct 11, 2019

    @estebank
    Contributor

    It seems to me what this is missing is a note explaining the same thing as #37892 (comment).

  10. MatrixDev commented on Feb 10, 2022

    @MatrixDev

    Just had the same issue, just a little different implementation:

    enum MyEnum {}
    
    impl MyEnum {
        fn do_something(result: impl FnOnce()) {
            result();
        }
    
        fn do_something_extra() {
            fn inner() {
                Self::do_something(move || {}); // can't use generic parameters from outer function E0401
                MyEnum::do_something(move || {}); // no error
            }
            inner();
        }
    }

    It seams that accessing Self from inner functions is not allowed. This doesn't seem logical and error is way too confusing (or probably describing something else completely).

  11. added a commit that references this issue on Nov 3, 2025
  12. estebank commented on Nov 3, 2025

    @estebank
    Contributor

    After changes on the above linked PR and follow up changes I'll publish after that lands, for the original report:

    error[E0401]: can't use `Self` from outer item
     --> f16.rs:5:19
      |
    3 | impl Foo {
      | ---- `Self` type implicitly declared here, by this `impl`
    4 |     fn method<T>(&self) {
    5 |         type X = (Self, T);
      |              -    ^^^^ use of `Self` from outer item
      |              |
      |              `Self` used in this inner type alias
      |
      = note: nested items are independent from their parent item for everything except for privacy and name resolution
    help: refer to the type directly here instead
      |
    5 -         type X = (Self, T);
    5 +         type X = (Foo, T);
      |
    
    error[E0401]: can't use generic parameters from outer item
     --> f16.rs:5:25
      |
    4 |     fn method<T>(&self) {
      |               - type parameter from outer item
    5 |         type X = (Self, T);
      |              -          ^ use of generic parameter from outer item
      |              |
      |              generic parameter used in this inner type alias
      |
      = note: nested items are independent from their parent item for everything except for privacy and name resolution
    help: try introducing a local generic parameter here
      |
    5 |         type X<T> = (Self, T);
      |               +++
    

    For the case above.

    error[E0401]: can't use `Self` from outer item
      --> f16.rs:17:13
       |
    10 | impl MyEnum {
       | ---- `Self` type implicitly declared here, by this `impl`
    ...
    16 |         fn inner() {
       |            ----- `Self` used in this inner function
    17 |             Self::do_something(move || {}); // can't use generic parameters from outer function E0401
       |             ^^^^ use of `Self` from outer item
       |
       = note: nested items are independent from their parent item for everything except for privacy and name resolution
    help: refer to the type directly here instead
       |
    17 -             Self::do_something(move || {}); // can't use generic parameters from outer function E0401
    17 +             MyEnum::do_something(move || {}); // can't use generic parameters from outer function E0401
       |
    
  13. added a commit that references this issue on Nov 3, 2025
  14. added a commit that references this issue on Nov 3, 2025
    3cd6aa4
  15. added a commit that references this issue on Nov 3, 2025
    bcf227a
  16. added a commit that references this issue on Nov 4, 2025
    381595e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-papercutDiagnostics: An error or lint that needs small tweaks.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions