Skip to content

Writing a custom crate attribute is impossible with the current plugin system #15778

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

Closed
Kimundi opened this issue Jul 18, 2014 · 5 comments · Fixed by #22977
Closed

Writing a custom crate attribute is impossible with the current plugin system #15778

Kimundi opened this issue Jul 18, 2014 · 5 comments · Fixed by #22977
Assignees
Labels
A-plugins Area: compiler plugins, doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html

Comments

@Kimundi
Copy link
Member

Kimundi commented Jul 18, 2014

Currently, its not possible to write a custom attribute that applies to the crate, due to the way syntax extensions and the module system works.

  • This does not work because inner attributes have to go first an a module body:
// crate.rs
#![feature(phase)]
#[phase(plugin)]
extern crate foo;
#![foo] // ERROR: An inner attribute is not permitted in this context
  • This does not work because the attribute gets only loaded after it got used:
// crate.rs
#![feature(phase)]
#![foo] // Gets ignored because the syntax extension did not yet get loaded
#[phase(plugin)]
extern crate foo;

Possible solutions

  • Lift the ordering restriction between items.
  • Make plugins mutual recursive visible, like regular items.
@kmcallister
Copy link
Contributor

Is this true for attributes in general? Or only for attributes which are themselves syntax extensions (item decorators / modifiers)?

@kmcallister kmcallister self-assigned this Jan 12, 2015
@Kimundi
Copy link
Member Author

Kimundi commented Jan 13, 2015

Its true for attributes in general, its only turning into an issue if a attribute comes from a extern crate though.

@kmcallister
Copy link
Contributor

Attributes don't come from anywhere. They're just nested key/value data that any part of the compiler can query by name. There's no central registration of attributes.

Also, plugin loading happens after a full parse and before any syntax expansion. So I'm not sure why the order of a plugin and some attribute the plugin will later check would matter.

Can you give a specific example of something you'd like to do with crate attributes that you cannot?

For example, this plugin:

#![feature(plugin_registrar)]
#![feature(box_syntax)]

extern crate syntax;
#[macro_use] extern crate rustc;

use syntax::{ast, attr};
use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
use rustc::plugin::Registry;

declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]");

struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(CRATE_NOT_OKAY)
    }

    fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
        if !attr::contains_name(&krate.attrs, "crate_okay") {
            cx.span_lint(CRATE_NOT_OKAY, krate.span,
                         "crate is not marked with #![crate_okay]");
        }
    }
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_lint_pass(box Pass as LintPassObject);
}

works as expected:

$ cat /tmp/foo.rs
#![feature(plugin, custom_attribute)]
#![plugin(lint_for_crate)]

fn main() { }

$ rustc -C prefer-dynamic --crate-type dylib lint_for_crate.rs

$ rustc -D crate-not-okay -L . /tmp/foo.rs  
/tmp/foo.rs:1:1: 4:13 error: crate is not marked with #![crate_okay] [-D crate-not-okay]  
/tmp/foo.rs:1 #![feature(plugin, custom_attribute)]  
/tmp/foo.rs:2 #![plugin(lint_for_crate)]  
/tmp/foo.rs:3  
/tmp/foo.rs:4 fn main() { }  
error: aborting due to previous error  

$ sed -i '3i#![crate_okay]' /tmp/foo.rs
$ rustc -D crate-not-okay -L . /tmp/foo.rs  
$ echo $?
0

@Kimundi
Copy link
Member Author

Kimundi commented Mar 2, 2015

Hm, it might be that since I opened this issue the plugin system changed in a way that makes this work. I'll have to check with the code that had this issue...

kmcallister added a commit to kmcallister/rust that referenced this issue Mar 2, 2015
Manishearth added a commit to Manishearth/rust that referenced this issue Mar 3, 2015
@kmcallister
Copy link
Contributor

I added a regression test for the original issue. Please open a new ticket if you find something that's still broken :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-plugins Area: compiler plugins, doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants