Skip to content

Commit e77eb04

Browse files
committed
Arbitrary self types v2: pointers feature gate.
The main `arbitrary_self_types` feature gate will shortly be reused for a new version of arbitrary self types which we are amending per [this RFC](https://github.com/rust-lang/rfcs/blob/master/text/3519-arbitrary-self-types-v2.md). The main amendments are: * _do_ support `self` types which can't safely implement `Deref` * do _not_ support generic `self` types * do _not_ support raw pointers as `self` types. This PR relates to the last of those bullet points: this strips pointer support from the current `arbitrary_self_types` feature. We expect this to cause some amount of breakage for crates using this unstable feature to allow raw pointer self types. If that's the case, we want to know about it, and we want crate authors to know of the upcoming changes. For now, this can be resolved by adding the new `arbitrary_self_types_pointers` feature to such crates. If we determine that use of raw pointers as self types is common, then we may maintain that as an unstable feature even if we come to stabilize the rest of the `arbitrary_self_types` support in future. If we don't hear that this PR is causing breakage, then perhaps we don't need it at all, even behind an unstable feature gate. [Tracking issue](#44874) This is [step 4 of the plan outlined here](#44874 (comment))
1 parent ae9f501 commit e77eb04

14 files changed

+134
-34
lines changed

Diff for: compiler/rustc_feature/src/unstable.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,10 @@ declare_features! (
348348
(unstable, adt_const_params, "1.56.0", Some(95174)),
349349
/// Allows defining an `#[alloc_error_handler]`.
350350
(unstable, alloc_error_handler, "1.29.0", Some(51540)),
351-
/// Allows trait methods with arbitrary self types.
351+
/// Allows inherent and trait methods with arbitrary self types.
352352
(unstable, arbitrary_self_types, "1.23.0", Some(44874)),
353+
/// Allows inherent and trait methods with arbitrary self types that are raw pointers.
354+
(unstable, arbitrary_self_types_pointers, "CURRENT_RUSTC_VERSION", Some(44874)),
353355
/// Enables experimental inline assembly support for additional architectures.
354356
(unstable, asm_experimental_arch, "1.58.0", Some(93335)),
355357
/// Allows using `label` operands in inline assembly.

Diff for: compiler/rustc_hir_analysis/src/check/wfcheck.rs

+65-19
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,14 @@ fn check_fn_or_method<'tcx>(
16511651
}
16521652
}
16531653

1654+
/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
1655+
#[derive(Clone, Copy)]
1656+
enum ArbitrarySelfTypesLevel {
1657+
None, // neither arbitrary_self_types nor arbitrary_self_types_pointers
1658+
ArbitrarySelfTypes, // just arbitrary_self_types
1659+
ArbitrarySelfTypesPointers, // both arbitrary_self_types and arbitrary_self_types_pointers
1660+
}
1661+
16541662
#[instrument(level = "debug", skip(wfcx))]
16551663
fn check_method_receiver<'tcx>(
16561664
wfcx: &WfCheckingCtxt<'_, 'tcx>,
@@ -1683,40 +1691,78 @@ fn check_method_receiver<'tcx>(
16831691
return Ok(());
16841692
}
16851693

1686-
if tcx.features().arbitrary_self_types {
1687-
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
1688-
// Report error; `arbitrary_self_types` was enabled.
1689-
return Err(tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }));
1690-
}
1694+
let arbitrary_self_types_level = if tcx.features().arbitrary_self_types_pointers {
1695+
ArbitrarySelfTypesLevel::ArbitrarySelfTypesPointers
1696+
} else if tcx.features().arbitrary_self_types {
1697+
ArbitrarySelfTypesLevel::ArbitrarySelfTypes
16911698
} else {
1692-
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, false) {
1693-
return Err(if receiver_is_valid(wfcx, span, receiver_ty, self_ty, true) {
1699+
ArbitrarySelfTypesLevel::None
1700+
};
1701+
1702+
if !receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level) {
1703+
return Err(match arbitrary_self_types_level {
1704+
// Wherever possible, emit a message advising folks that the features
1705+
// `arbitrary_self_types` or `arbitrary_self_types_pointers` might
1706+
// have helped.
1707+
ArbitrarySelfTypesLevel::None
1708+
if receiver_is_valid(
1709+
wfcx,
1710+
span,
1711+
receiver_ty,
1712+
self_ty,
1713+
ArbitrarySelfTypesLevel::ArbitrarySelfTypes,
1714+
) =>
1715+
{
16941716
// Report error; would have worked with `arbitrary_self_types`.
16951717
feature_err(
16961718
&tcx.sess,
16971719
sym::arbitrary_self_types,
16981720
span,
16991721
format!(
17001722
"`{receiver_ty}` cannot be used as the type of `self` without \
1701-
the `arbitrary_self_types` feature",
1723+
the `arbitrary_self_types` feature",
17021724
),
17031725
)
17041726
.with_help(fluent::hir_analysis_invalid_receiver_ty_help)
17051727
.emit()
1706-
} else {
1707-
// Report error; would not have worked with `arbitrary_self_types`.
1728+
}
1729+
ArbitrarySelfTypesLevel::ArbitrarySelfTypes | ArbitrarySelfTypesLevel::None
1730+
if receiver_is_valid(
1731+
wfcx,
1732+
span,
1733+
receiver_ty,
1734+
self_ty,
1735+
ArbitrarySelfTypesLevel::ArbitrarySelfTypesPointers,
1736+
) =>
1737+
{
1738+
// Report error; would have worked with `arbitrary_self_types_pointers`.
1739+
feature_err(
1740+
&tcx.sess,
1741+
sym::arbitrary_self_types_pointers,
1742+
span,
1743+
format!(
1744+
"`{receiver_ty}` cannot be used as the type of `self` without \
1745+
the `arbitrary_self_types_pointers` feature",
1746+
),
1747+
)
1748+
.with_help(fluent::hir_analysis_invalid_receiver_ty_help)
1749+
.emit()
1750+
}
1751+
_ =>
1752+
// Report error; would not have worked with `arbitrary_self_types[_pointers]`.
1753+
{
17081754
tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty })
1709-
});
1710-
}
1755+
}
1756+
});
17111757
}
17121758
Ok(())
17131759
}
17141760

17151761
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
17161762
/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
1717-
/// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
1718-
/// strict: `receiver_ty` must implement `Receiver` and directly implement
1719-
/// `Deref<Target = self_ty>`.
1763+
/// through a `*const/mut T` raw pointer if `arbitrary_self_types_pointers` is also enabled.
1764+
/// If neither feature is enabled, the requirements are more strict: `receiver_ty` must implement
1765+
/// `Receiver` and directly implement `Deref<Target = self_ty>`.
17201766
///
17211767
/// N.B., there are cases this function returns `true` but causes an error to be emitted,
17221768
/// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the
@@ -1726,7 +1772,7 @@ fn receiver_is_valid<'tcx>(
17261772
span: Span,
17271773
receiver_ty: Ty<'tcx>,
17281774
self_ty: Ty<'tcx>,
1729-
arbitrary_self_types_enabled: bool,
1775+
arbitrary_self_types_enabled: ArbitrarySelfTypesLevel,
17301776
) -> bool {
17311777
let infcx = wfcx.infcx;
17321778
let tcx = wfcx.tcx();
@@ -1744,8 +1790,8 @@ fn receiver_is_valid<'tcx>(
17441790

17451791
let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);
17461792

1747-
// The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
1748-
if arbitrary_self_types_enabled {
1793+
// The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
1794+
if matches!(arbitrary_self_types_enabled, ArbitrarySelfTypesLevel::ArbitrarySelfTypesPointers) {
17491795
autoderef = autoderef.include_raw_pointers();
17501796
}
17511797

@@ -1771,7 +1817,7 @@ fn receiver_is_valid<'tcx>(
17711817

17721818
// Without `feature(arbitrary_self_types)`, we require that each step in the
17731819
// deref chain implement `receiver`.
1774-
if !arbitrary_self_types_enabled {
1820+
if matches!(arbitrary_self_types_enabled, ArbitrarySelfTypesLevel::None) {
17751821
if !receiver_is_implemented(
17761822
wfcx,
17771823
receiver_trait_def_id,

Diff for: compiler/rustc_hir_typeck/src/method/probe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
402402
mode,
403403
}));
404404
} else if bad_ty.reached_raw_pointer
405-
&& !self.tcx.features().arbitrary_self_types
405+
&& !self.tcx.features().arbitrary_self_types_pointers
406406
&& !self.tcx.sess.at_least_rust_2018()
407407
{
408408
// this case used to be allowed by the compiler,

Diff for: compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ symbols! {
406406
append_const_msg,
407407
arbitrary_enum_discriminant,
408408
arbitrary_self_types,
409+
arbitrary_self_types_pointers,
409410
args,
410411
arith_offset,
411412
arm,

Diff for: src/tools/miri/tests/pass/dyn-arbitrary-self.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@revisions: stack tree
22
//@[tree]compile-flags: -Zmiri-tree-borrows
3-
#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
3+
#![feature(arbitrary_self_types_pointers, unsize, coerce_unsized, dispatch_from_dyn)]
44
#![feature(rustc_attrs)]
55

66
fn pin_box_dyn() {

Diff for: tests/mir-opt/building/receiver_ptr_mutability.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// skip-filecheck
22
// EMIT_MIR receiver_ptr_mutability.main.built.after.mir
33

4-
#![feature(arbitrary_self_types)]
4+
#![feature(arbitrary_self_types_pointers)]
55

66
struct Test {}
77

Diff for: tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// issue: <https://github.com/rust-lang/rust/issues/120217>
44

5-
#![feature(arbitrary_self_types)]
5+
#![feature(arbitrary_self_types_pointers)]
66

77
trait Static<'a> {
88
fn proof(self: *const Self, s: &'a str) -> &'static str;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
trait Foo {
2+
fn foo(self: *const Self); //~ ERROR `*const Self` cannot be used as the type of `self`
3+
}
4+
5+
struct Bar;
6+
7+
impl Foo for Bar {
8+
fn foo(self: *const Self) {} //~ ERROR `*const Bar` cannot be used as the type of `self`
9+
}
10+
11+
impl Bar {
12+
fn bar(self: *mut Self) {} //~ ERROR `*mut Bar` cannot be used as the type of `self`
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0658]: `*const Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
2+
--> $DIR/feature-gate-arbitrary-self-types-pointers.rs:8:18
3+
|
4+
LL | fn foo(self: *const Self) {}
5+
| ^^^^^^^^^^^
6+
|
7+
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
8+
= help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
11+
12+
error[E0658]: `*mut Bar` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
13+
--> $DIR/feature-gate-arbitrary-self-types-pointers.rs:12:18
14+
|
15+
LL | fn bar(self: *mut Self) {}
16+
| ^^^^^^^^^
17+
|
18+
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
19+
= help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
20+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
21+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
22+
23+
error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
24+
--> $DIR/feature-gate-arbitrary-self-types-pointers.rs:2:18
25+
|
26+
LL | fn foo(self: *const Self);
27+
| ^^^^^^^^^^^
28+
|
29+
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
30+
= help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
31+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
32+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
33+
34+
error: aborting due to 3 previous errors
35+
36+
For more information about this error, try `rustc --explain E0658`.

Diff for: tests/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types` feature
1+
error[E0658]: `*const Foo` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
22
--> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:4:18
33
|
44
LL | fn foo(self: *const Self) {}
55
| ^^^^^^^^^^^
66
|
77
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
8-
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
8+
= help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
1111

12-
error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types` feature
12+
error[E0658]: `*const ()` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
1313
--> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18
1414
|
1515
LL | fn bar(self: *const Self) {}
1616
| ^^^^^^^^^^^
1717
|
1818
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
19-
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
19+
= help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
2020
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2121
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
2222

23-
error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types` feature
23+
error[E0658]: `*const Self` cannot be used as the type of `self` without the `arbitrary_self_types_pointers` feature
2424
--> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:9:18
2525
|
2626
LL | fn bar(self: *const Self);
2727
| ^^^^^^^^^^^
2828
|
2929
= note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
30-
= help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
30+
= help: add `#![feature(arbitrary_self_types_pointers)]` to the crate attributes to enable
3131
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3232
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
3333

Diff for: tests/ui/inference/auxiliary/inference_unstable_iterator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![feature(staged_api)]
2-
#![feature(arbitrary_self_types)]
2+
#![feature(arbitrary_self_types_pointers)]
33

44
#![stable(feature = "ipu_iterator", since = "1.0.0")]
55

Diff for: tests/ui/inference/auxiliary/inference_unstable_itertools.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(arbitrary_self_types)]
1+
#![feature(arbitrary_self_types_pointers)]
22

33
pub trait IpuItertools {
44
fn ipu_flatten(&self) -> u32 {

Diff for: tests/ui/self/arbitrary_self_types_raw_pointer_struct.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@ run-pass
2-
#![feature(arbitrary_self_types)]
2+
#![feature(arbitrary_self_types_pointers)]
33

44
use std::rc::Rc;
55

Diff for: tests/ui/self/arbitrary_self_types_raw_pointer_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//@ run-pass
2-
#![feature(arbitrary_self_types)]
2+
#![feature(arbitrary_self_types_pointers)]
33

44
use std::ptr;
55

0 commit comments

Comments
 (0)