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

[1.30 beta] Ambiguous macro names #54472

Closed
pietroalbini opened this issue Sep 22, 2018 · 8 comments · Fixed by #54605
Closed

[1.30 beta] Ambiguous macro names #54472

pietroalbini opened this issue Sep 22, 2018 · 8 comments · Fixed by #54605
Assignees
Labels
P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@pietroalbini
Copy link
Member

Some crates in 1.30 beta are failing with ambiguous macro names errors:

 error[E0659]: `run_cancel` is ambiguous
    --> tests/pipeable.rs:156:5
     |
 156 |     run_cancel!(Simple(mock_must_cancel()));
     |     ^^^^^^^^^^ ambiguous name
     |
 error[E0659]: `try` is ambiguous
   --> src/lib.rs:52:10
    |
 52 | #[derive(Serialize, Deserialize, Debug)]
    |          ^^^^^^^^^ ambiguous name
    |

cc @petrochenkov

@pietroalbini pietroalbini added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. regression-from-stable-to-beta Performance or correctness regression from stable to beta. C-bug Category: This is a bug. labels Sep 22, 2018
@pietroalbini pietroalbini added this to the 1.30 milestone Sep 22, 2018
@ipetkov
Copy link
Contributor

ipetkov commented Sep 22, 2018

Only the conch-runtime tests were affected by this, which were fixed a while back but I didn't end up releasing a new version (an oversight which has now been corrected)

@petrochenkov petrochenkov self-assigned this Sep 22, 2018
@petrochenkov
Copy link
Contributor

All the ambiguities are legitimate, sorry :(
This is all fallout from enabling macro modularization in general.

I think we may be able to reliably disambiguate some of these in the future, but that's not something that can be backported to beta.

One low-hanging fruit is treating glob imports from other crates as single imports for the purposes of restricted shadowing.
Cross-crate globs are available immediately and don't require going through fix-point, so it's not necessary to apply restricted shadowing to them.
I'll try to implement it and then we can think about backporting.

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 26, 2018

One low-hanging fruit is treating glob imports from other crates as single imports for the purposes of restricted shadowing.

It actually won't help with regressions here, I've misinterpreted the error messages.

The ambiguities in listed crates are "macro_rules definition" vs "macro in module", so they are not caused by restricted glob shadowing.
They need some disambiguation scheme similar to "let variable" vs "item in block", but at module level.

fn main() {
    let x = || 0;
    println!("{:?}", x());
    {
        println!("{:?}", x());
        fn x() -> i32 { 1 }
        println!("{:?}", x());
        let x = || 2;
        println!("{:?}", x());
    }
    println!("{:?}", x());
}
---
0
1
1
2
0

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 27, 2018

Partially fixed in #54605 using subset of the let rules described in the previous comment.

EDIT: I'm planning to extend #54605 to the full fix so far, but haven't yet looked what exactly causes smpl_jwt and off_blockway to fail.

@pnkfelix pnkfelix added P-high High priority and removed I-nominated labels Sep 27, 2018
@nagisa
Copy link
Member

nagisa commented Sep 27, 2018

@petrochenkov should we also warn when resolving in favour of macro_rules!?

@petrochenkov
Copy link
Contributor

petrochenkov commented Sep 27, 2018

I don't think so? In all the regressed cases the macro_rules resolution is expected, and modularized resolutions are accidental - either from globs, or from #[macro_export] planted into the root module.

It's not something to-be-deprecated/hacky either - I planned to implement the scoping rules from #54472 (comment) eventually anyway since it's kinda "natural" expected behavior for let-like things, the regressions just made the matter more urgent.

@petrochenkov
Copy link
Contributor

Minimized reproduction for smpl_jwt and off_blockway:

use std::*;

fn main() {
    macro_rules! try { ($expr:expr) => () }
    
    try!(0);
}

@petrochenkov
Copy link
Contributor

#54605 is updated with a fix for the remaining regressions.

bors added a commit that referenced this issue Oct 3, 2018
resolve: Disambiguate a subset of conflicts "macro_rules" vs "macro name in module"

Currently if macro name may refer to both a `macro_rules` macro definition and a macro defined/imported into module we conservatively report an ambiguity error.
Unfortunately, these errors became a source of regressions when macro modularization was enabled - see issue #54472.

This PR disambiguates such conflicts in favor of `macro_rules` if both the `macro_rules` item and in-module macro name are defined in the same normal (named) module and `macro_rules` is closer in scope to the point of use (see the tests for examples).
This is a subset of more general approach described in #54472 (comment).
The subset is enough to fix all the regressions from #54472, but it can be extended to apply to all "macro_rules" vs "macro name in module" conflicts in the future.

To give an analogy, this is equivalent to scoping rules for `let` variables and items defined in blocks (`macro_rules` behaves like "`let` at module level" in general).
```rust
{ // beginning of the block
    use xxx::m; // (1)

    // Starting from the beginning of the block and until here m!() refers to (1)
    macro_rules! m { ... } // (2)
    // Starting from here and until the end of the block m!() refers to (2)
} // end of the block
```
More complex examples with `use` and `macro_rules` from different modules still report ambiguity errors, even if equivalent examples with `let` are legal.

Fixes #54472 (stable-to-beta regression)
bors added a commit that referenced this issue Oct 3, 2018
resolve: Disambiguate a subset of conflicts "macro_rules" vs "macro name in module"

Currently if macro name may refer to both a `macro_rules` macro definition and a macro defined/imported into module we conservatively report an ambiguity error.
Unfortunately, these errors became a source of regressions when macro modularization was enabled - see issue #54472.

This PR disambiguates such conflicts in favor of `macro_rules` if both the `macro_rules` item and in-module macro name are defined in the same normal (named) module and `macro_rules` is closer in scope to the point of use (see the tests for examples).
This is a subset of more general approach described in #54472 (comment).
The subset is enough to fix all the regressions from #54472, but it can be extended to apply to all "macro_rules" vs "macro name in module" conflicts in the future.

To give an analogy, this is equivalent to scoping rules for `let` variables and items defined in blocks (`macro_rules` behaves like "`let` at module level" in general).
```rust
{ // beginning of the block
    use xxx::m; // (1)

    // Starting from the beginning of the block and until here m!() refers to (1)
    macro_rules! m { ... } // (2)
    // Starting from here and until the end of the block m!() refers to (2)
} // end of the block
```
More complex examples with `use` and `macro_rules` from different modules still report ambiguity errors, even if equivalent examples with `let` are legal.

Fixes #54472 (stable-to-beta regression)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
5 participants