diff options
| author | bors <bors@rust-lang.org> | 2018-06-12 15:23:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-06-12 15:23:28 +0000 |
| commit | ef8cb40c9c03fe60aac47c8736045231633dbdac (patch) | |
| tree | 372aa750a7d6b5351c8824c762ac7b68b8640825 /src/test | |
| parent | 3f3ba6c3cb1707eaf63640fc6681ae389253fe18 (diff) | |
| parent | d13bfd294c55a47bb33e5846ce184c80cdf547dd (diff) | |
| download | rust-ef8cb40c9c03fe60aac47c8736045231633dbdac.tar.gz rust-ef8cb40c9c03fe60aac47c8736045231633dbdac.zip | |
Auto merge of #51519 - ExpHP:issue-51331-b, r=petrochenkov
Fix for $crate var normalization in proc macro for externally defined macros Fixes #51331, a bug that has existed in at least *some* form for a year and a half. The PR includes the addition of a `fold_qpath` method to `syntax::fold::Folder`. Overriding this method is useful for folds that modify paths in a way that invalidates indices (insertion or removal of a component), as it provides the opportunity to update `qself.position` in `<A as B>::C` paths. I added it because the bugfix is messy without it. (unfortunately, grepping around the codebase, I did not see anything else that could use it.)
Diffstat (limited to 'src/test')
3 files changed, 101 insertions, 4 deletions
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs index f4404b737f9..a6c9817f247 100644 --- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs @@ -16,6 +16,8 @@ extern crate proc_macro; use proc_macro::TokenStream; +// Outputs another copy of the struct. Useful for testing the tokens +// seen by the proc_macro. #[proc_macro_derive(Double)] pub fn derive(input: TokenStream) -> TokenStream { format!("mod foo {{ {} }}", input.to_string()).parse().unwrap() diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs new file mode 100644 index 00000000000..030c53b3e6f --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs @@ -0,0 +1,51 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub struct ExternFoo; + +pub trait ExternTrait { + const CONST: u32; + type Assoc; +} + +impl ExternTrait for ExternFoo { + const CONST: u32 = 0; + type Assoc = ExternFoo; +} + +#[macro_export] +macro_rules! external { () => { + mod bar { + #[derive(Double)] + struct Bar($crate::ExternFoo); + } + + mod qself { + #[derive(Double)] + struct QSelf(<$crate::ExternFoo as $crate::ExternTrait>::Assoc); + } + + mod qself_recurse { + #[derive(Double)] + struct QSelfRecurse(< + <$crate::ExternFoo as $crate::ExternTrait>::Assoc + as $crate::ExternTrait>::Assoc + ); + } + + mod qself_in_const { + #[derive(Double)] + #[repr(u32)] + enum QSelfInConst { + Variant = <$crate::ExternFoo as $crate::ExternTrait>::CONST, + } + } +} } + diff --git a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs index b6acb0faab2..41c15195bc8 100644 --- a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs +++ b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs @@ -9,19 +9,63 @@ // except according to those terms. // aux-build:double.rs +// aux-build:external-crate-var.rs // ignore-stage1 #![allow(unused)] #[macro_use] extern crate double; +#[macro_use] +extern crate external_crate_var; struct Foo; -macro_rules! m { () => { - #[derive(Double)] - struct Bar($crate::Foo); +trait Trait { + const CONST: u32; + type Assoc; +} + +impl Trait for Foo { + const CONST: u32 = 0; + type Assoc = Foo; +} + +macro_rules! local { () => { + // derive_Double outputs secondary copies of each definition + // to test what the proc_macro sees. + mod bar { + #[derive(Double)] + struct Bar($crate::Foo); + } + + mod qself { + #[derive(Double)] + struct QSelf(<::Foo as $crate::Trait>::Assoc); + } + + mod qself_recurse { + #[derive(Double)] + struct QSelfRecurse(<<$crate::Foo as $crate::Trait>::Assoc as $crate::Trait>::Assoc); + } + + mod qself_in_const { + #[derive(Double)] + #[repr(u32)] + enum QSelfInConst { + Variant = <::Foo as $crate::Trait>::CONST, + } + } } } -m!(); + +mod local { + local!(); +} + +// and now repeat the above tests, using a macro defined in another crate + +mod external { + external!{} +} fn main() {} |
