Skip to content

Macros 2.0: macro defined and used in same function-like scope can't resolve its own items #52389

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

Open
arielb1 opened this issue Jul 14, 2018 · 2 comments
Labels
A-decl-macros-2-0 Area: Declarative macros 2.0 (#39412) A-resolve Area: Name/path resolution done by `rustc_resolve` specifically F-decl_macro `#![feature(decl_macro)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@arielb1
Copy link
Contributor

arielb1 commented Jul 14, 2018

Maybe this is just a misunderstanding of hygiene, but if a macro 2.0 is defined and used in the same function-like scope (function/const) then it can't resolve its own items:

#![feature(decl_macro)]

trait Tr { fn foo(self); }

const C: () = {
    macro implit {
        () => {
            fn doit() { println!("Hi"); }
            impl ::Tr for () {
                fn foo(self) {
                    doit();
                }
            }
        }
    }
    
    
    #[cfg(works)]
    const T: () = { implit!(); () }; // this works with no error
    
    #[cfg(not(works))]
    implit!(); //~ ERROR cannot find function `doit` in this scope
};

fn main() {
    ().foo();
}

Expected Result

doit() should resolve to the fn doit in the scope of the macro, printing Hi!

Actual Result

Resolution error.

Note that

  1. Having the macro defined and used in a module (i.e., if const C: () was a mod _xyz) does work.
  2. Having the macro defined in 1 function-like scope, and used in a child scope of it (see cfg(works)) also works. This error only occurs if the macro is defined and used in the same scope.

cc @petrochenkov @nrc

@arielb1 arielb1 added A-resolve Area: Name/path resolution done by `rustc_resolve` specifically T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-decl-macros-2-0 Area: Declarative macros 2.0 (#39412) labels Jul 14, 2018
@petrochenkov
Copy link
Contributor

Looks like a bug rather than misunderstanding.

@Centril Centril added the F-decl_macro `#![feature(decl_macro)]` label Sep 28, 2019
bors added a commit to rust-lang-ci/rust that referenced this issue Mar 27, 2021
resolve: Partially unify early and late scope-relative identifier resolution

Reuse `early_resolve_ident_in_lexical_scope` instead of a chunk of code in `resolve_ident_in_lexical_scope` doing the same job.

`early_resolve_ident_in_lexical_scope`/`visit_scopes` had to be slightly extended to be able to 1) start from a specific module instead of the current parent scope and 2) report one deprecation lint.
`early_resolve_ident_in_lexical_scope` still doesn't support walking through "ribs", that part is left in `resolve_ident_in_lexical_scope` (moreover, I'm pretty sure it's buggy, but that's a separate issue, cc rust-lang#52389 at least).
@lcnr
Copy link
Contributor

lcnr commented Aug 9, 2022

similar issue:

#![feature(decl_macro)]

struct FromMacro;
pub macro fun_with_macros() {
    fn my_function() -> FromMacro { FromMacro }

    fn uses_from_macro() {
        let FromMacro = Self::my_function();
    }
}

struct LocalStruct;
struct NoMacro;
impl LocalStruct {
    fun_with_macros!();

    fn my_function() -> NoMacro { NoMacro }

    fn doesnt_use_macro() {
        let NoMacro = Self::my_function();
    }
}

This currently errors because my_function in uses_from_macro is the my_function returning NoMacro.

I believe that hygiene for impl items seems generally undesirable but that seems unrelated to this bug and without having spent too much time on hygiene or decl macros, so 🤷

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-decl-macros-2-0 Area: Declarative macros 2.0 (#39412) A-resolve Area: Name/path resolution done by `rustc_resolve` specifically F-decl_macro `#![feature(decl_macro)]` 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