[resolved] How to always export a trait from a module


#1

I’m working on my standard new-programming-language project, a PEG parser-generator, and am having a bit of trouble with the Rust module system.

Files

lib.rs:

pub mod ast;

ast.rs:

/// AST nodes
pub trait Expr {
  fn is_nullable(&self) -> bool;
  // other trait methods
}

/// Matches any character
pub struct Any {}

impl Expr for Any {
  fn is_nullable(&self) -> bool { true }
}

// other node types

main.rs:

extern crate foo;

use foo::ast::{self, Expr};
// use foo::ast; // would rather do this, but it doesn't work

fn main() {
  let e = ast::Any {};
  println!("Any nullable? {}", e.is_nullable());
}

Now, I have this compiling, but is there any way to set it up so that use foo::ast automatically imports foo::ast::Expr as well? The entire point of the module is to define a number of types which conform to the Expr trait, so importing the module isn’t much use without it.

If there isn’t a way to do this, I assume there’s a good reason - would someone be so kind as to tell me what having that feature breaks? (Also, if there are any other newbie errors in my code here I’d appreciate correction.)


#2

Would you be willing to tolerate use foo::ast::* or foo::ast::prelude::*?


#3

I’m happy with foo::ast::*, thanks.

Also, for the curious, I found the explanation for why I have to import the trait separately (I’d missed it in my first read-through of the Traits section in the Rust book):

Importing a trait imports all the impls of that trait, which could be for types defined elsewhere, e.g. I could decide to impl Expr for char directly, as a single character matcher, and one of the names might clash with some other impl on char.