Skip to content
Permalink
Browse files

Revise and generalize the macros-unlinted tests.

Review feedback asked for the test to be generalized to include macros
2.0; that generalization is dyn-2015-idents-in-decl-macros-unlinted.rs

As a drive-by, I also decided to revise the test to make it clear
*why* we cannot generally lint these cases. (I already had similar
demonstrations in dyn-2015-edition-keyword-ident-lint.rs, but it does
not hurt to try to emphasize matters.)

I also added some commentary on the cases where we could choose to
make the lint smarter, namely the situations where a macro is
*definitely* using `dyn` as an identifier (because it is using it as a
path component).
  • Loading branch information...
pnkfelix committed Mar 28, 2019
1 parent f043d2d commit 528366d3ffe0564c2e300aae6df06e6a1bfafde2
@@ -0,0 +1,51 @@
// compile-pass

// Under the 2015 edition with the keyword_idents lint, `dyn` is
// not entirely acceptable as an identifier.
//
// We currently do not attempt to detect or fix uses of `dyn` as an
// identifier under a macro, including under the declarative `macro`
// forms from macros 1.2 and macros 2.0.

#![feature(decl_macro)]
#![allow(non_camel_case_types)]
#![deny(keyword_idents)]

mod outer_mod {
pub mod r#dyn {
pub struct r#dyn;
}
}

// Here we are illustrating that the current lint does not flag the
// occurrences of `dyn` in this macro definition; however, it
// certainly *could* (and it would be nice if it did), since these
// occurrences are not compatible with the 2018 edition's
// interpretation of `dyn` as a keyword.
macro defn_has_dyn_idents() { ::outer_mod::dyn::dyn }

struct X;
trait Trait { fn hello(&self) { }}
impl Trait for X { }

macro tt_trait($arg:tt) { & $arg Trait }
macro id_trait($id:ident) { & $id Trait }

fn main() {
defn_has_dyn_idents!();

// Here we are illustrating that the current lint does not flag
// the occurrences of `dyn` in these macro invocations. It
// definitely should *not* flag the one in `tt_trait`, since that
// is expanding in a valid fashion to `&dyn Trait`.
//
// It is arguable whether it would be valid to flag the occurrence
// in `id_trait`, since that macro specifies that it takes an
// `ident` as its input.
fn f_tt(x: &X) -> tt_trait!(dyn) { x }
fn f_id(x: &X) -> id_trait!(dyn) { x }

let x = X;
f_tt(&x).hello();
f_id(&x).hello();
}
@@ -15,10 +15,42 @@ mod outer_mod {
}
}

// Here we are illustrating that the current lint does not flag the
// occurrences of `dyn` in this macro definition; however, it
// certainly *could* (and it would be nice if it did), since these
// occurrences are not compatible with the 2018 edition's
// interpretation of `dyn` as a keyword.
macro_rules! defn_has_dyn_idents {
($arg:ident) => { ::outer_mod::dyn::dyn }
() => { ::outer_mod::dyn::dyn }
}

struct X;
trait Trait { fn hello(&self) { }}
impl Trait for X { }

macro_rules! tt_trait {
($arg:tt) => { & $arg Trait }
}

macro_rules! id_trait {
($id:ident) => { & $id Trait }
}

fn main() {
defn_has_dyn_idents!(dyn);
defn_has_dyn_idents!();

// Here we are illustrating that the current lint does not flag
// the occurrences of `dyn` in these macro invocations. It
// definitely should *not* flag the one in `tt_trait`, since that
// is expanding in a valid fashion to `&dyn Trait`.
//
// It is arguable whether it would be valid to flag the occurrence
// in `id_trait`, since that macro specifies that it takes an
// `ident` as its input.
fn f_tt(x: &X) -> tt_trait!(dyn) { x }
fn f_id(x: &X) -> id_trait!(dyn) { x }

let x = X;
f_tt(&x).hello();
f_id(&x).hello();
}

0 comments on commit 528366d

Please sign in to comment.
You can’t perform that action at this time.