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

super trait and trait object error with "source trait is inaccessible", but source trait is in scope (via a reexport) #16264

Closed
japaric opened this issue Aug 5, 2014 · 11 comments
Labels
A-trait-system Area: Trait system

Comments

@japaric
Copy link
Member

japaric commented Aug 5, 2014

STR

use array::ArrayShape;

pub mod array {
    pub use self::traits::ArrayShape;

    mod traits {
        pub trait ArrayShape {
            fn shape(&self) -> (usize, usize) {
                (0, 0)
            }
        }
    }
}

struct Array;

impl ArrayShape for Array {}

fn main() {
    println!("{:?}", Array.shape());  //~ error: source trait is inaccessible
}

trait MatrixShape: ArrayShape {
    fn nrows(&self) -> usize { self.shape().0 }  //~ error: source trait is inaccessible
}

fn show() {
    println!("{:?}", (&Array as &ArrayShape).shape());  //~ error: source trait is inaccessible
}

Version

rustc 1.0.0-nightly (458a6a2f6 2015-01-25 21:20:37 +0000)

Original issue

STR

use array::ArrayShape;

pub mod array {
    pub use self::traits::ArrayShape;

    mod traits {
        pub trait ArrayShape {
            fn shape(&self) -> (uint, uint) {
                (0, 0)
            }
        }
    }
}

struct Array;

// `ArrayShape` is available in this scope, it can be implemented ...
impl ArrayShape for Array {}

fn main() {
    // ... and can also be used
    println!("{}", Array.shape());
}

// But this super trait doesn't work
#[cfg(not(working))]
trait MatrixShape: ArrayShape {
    fn nrows(&self) -> uint { self.shape().val0() }
}

#[cfg(not(working))]
fn bad() {
    // This doesn't work either
    println!("{}", (&Array as &ArrayShape).shape());
}

Output:

trait.rs:28:31: 28:43 error: source trait is inaccessible
trait.rs:28     fn nrows(&self) -> uint { self.shape().val0() }
                                          ^~~~~~~~~~~~
trait.rs:28:31: 28:43 note: module `traits` is private
trait.rs:28     fn nrows(&self) -> uint { self.shape().val0() }
                                          ^~~~~~~~~~~~
trait.rs:34:20: 34:51 error: source trait is inaccessible
trait.rs:34     println!("{}", (&Array as &ArrayShape).shape());
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
trait.rs:34:5: 34:53 note: expansion site
trait.rs:34:20: 34:51 note: module `traits` is private
trait.rs:34     println!("{}", (&Array as &ArrayShape).shape());
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
trait.rs:34:5: 34:53 note: expansion site
error: aborting due to 2 previous errors

I'm no longer sure if this is a bug or is intended? The impl block works, but the super trait and the trait object don't. Do the latter two have different scoping/privacy rules?

Version:

rustc 0.12.0-pre (795f6ae82 2014-08-04 07:01:10 +0000)
@steveklabnik
Copy link
Member

This now gives "expected function, found usize" :/

@steveklabnik steveklabnik added the A-trait-system Area: Trait system label Jan 27, 2015
@japaric
Copy link
Member Author

japaric commented Jan 27, 2015

I've updated the top comment code to rust nightly, and at least now we are getting a more consistent answer from the compiler; all the uses of the ArrayShape trait are rejected with "inaccessible source trait".

What I'm not sure about is if the impl ArrayShape for Array {} should be accepted given that it occurrs in the root of the crate, where the trait is supossed to be inaccessible.

Maybe @alexcrichton can confirm if that's the intended behaviour?

@alexcrichton
Copy link
Member

This definitely seems like suspicious behavior to me, I would expect no errors from the code above. I suspect that the privacy checks for traits is a little wonky and not seeing the reexport.

@mahkoh
Copy link
Contributor

mahkoh commented Feb 10, 2015

Still an issue.

@zummenix
Copy link

I have a similar example:

use core::Check;

fn main() {
    let x = Value;
    x.check();
}

struct Value;

impl Check for Value {
    fn check(&self) -> bool {
        true
    }
}

pub mod core {
    pub use self::private::Check;
    mod private {
        pub trait Check {
            fn check(&self) -> bool;
        }
    }
}

Only acceptable fix for me is to move the Check trait to the core level.

@ihrwein
Copy link
Contributor

ihrwein commented May 30, 2015

Still an issue with stable 1.0. Making public the private module is a workaround.

@ghost
Copy link

ghost commented Jun 6, 2015

Ran into this issue today and noticed something odd, this only seems to happen when trying to use the "private" trait internally. Created a small test repo to demonstrate: Eljay/trait_privacy_test@6a9fc6a

The Bar trait from the inner crate is accessible from the main crate, and from the test_baz_external test in the tests folder (I guess these are technically the same but testing both anyway).

However, the inline test in inner\src\lib.rs fails with the error:

inner\src\lib.rs:17:5: 17:12 error: source trait is inaccessible
inner\src\lib.rs:17     y.baz();
                        ^~~~~~~
inner\src\lib.rs:17:5: 17:12 note: module `bar` is private
inner\src\lib.rs:17     y.baz();
                        ^~~~~~~

Tested on stable 1.0.0 and latest nightly.

@dbrgn
Copy link
Contributor

dbrgn commented Aug 3, 2015

Same issue here. Any solutions? Is this intended behavior?

I'd prefer not making my submodules containing traits public, as that is an implementation detail. I'd rather re-export the trait from the mod.rs file.

@IvanUkhov
Copy link
Contributor

I also would be grateful for an update on the issue. Thanks!

Regards,
Ivan

@ticki
Copy link
Contributor

ticki commented Aug 9, 2015

Still a problem in rustc stable 1.2.0.

@bluss
Copy link
Member

bluss commented Sep 13, 2015

One workaround is calling using explicit Trait::method syntax.

bors added a commit that referenced this issue Sep 22, 2015
Fixes #16264 / #18241.

As far as I can tell, it should be impossible for a trait to be inaccessible if it's in scope, so this check is unnecessary. Are there any cases where this check is actually needed?
bors added a commit to rust-lang-ci/rust that referenced this issue Jan 8, 2024
…gate-trait, r=Veykril

internal: clean and enhance readability for `generate_delegate_trait`

Continue from rust-lang#16112

This PR primarily involves some cleanup and simple refactoring work, including:

- Adding numerous comments to layer the code and explain the behavior of each step.
- Renaming some variables to make them more sensible.
- Simplify certain operations using a more elegant approach.

The goal is to make this intricate implementation clearer and facilitate future maintenance.

In addition to this, the PR also removes redundant `path_transform` operations for `type_gen_args`.
Taking the example of `impl Trait<T1> for S<S1>`, where `S1` is considered. The struct `S` must be in the file where the user triggers code actions, so there's no need for the `path_transform`. Furthermore, before performing the transform, we've already renamed `S1`, ensuring it won't clash with existing generics parameters. Therefore, there's no need to transform it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system
Projects
None yet
Development

No branches or pull requests

10 participants