mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
fix for Self
not respecting tuple Ctor privacy
This fixes #111220 by checking the privacy of tuple constructors using `Self`, so the following code now errors ```rust mod my { pub struct Foo(&'static str); } impl AsRef<str> for my::Foo { fn as_ref(&self) -> &str { let Self(s) = self; // previously compiled, now errors correctly s } } ```
This commit is contained in:
parent
c86212f9bc
commit
be44860ab9
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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};
|
||||
@ -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;
|
||||
|
@ -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() {}
|
@ -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
tests/ui/privacy/issue-111220-tuple-struct-fields.rs
Normal file
46
tests/ui/privacy/issue-111220-tuple-struct-fields.rs
Normal file
@ -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
tests/ui/privacy/issue-111220-tuple-struct-fields.stderr
Normal file
21
tests/ui/privacy/issue-111220-tuple-struct-fields.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user