Stream: t-compiler/wg-rls-2.0

Topic: MacroFileKind in hir::Expansion:file_id()


Edwin Cheng (Nov 20 2019 at 15:52, on Zulip):

I am tracing a bug which fail to expand match_ast , I found that in current source code:

impl Expansion {
    pub fn file_id(&self) -> HirFileId {
        self.macro_call_id.as_file(MacroFileKind::Items)
    }
}

Which is hardcoded as items. But in inner match_ast! expansion, It fail to expand as trying to parse from TokenTree. (i.e. the expansion is ok, but cannot convert it to ast::Source)

So my question is , how to determine which MacroFileKind it should be here?

matklad (Nov 20 2019 at 15:54, on Zulip):

I thin in the resolve_macro_call we should look at the parent of the maro call and save the appropriate MacroKind as a field of the xpansion

Edwin Cheng (Nov 20 2019 at 16:02, on Zulip):

And do it recursively ? I mean if the parent of the macro call HirFileId is MacroFile, try to find it parent in parent HirFileId ?

Edwin Cheng (Nov 20 2019 at 16:05, on Zulip):

And can we determine it by only its parent, or we need to know how hierarachy ?

Jeremy Kolb (Nov 20 2019 at 16:08, on Zulip):

Is this why I'm seeing foo(<|>)end up being a token tree and not a ast::CallExpr?

Edwin Cheng (Nov 20 2019 at 16:36, on Zulip):

Maybe :laughing:

Edwin Cheng (Nov 20 2019 at 16:38, on Zulip):

It seem to be related, but I’m not sure

matklad (Nov 20 2019 at 17:16, on Zulip):

@Edwin Cheng I think you don't need recursion, it should be possible to get the context from just the parent node

matklad (Nov 20 2019 at 17:17, on Zulip):

if parent is MACRO_ITEMS, it's items, etc

matklad (Nov 20 2019 at 17:17, on Zulip):

Not 100% sure, but I think so

Edwin Cheng (Nov 20 2019 at 17:27, on Zulip):

Um..

macro_rules! foo {
    ( $($tt:tt)* ) => {
        fn b() -> u32 {
            $($tt)*
        }
    }
}

macro_rules! bar {
    () => { 0 }
}

foo!(b<|>ar!());

foo is items, but bar is expr, right ?

Edwin Cheng (Nov 20 2019 at 17:27, on Zulip):

Um.. you are right, because it is expanded.

Edwin Cheng (Nov 20 2019 at 17:28, on Zulip):

The parent of bar is b(). not foo

matklad (Nov 20 2019 at 17:31, on Zulip):

Right, the parent of bar would be the block in the expansino code

matklad (Nov 20 2019 at 17:31, on Zulip):

there's a nasty edge case though: macro_rules! foo { () => { bar!() }}

matklad (Nov 20 2019 at 17:32, on Zulip):

Here, the parent of bar is the root node, but it still should be possible to figure out the context (stmt, expr, item) from the kind of this root

Edwin Cheng (Nov 21 2019 at 03:51, on Zulip):

Um... another nasty edge case:

#![allow(dead_code)]

macro_rules! foo {
    ( i ) => {
        fn b() -> u32 { 0 }
    };

    ( e ) => {
        match 0 { _ => 0 }
    };
}

fn main() {
    if false {
        foo!(i);
    }

    if false {
        foo!(e);
    }
}

The ancestors of 2 foo! is same :(

Edwin Cheng (Nov 21 2019 at 03:54, on Zulip):

It is EXPR_STMT, so we should add ExprStmt in MacroKindFile ?

matklad (Nov 21 2019 at 07:43, on Zulip):

@Edwin Cheng it's just that, at the moment, MacroFIleKind supports only expression or items. We should extend MacroFileKind to propely support all kinds of fragments (together with actually supporting them, like expanding macros in patterns, etc)

Edwin Cheng (Nov 21 2019 at 14:15, on Zulip):

@Jeremy Kolb I can confirm that the inner match_ast can't expand by mbe now. It use a neat trick to make comma option in macro lhs arm, which i didn’t handle. Will make a PR to fix it and ping you to test again

Jeremy Kolb (Nov 21 2019 at 14:29, on Zulip):

Cool, if that fixes it I can test signature help again

Jeremy Kolb (Nov 21 2019 at 18:24, on Zulip):

@Edwin Cheng That didn't seem to fix my issue

Edwin Cheng (Nov 21 2019 at 18:25, on Zulip):

Yeah, you need another one PR too, Which is related to this topic

Last update: Dec 12 2019 at 00:55UTC