mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +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_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_default_return_type = expected `()` because of default return type
|
||||||
|
|
||||||
hir_typeck_expected_return_type = expected `{$expected}` because of 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 item_name: Ident,
|
||||||
pub action_or_ty: String,
|
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::callee::{self, DeferredCallResolution};
|
||||||
|
use crate::errors::CtorIsPrivate;
|
||||||
use crate::method::{self, MethodCallee, SelfSource};
|
use crate::method::{self, MethodCallee, SelfSource};
|
||||||
use crate::rvalue_scopes;
|
use crate::rvalue_scopes;
|
||||||
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy};
|
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy};
|
||||||
@ -1207,6 +1208,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
match ty.normalized.ty_adt_def() {
|
match ty.normalized.ty_adt_def() {
|
||||||
Some(adt_def) if adt_def.has_ctor() => {
|
Some(adt_def) if adt_def.has_ctor() => {
|
||||||
let (ctor_kind, ctor_def_id) = adt_def.non_enum_variant().ctor.unwrap();
|
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 new_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
|
||||||
let user_substs = Self::user_substs_for_adt(ty);
|
let user_substs = Self::user_substs_for_adt(ty);
|
||||||
user_self_ty = user_substs.user_self_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