diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-09-09 22:09:23 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-09-09 22:09:23 +0100 |
commit | c3d96f64ef1b2a5ded9cf5950f8e0f5798de4e1b (patch) | |
tree | a0d6c8121ca6845a48acbb3e9a895a07bfc584ce /crates/ra_hir/src/ty | |
parent | 5fbdf57c4fe7ee99ba94549766a2644431f61b26 (diff) | |
parent | 5f48ef39024f62c135197e764741354611e02b6f (diff) |
Merge #1795
1795: Make macro scope a real name scope and fix some details r=matklad a=uHOOCCOOHu
This PR make macro's module scope a real name scope in `PerNs`, instead of handling `Either<PerNs, MacroDef>` everywhere.
In `rustc`, the macro scope behave exactly the same as type and value scope.
It is valid that macros, types and values having exact the same name, and a `use` statement will import all of them. This happened to module `alloc::vec` and macro `alloc::vec!`.
So `Either` is not suitable here.
There is a trap that not only does `#[macro_use]` import all `#[macro_export] macro_rules`, but also imports all macros `use`d in the crate root.
In other words, it just _imports all macros in the module scope of crate root_. (Visibility of `use` doesn't matter.)
And it also happened to `libstd` which has `use alloc_crate::vec;` in crate root to re-export `alloc::vec`, which it both a module and a macro.
The current implementation of `#[macro_use] extern crate` doesn't work here, so that is why only macros directly from `libstd` like `dbg!` work, while `vec!` from `liballoc` doesn't.
This PR fixes this.
Another point is that, after some tests, I figure out that _`macro_rules` does NOT define macro in current module scope at all_.
It defines itself in legacy textual scope. And if `#[macro_export]` is given, it also is defined ONLY in module scope of crate root. (Then being `macro_use`d, as mentioned above)
(Well, the nightly [Declarative Macro 2.0](https://github.com/rust-lang/rust/issues/39412) simply always define in current module scope only, just like normal items do. But it is not yet supported by us)
After this PR, in my test, all non-builtin macros are resolved now. (Hover text for documentation is available) So it fixes #1688 . Since compiler builtin macros are marked as `#[rustc_doc_only_macro]` instead of `#[macro_export]`, we can simply tweak the condition to let it resolved, but it may cause expansion error.
Some critical notes are also given in doc-comments.
<img width="447" alt="Screenshot_20190909_223859" src="https://user-images.githubusercontent.com/14816024/64540366-ac1ef600-d352-11e9-804f-566ba7559206.png">
Co-authored-by: uHOOCCOOHu <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 2c7d94bce..c60e72abf 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2838,6 +2838,64 @@ fn main() { | |||
2838 | ); | 2838 | ); |
2839 | } | 2839 | } |
2840 | 2840 | ||
2841 | #[test] | ||
2842 | fn infer_path_quantified_macros_expanded() { | ||
2843 | assert_snapshot!( | ||
2844 | infer(r#" | ||
2845 | #[macro_export] | ||
2846 | macro_rules! foo { | ||
2847 | () => { 42i32 } | ||
2848 | } | ||
2849 | |||
2850 | mod m { | ||
2851 | pub use super::foo as bar; | ||
2852 | } | ||
2853 | |||
2854 | fn main() { | ||
2855 | let x = crate::foo!(); | ||
2856 | let y = m::bar!(); | ||
2857 | } | ||
2858 | "#), | ||
2859 | @r###" | ||
2860 | ![0; 5) '42i32': i32 | ||
2861 | ![0; 5) '42i32': i32 | ||
2862 | [111; 164) '{ ...!(); }': () | ||
2863 | [121; 122) 'x': i32 | ||
2864 | [148; 149) 'y': i32 | ||
2865 | "### | ||
2866 | ); | ||
2867 | } | ||
2868 | |||
2869 | #[test] | ||
2870 | fn infer_type_value_macro_having_same_name() { | ||
2871 | assert_snapshot!( | ||
2872 | infer(r#" | ||
2873 | #[macro_export] | ||
2874 | macro_rules! foo { | ||
2875 | () => { | ||
2876 | mod foo { | ||
2877 | pub use super::foo; | ||
2878 | } | ||
2879 | }; | ||
2880 | ($x:tt) => { | ||
2881 | $x | ||
2882 | }; | ||
2883 | } | ||
2884 | |||
2885 | foo!(); | ||
2886 | |||
2887 | fn foo() { | ||
2888 | let foo = foo::foo!(42i32); | ||
2889 | } | ||
2890 | "#), | ||
2891 | @r###" | ||
2892 | ![0; 5) '42i32': i32 | ||
2893 | [171; 206) '{ ...32); }': () | ||
2894 | [181; 184) 'foo': i32 | ||
2895 | "### | ||
2896 | ); | ||
2897 | } | ||
2898 | |||
2841 | #[ignore] | 2899 | #[ignore] |
2842 | #[test] | 2900 | #[test] |
2843 | fn method_resolution_trait_before_autoref() { | 2901 | fn method_resolution_trait_before_autoref() { |