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

fix for Self not respecting tuple Ctor privacy #111245

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ hir_typeck_const_select_must_be_fn = this argument must be a function item

hir_typeck_convert_to_str = try converting the passed type into a `&str`

hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private

hir_typeck_expected_default_return_type = expected `()` because of default return type

hir_typeck_expected_return_type = expected `{$expected}` because of return type
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,11 @@ pub struct CandidateTraitNote {
pub item_name: Ident,
pub action_or_ty: String,
}

#[derive(Diagnostic)]
#[diag(hir_typeck_ctor_is_private, code = "E0603")]
pub struct CtorIsPrivate {
#[primary_span]
pub span: Span,
pub def: String,
}
7 changes: 7 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::callee::{self, DeferredCallResolution};
use crate::errors::CtorIsPrivate;
use crate::method::{self, MethodCallee, SelfSource};
use crate::rvalue_scopes;
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy};
Expand Down Expand Up @@ -1207,6 +1208,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match ty.normalized.ty_adt_def() {
Some(adt_def) if adt_def.has_ctor() => {
let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap();
// Check the visibility of the ctor.
let vis = tcx.visibility(ctor_def_id);
if !vis.is_accessible_from(tcx.parent_module(hir_id).to_def_id(), tcx) {
tcx.sess
.emit_err(CtorIsPrivate { span, def: tcx.def_path_str(adt_def.did()) });
}
let new_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
let user_substs = Self::user_substs_for_adt(ty);
user_self_ty = user_substs.user_self_ty;
Expand Down
33 changes: 33 additions & 0 deletions tests/ui/privacy/issue-111220-2-tuple-struct-fields-projection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
mod b {
pub struct A(u32);
}

trait Id {
type Assoc;
}
impl Id for b::A {
type Assoc = b::A;
}
impl Id for u32 {
type Assoc = u32;
}


trait Trait<T> {
fn method(&self)
where
T: Id<Assoc = b::A>;
}

impl<T: Id> Trait<T> for <T as Id>::Assoc {
fn method(&self)
where
T: Id<Assoc = b::A>,
{
let Self(a) = self;
//~^ ERROR: tuple struct constructor `A` is private
println!("{a}");
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0603]: tuple struct constructor `A` is private
--> $DIR/issue-111220-2-tuple-struct-fields-projection.rs:27:13
|
LL | let Self(a) = self;
| ^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0603`.
46 changes: 46 additions & 0 deletions tests/ui/privacy/issue-111220-tuple-struct-fields.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
mod b {
#[derive(Default)]
pub struct A(u32);
}

impl b::A {
fn inherent_bypass(&self) {
let Self(x) = self;
//~^ ERROR: tuple struct constructor `A` is private
println!("{x}");
}
}

pub trait B {
fn f(&self);
}

impl B for b::A {
fn f(&self) {
let Self(a) = self;
//~^ ERROR: tuple struct constructor `A` is private
println!("{}", a);
}
}

pub trait Projector {
type P;
}

impl Projector for () {
type P = b::A;
}

pub trait Bypass2 {
fn f2(&self);
}

impl Bypass2 for <() as Projector>::P {
fn f2(&self) {
let Self(a) = self;
//~^ ERROR: tuple struct constructor `A` is private
println!("{}", a);
}
}

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui/privacy/issue-111220-tuple-struct-fields.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0603]: tuple struct constructor `A` is private
--> $DIR/issue-111220-tuple-struct-fields.rs:8:13
|
LL | let Self(x) = self;
| ^^^^^^^

error[E0603]: tuple struct constructor `A` is private
--> $DIR/issue-111220-tuple-struct-fields.rs:20:13
|
LL | let Self(a) = self;
| ^^^^^^^

error[E0603]: tuple struct constructor `A` is private
--> $DIR/issue-111220-tuple-struct-fields.rs:40:13
|
LL | let Self(a) = self;
| ^^^^^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0603`.