Skip to content
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

Ability to refer to a path relative to the current scope in use declarations #959

Closed
crumblingstatue opened this issue Mar 10, 2015 · 6 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@crumblingstatue
Copy link

(Note that this is not about the ability to refer to the current module, which is already possible with use self::foo.)

Rust allows declaring modules, enums, and extern crates in most places where items can be declared, including block scopes inside functions.
One use of this is bringing an extern crate into scope inside a conditional branch:

fn show_message(message: &str) {
    if (inside_a_gui_context) {
        extern crate messagebox;
        // Import trait Messagebox
        use messagebox::Messagebox; // Doesn't work
        ...
    } else {
        println!("{}", message);
    }
}

The problem is that there is no way to refer to items declared this way in use declarations, as paths in use declarations are absolute.

It feels inconsistent being able to declare items like this, but not being able to refer to them in use declarations, and might surprise some users. It did surprise me.

While referring to the items inside can be done by using their full relative path (e.g. do_something_with(messagebox::foo)), there is no way to import traits, so the user has to move the module/crate up to a scope where it can be referred from in use declarations.

One way this could be resolved is to give users a way to refer to a relative path in use declarations.

Options include:

  • Using a keyword , e.g. use relative::messagebox::Messagebox, although I'm not sure reserving a new keyword this late in the alpha is desirable.
  • Using _, as in use _::messagebox::Messagebox, but I'm not sure if _ could otherwise refer to a valid path. It's also not as descriptive as a keyword, but still better than nothing.

The general ability to use relative paths in use declarations might also bring ergonomic benefits in other cases too.

Any thoughts on this issue?

@crumblingstatue crumblingstatue changed the title Ability to refer to items from an inner scope in use declarations Ability to refer to a relative path in use declarations Mar 10, 2015
@crumblingstatue crumblingstatue changed the title Ability to refer to a relative path in use declarations Ability to refer to a path relative to the current scope in use declarations Mar 10, 2015
@blaenk
Copy link
Contributor

blaenk commented Mar 12, 2015

Not sure I understand the issue. I think @eddyb has the best understanding of this area.

@Kimundi
Copy link
Member

Kimundi commented Sep 21, 2015

Another option would be to change the existing use self::messagebox::MessageBox semantic to refer to all items currently in scope, which would include the items inside a block if the use is written inside the block.

@ticki
Copy link
Contributor

ticki commented Aug 1, 2017

This seems like it should enter FCP.

@ticki
Copy link
Contributor

ticki commented Aug 1, 2017

If not outright considered a bug.

@lambda-fairy
Copy link
Contributor

lambda-fairy commented Aug 27, 2017

I think I've run into this issue with Maud.

I'd like to write a function-like proc macro that expands to the following expression (where $expr and $output are arguments to the macro):

{
    extern crate maud;
    use maud::Render;
    $expr.render_to($output);
}

But because of this issue, the use statement fails to compile.

I could call the trait method directly (maud::Render::render_to($expr, $output)) but then I lose autoref.

I ended up working around this issue using a forwarding trait + blanket impl:

{
    extern crate maud;
    trait RenderWrapper: maud::Render {
        fn __render_to(&self, output: &mut String) {
            maud::Render::render_to(self, output);
        }
    }
    impl<T: maud::Render> RenderWrapper for T {}
    $expr.__render_to($output);
}

but this feels kind of icky.

@Centril
Copy link
Contributor

Centril commented Oct 7, 2018

Closing in favor of rust-lang/rust#53130.

@Centril Centril closed this as completed Oct 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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

6 participants