Skip to content

include! macro fails if included file has top-level inner attributes #752

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
steveklabnik opened this issue Jan 27, 2015 · 11 comments
Open
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@steveklabnik
Copy link
Member

Issue by dwrensha
Sunday Nov 09, 2014 at 14:25 GMT

For earlier discussion, see rust-lang/rust#18810

This issue was labelled with: in the Rust repository


// test.rs

pub mod included {
    include!("test_included.rs")
}

fn main() {}
// test_included.rs

#![allow(dead_code)]

pub fn foo() {}
$ rustc test.rs
test_included.rs:3:3: 3:4 error: an inner attribute is not permitted in this context
test_included.rs:3 #![allow(dead_code)]
                     ^
error: aborting due to previous error

I at first thought that the problem was due to the implicit insert of the prelude in the included module. However, adding a #[no_implicit_prelude] attribute does not help.

@SimonSapin
Copy link
Contributor

@dwrensha
Copy link

On the latest nightly, I still get the same error (after inserting a semicolon to account for the new macro syntax).

@SirVer
Copy link

SirVer commented Dec 8, 2016

Future searchers: I stumbled on this issue as I created a generated module in build.rs and rust-lang/rust#18810 contained a work around that helped me.

@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the RFC. label Feb 23, 2018
Marwes added a commit to Marwes/lalrpop that referenced this issue Mar 17, 2018
Due to rust-lang/rust#18810 (rust-lang/rfcs#752)
it is not possible to have an inner attribute in a file that gets
used with `include!`.

Specifying the attribute on each parser module is less precise and more
duplication but it will at least work for that case. If a user wants to
apply the rustfmt on the whole module they can still add an outer
attribute manually as well.
@peterhuene
Copy link

After running into this issue still, I implemented a hacky workaround for this issue with the upcoming procedural macros feature: https://github.com/peterhuene/azure-functions-rs/blob/master/azure-functions-shared-codegen/src/lib.rs

@nixomose
Copy link

nixomose commented Jan 2, 2020

Future searchers: I stumbled on this issue as I created a generated module in build.rs and rust-lang/rust#18810 contained a work around that helped me.

Future searchers who happen to be rust newbies might be interested to know what you mean by "a work around"
I read the ticket, nothing jumped out at me, and everything I tried failed to yield any result.

I am following this guide for bindgen:
https://rust-lang.github.io/rust-bindgen/tutorial-4.html
and getting this:

error: an inner attribute is not permitted in this context
|
6 | #![allow(non_snake_case)];
| ^^^^^^^^^^^^^^^^^^^^^^^^^

It is hard to google for the difference between #![allow... and #[allow... and although the error explains what the difference between an inner and outer attribute is, it doesn't explain help me understand why the tutorial doesn't work as explained.

@ghost
Copy link

ghost commented Dec 10, 2021

It happens yet, are there news about if there will be a solution?

@dwrensha
Copy link

I haven't tried it myself, but I think that, starting in rustc 1.54, something like this now works:

#[path = concat!(env!("OUT_DIR"), "/foo.rs")]
mod foo;

See https://blog.rust-lang.org/2021/07/29/Rust-1.54.0.html#attributes-can-invoke-function-like-macros

@MingweiSamuel
Copy link

MingweiSamuel commented Feb 9, 2022

#[path = concat!(env!("OUT_DIR"), "/foo.rs")]
mod foo;

Unfortunately this doesn't work

Notably, the attributes path, crate_type, and recursion_limit do not support this because they need their values before or during expansion. It is also not supported with proc-macros.

rust-lang/rust#83366 (comment)

@glandium
Copy link

It's also worth noting that this also happens if you include!() as the first thing in the crate source itself (e.g. lib.rs or main.rs), and the #[path = concat!(env!("OUT_DIR"), "/foo.rs"] mod foo workaround, even if macros in #[path] worked, couldn't be used.

@DimanNe
Copy link

DimanNe commented Sep 22, 2023

It looks like the issue is still here... I cannot include protobuf generated code, getting a bunch of errors:

error: an inner attribute is not permitted in this context
 --> /home/dimanne/devel/scripts/observability/target/debug/build/input-20af024046742d76/out/generated_with_native/capabilities.rs:6:1
  |
6 | #![allow(unknown_lints)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
  = note: outer attributes, like `#[test]`, annotate the item following them

@mheese
Copy link

mheese commented Sep 25, 2023

@DimanNe as I just came across the same problem, and I saw your comment in the rust-protobuf repo as well, the way out of this is: generate with .gen_mod_rs(true) (should be default since version 3). And then instead of including the module, simply include the generated mod.rs file:

include!(concat!(env!("OUT_DIR"), "/mod.rs"));

I guess the suggested workarounds above are a similar suggestions in nature? unfortunately, this was the only way for me out of this.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests