Skip to content

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Jan 4, 2019

Rollback to pre-#56878 logic of determining reachability.
reachability(impl Trait<Substs> for Type<Substs>) = reachability(Trait & Type), substs are ignored.

Fixes #57264

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 4, 2019
@petrochenkov
Copy link
Contributor Author

r? @nikomatsakis

@rust-lang rust-lang deleted a comment from rust-highfive Jan 5, 2019
@arielb1
Copy link
Contributor

arielb1 commented Jan 5, 2019

I think the invariant the impl rule tries to rely on should be documented somewhere:

The invariant is that type-inference won't let you use an impl without knowing the "shallow" version of its self type (which requires reaching the DefIds in it).

I noted this is not handled correctly with projections, so I have an example that ICEs even older rustcs:

aux.rs:

mod inner {
    #[derive(Default)]
    pub struct PubUnnameable;
}

trait Mirror { type Image; }
impl<T> Mirror for T { type Image = T; }

pub enum Pub<T> { Nothing, Just(T) }
pub trait Aux {}
impl Aux for <Pub<inner::PubUnnameable> as Mirror>::Image {}

pub fn assert_aux<T: Aux>(_t: &T) {}

impl inner::PubUnnameable {
    pub fn pub_method(self) {}
}

main.rs:

extern crate aux;

fn get_default<T: Default>(_t: &aux::Pub<T>) -> T { T::default() }

fn main() {
    let pub_ = aux::Pub::Nothing;
    aux::assert_aux(&pub_);
    let def = get_default(&pub_);
    def.pub_method();
}

@arielb1
Copy link
Contributor

arielb1 commented Jan 5, 2019

I would rename RECURSE into !SHALLOW, and make sure that the few other recursive calls in visit_ty don't occur in shallow mode. Also document the invariant.

@arielb1
Copy link
Contributor

arielb1 commented Jan 5, 2019

r=me with these changes

str4d added a commit to str4d/ire that referenced this pull request Jan 5, 2019
@petrochenkov
Copy link
Contributor Author

petrochenkov commented Jan 5, 2019

@arielb1

I noted this is not handled correctly with projections, so I have an example that ICEs even older rustcs

Projections are not necessary in that case, the root reason is a public trait that's implemented for a single type, so type inference can make conclusion "T: Trait => T = ThatType".
9503c56 has a further minimized example and a fix.

@bors r=arielb1

@bors
Copy link
Collaborator

bors commented Jan 5, 2019

📌 Commit 46d53e53bd20613e1921efbc529726b306732fd2 has been approved by arielb1

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 5, 2019
@bors
Copy link
Collaborator

bors commented Jan 5, 2019

💡 This pull request was already approved, no need to approve it again.

@bors
Copy link
Collaborator

bors commented Jan 5, 2019

📌 Commit 46d53e53bd20613e1921efbc529726b306732fd2 has been approved by arielb1

@arielb1
Copy link
Contributor

arielb1 commented Jan 5, 2019

I noted this is not handled correctly with projections, so I have an example that ICEs even older rustcs

Projections are not necessary in that case, the root reason is a public trait that's implemented for a single type, so type inference can make conclusion "T: Trait => T = ThatType".
9503c56 has a further minimized example and a fix.

Ok. And there's no inherent problem with projections because accessibility computation has to treat projections as public anyway.

@​bors r=arielb1

I would prefer you to not do a @​bors r=me after you make a change this size.

In any case:

Looking at the code, the one point that I think is missing an adequate explanation is the Ty::Opaque case where you are recurring into the contents. However, I think this is currently OK:

Treating opaque types with private predicates as private when computing the AccessLevel of impls is OK because:
1. First, I don't think we can have Ty::Opaque in the self-type of an impl, and if that becomes possible (abstract type), we'll have to rethink the privacy of pub abstract type MyType: PublicTrait + PrivateTrait anyway.
2. In any case, the privacy property we are checking is the privacy of the def id, not the privacy of the substs. If a user can get his hands on an instance of an Opaque, "inductively on the type-checking of the program" we can know that the def id of that Opaque is not private, which means that we won't mark it as private in our pass.

However, I think that is remarkable enough I'll want it as a comment.

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jan 5, 2019
@bors
Copy link
Collaborator

bors commented Jan 5, 2019

📌 Commit 46d53e53bd20613e1921efbc529726b306732fd2 has been approved by arielb1

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 5, 2019
@arielb1
Copy link
Contributor

arielb1 commented Jan 5, 2019

@bors r-

@bors bors removed the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jan 5, 2019
@bors bors added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jan 5, 2019
@arielb1
Copy link
Contributor

arielb1 commented Jan 5, 2019

r=me with a comment on ty::Opaque (it would be OK to copy what I wrote and put it in a comment).

(If you are only changing the comment, I'm ok with a @​bors r=arielb1).

@petrochenkov
Copy link
Contributor Author

petrochenkov commented Jan 5, 2019

@arielb1
From privacy point of view impl Trait1 + Trait2 should be checked identically to dyn Trait1 + Trait2, so we are not even interested in the def-id of the opaque itself (which either doesn't have attached visibility or it's insignificant, like visibility of a type alias).
pub abstract type MyType: PublicTrait + PrivateTrait is equivalent to pub type MyType = dyn PublicTrait + PrivateTrait in this sense.
It's private if any trait in the list is private.

This intent is somewhat hidden because impl-Trait and dyn-Trait use such different structures in ty and we have to recurse to get the trait list in one case, but not in another.

@petrochenkov
Copy link
Contributor Author

@bors r=arielb1

@bors
Copy link
Collaborator

bors commented Jan 6, 2019

📌 Commit fb00313 has been approved by arielb1

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 6, 2019
@bors
Copy link
Collaborator

bors commented Jan 6, 2019

⌛ Testing commit fb00313 with merge d39dddf...

bors added a commit that referenced this pull request Jan 6, 2019
privacy: Fix regression in impl reachability

Rollback to pre-#56878 logic of determining reachability.
`reachability(impl Trait<Substs> for Type<Substs>) = reachability(Trait & Type)`, substs are ignored.

Fixes #57264
@bors
Copy link
Collaborator

bors commented Jan 7, 2019

☀️ Test successful - status-appveyor, status-travis
Approved by: arielb1
Pushing d39dddf to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants