Skip to content

Commit 50f34d6

Browse files
committed
Arbitrary self types v2: stabilize
1 parent 03eb454 commit 50f34d6

File tree

15 files changed

+90
-257
lines changed

15 files changed

+90
-257
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ declare_features! (
6060
(accepted, adx_target_feature, "1.61.0", Some(44839)),
6161
/// Allows explicit discriminants on non-unit enum variants.
6262
(accepted, arbitrary_enum_discriminant, "1.66.0", Some(60553)),
63+
/// Allows inherent and trait methods with arbitrary self types.
64+
(accepted, arbitrary_self_types, "CURRENT_RUSTC_VERSION", Some(44874)),
6365
/// Allows using `const` operands in inline assembly.
6466
(accepted, asm_const, "1.82.0", Some(93332)),
6567
/// Allows using `sym` operands in inline assembly.

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

-2
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,6 @@ declare_features! (
364364
(unstable, adt_const_params, "1.56.0", Some(95174)),
365365
/// Allows defining an `#[alloc_error_handler]`.
366366
(unstable, alloc_error_handler, "1.29.0", Some(51540)),
367-
/// Allows inherent and trait methods with arbitrary self types.
368-
(unstable, arbitrary_self_types, "1.23.0", Some(44874)),
369367
/// Allows inherent and trait methods with arbitrary self types that are raw pointers.
370368
(unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)),
371369
/// Enables experimental inline assembly support for additional architectures.

Diff for: compiler/rustc_hir/src/lang_items.rs

-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ language_item_table! {
242242
DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None;
243243
Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None;
244244
ReceiverTarget, sym::receiver_target, receiver_target, Target::AssocTy, GenericRequirement::None;
245-
LegacyReceiver, sym::legacy_receiver, legacy_receiver_trait, Target::Trait, GenericRequirement::None;
246245

247246
Fn, kw::Fn, fn_trait, Target::Trait, GenericRequirement::Exact(1);
248247
FnMut, sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1);

Diff for: compiler/rustc_hir_analysis/messages.ftl

-6
Original file line numberDiff line numberDiff line change
@@ -256,18 +256,12 @@ hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty
256256
hir_analysis_invalid_receiver_ty_help =
257257
consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
258258
259-
hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types =
260-
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`)
261-
262259
hir_analysis_invalid_receiver_ty_help_nonnull_note =
263260
`NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`
264261
265262
hir_analysis_invalid_receiver_ty_help_weak_note =
266263
`Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`
267264
268-
hir_analysis_invalid_receiver_ty_no_arbitrary_self_types = invalid `self` parameter type: `{$receiver_ty}`
269-
.note = type of `self` must be `Self` or a type that dereferences to it
270-
271265
hir_analysis_invalid_union_field =
272266
field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
273267
.note = union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`

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

+22-125
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use rustc_trait_selection::regions::{InferCtxtRegionExt, OutlivesEnvironmentBuil
2929
use rustc_trait_selection::traits::misc::{
3030
ConstParamTyImplementationError, type_allowed_to_implement_const_param_ty,
3131
};
32-
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
3332
use rustc_trait_selection::traits::{
3433
self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
3534
WellFormedLoc,
@@ -1698,13 +1697,6 @@ fn check_sized_if_body<'tcx>(
16981697
}
16991698
}
17001699

1701-
/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
1702-
#[derive(Clone, Copy, PartialEq)]
1703-
enum ArbitrarySelfTypesLevel {
1704-
Basic, // just arbitrary_self_types
1705-
WithPointers, // both arbitrary_self_types and arbitrary_self_types_pointers
1706-
}
1707-
17081700
#[instrument(level = "debug", skip(wfcx))]
17091701
fn check_method_receiver<'tcx>(
17101702
wfcx: &WfCheckingCtxt<'_, 'tcx>,
@@ -1737,55 +1729,21 @@ fn check_method_receiver<'tcx>(
17371729
return Ok(());
17381730
}
17391731

1740-
let arbitrary_self_types_level = if tcx.features().arbitrary_self_types_pointers() {
1741-
Some(ArbitrarySelfTypesLevel::WithPointers)
1742-
} else if tcx.features().arbitrary_self_types() {
1743-
Some(ArbitrarySelfTypesLevel::Basic)
1744-
} else {
1745-
None
1746-
};
17471732
let generics = tcx.generics_of(method.def_id);
17481733

1749-
let receiver_validity =
1750-
receiver_is_valid(wfcx, span, receiver_ty, self_ty, arbitrary_self_types_level, generics);
1734+
let arbitrary_self_types_pointers_enabled = tcx.features().arbitrary_self_types_pointers();
1735+
let receiver_validity = receiver_is_valid(
1736+
wfcx,
1737+
span,
1738+
receiver_ty,
1739+
self_ty,
1740+
arbitrary_self_types_pointers_enabled,
1741+
generics,
1742+
);
17511743
if let Err(receiver_validity_err) = receiver_validity {
1752-
return Err(match arbitrary_self_types_level {
1753-
// Wherever possible, emit a message advising folks that the features
1754-
// `arbitrary_self_types` or `arbitrary_self_types_pointers` might
1755-
// have helped.
1756-
None if receiver_is_valid(
1757-
wfcx,
1758-
span,
1759-
receiver_ty,
1760-
self_ty,
1761-
Some(ArbitrarySelfTypesLevel::Basic),
1762-
generics,
1763-
)
1764-
.is_ok() =>
1765-
{
1766-
// Report error; would have worked with `arbitrary_self_types`.
1767-
feature_err(
1768-
&tcx.sess,
1769-
sym::arbitrary_self_types,
1770-
span,
1771-
format!(
1772-
"`{receiver_ty}` cannot be used as the type of `self` without \
1773-
the `arbitrary_self_types` feature",
1774-
),
1775-
)
1776-
.with_help(fluent::hir_analysis_invalid_receiver_ty_help)
1777-
.emit()
1778-
}
1779-
None | Some(ArbitrarySelfTypesLevel::Basic)
1780-
if receiver_is_valid(
1781-
wfcx,
1782-
span,
1783-
receiver_ty,
1784-
self_ty,
1785-
Some(ArbitrarySelfTypesLevel::WithPointers),
1786-
generics,
1787-
)
1788-
.is_ok() =>
1744+
return Err(
1745+
if !arbitrary_self_types_pointers_enabled
1746+
&& receiver_is_valid(wfcx, span, receiver_ty, self_ty, true, generics).is_ok()
17891747
{
17901748
// Report error; would have worked with `arbitrary_self_types_pointers`.
17911749
feature_err(
@@ -1794,17 +1752,15 @@ fn check_method_receiver<'tcx>(
17941752
span,
17951753
format!(
17961754
"`{receiver_ty}` cannot be used as the type of `self` without \
1797-
the `arbitrary_self_types_pointers` feature",
1755+
the `arbitrary_self_types_pointers` feature",
17981756
),
17991757
)
18001758
.with_help(fluent::hir_analysis_invalid_receiver_ty_help)
18011759
.emit()
1802-
}
1803-
_ =>
1804-
// Report error; would not have worked with `arbitrary_self_types[_pointers]`.
1805-
{
1760+
} else {
1761+
// Report error; would not have worked with `arbitrary_self_types_pointers`.
18061762
match receiver_validity_err {
1807-
ReceiverValidityError::DoesNotDeref if arbitrary_self_types_level.is_some() => {
1763+
ReceiverValidityError::DoesNotDeref => {
18081764
let hint = match receiver_ty
18091765
.builtin_deref(false)
18101766
.unwrap_or(receiver_ty)
@@ -1818,18 +1774,12 @@ fn check_method_receiver<'tcx>(
18181774

18191775
tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty, hint })
18201776
}
1821-
ReceiverValidityError::DoesNotDeref => {
1822-
tcx.dcx().emit_err(errors::InvalidReceiverTyNoArbitrarySelfTypes {
1823-
span,
1824-
receiver_ty,
1825-
})
1826-
}
18271777
ReceiverValidityError::MethodGenericParamUsed => {
18281778
tcx.dcx().emit_err(errors::InvalidGenericReceiverTy { span, receiver_ty })
18291779
}
18301780
}
1831-
}
1832-
});
1781+
},
1782+
);
18331783
}
18341784
Ok(())
18351785
}
@@ -1873,11 +1823,10 @@ fn receiver_is_valid<'tcx>(
18731823
span: Span,
18741824
receiver_ty: Ty<'tcx>,
18751825
self_ty: Ty<'tcx>,
1876-
arbitrary_self_types_enabled: Option<ArbitrarySelfTypesLevel>,
1826+
arbitrary_self_types_pointers_enabled: bool,
18771827
method_generics: &ty::Generics,
18781828
) -> Result<(), ReceiverValidityError> {
18791829
let infcx = wfcx.infcx;
1880-
let tcx = wfcx.tcx();
18811830
let cause =
18821831
ObligationCause::new(span, wfcx.body_def_id, traits::ObligationCauseCode::MethodReceiver);
18831832

@@ -1892,17 +1841,11 @@ fn receiver_is_valid<'tcx>(
18921841

18931842
confirm_type_is_not_a_method_generic_param(receiver_ty, method_generics)?;
18941843

1895-
let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);
1896-
1897-
// The `arbitrary_self_types` feature allows custom smart pointer
1898-
// types to be method receivers, as identified by following the Receiver<Target=T>
1899-
// chain.
1900-
if arbitrary_self_types_enabled.is_some() {
1901-
autoderef = autoderef.use_receiver_trait();
1902-
}
1844+
let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty)
1845+
.use_receiver_trait();
19031846

19041847
// The `arbitrary_self_types_pointers` feature allows raw pointer receivers like `self: *const Self`.
1905-
if arbitrary_self_types_enabled == Some(ArbitrarySelfTypesLevel::WithPointers) {
1848+
if arbitrary_self_types_pointers_enabled {
19061849
autoderef = autoderef.include_raw_pointers();
19071850
}
19081851

@@ -1925,58 +1868,12 @@ fn receiver_is_valid<'tcx>(
19251868
wfcx.register_obligations(autoderef.into_obligations());
19261869
return Ok(());
19271870
}
1928-
1929-
// Without `feature(arbitrary_self_types)`, we require that each step in the
1930-
// deref chain implement `LegacyReceiver`.
1931-
if arbitrary_self_types_enabled.is_none() {
1932-
let legacy_receiver_trait_def_id =
1933-
tcx.require_lang_item(LangItem::LegacyReceiver, Some(span));
1934-
if !legacy_receiver_is_implemented(
1935-
wfcx,
1936-
legacy_receiver_trait_def_id,
1937-
cause.clone(),
1938-
potential_self_ty,
1939-
) {
1940-
// We cannot proceed.
1941-
break;
1942-
}
1943-
1944-
// Register the bound, in case it has any region side-effects.
1945-
wfcx.register_bound(
1946-
cause.clone(),
1947-
wfcx.param_env,
1948-
potential_self_ty,
1949-
legacy_receiver_trait_def_id,
1950-
);
1951-
}
19521871
}
19531872

19541873
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
19551874
Err(ReceiverValidityError::DoesNotDeref)
19561875
}
19571876

1958-
fn legacy_receiver_is_implemented<'tcx>(
1959-
wfcx: &WfCheckingCtxt<'_, 'tcx>,
1960-
legacy_receiver_trait_def_id: DefId,
1961-
cause: ObligationCause<'tcx>,
1962-
receiver_ty: Ty<'tcx>,
1963-
) -> bool {
1964-
let tcx = wfcx.tcx();
1965-
let trait_ref = ty::TraitRef::new(tcx, legacy_receiver_trait_def_id, [receiver_ty]);
1966-
1967-
let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref);
1968-
1969-
if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) {
1970-
true
1971-
} else {
1972-
debug!(
1973-
"receiver_is_implemented: type `{:?}` does not implement `LegacyReceiver` trait",
1974-
receiver_ty
1975-
);
1976-
false
1977-
}
1978-
}
1979-
19801877
fn check_variances_for_type_defn<'tcx>(
19811878
tcx: TyCtxt<'tcx>,
19821879
item: &'tcx hir::Item<'tcx>,

Diff for: compiler/rustc_hir_analysis/src/errors.rs

-10
Original file line numberDiff line numberDiff line change
@@ -1610,16 +1610,6 @@ pub(crate) enum InvalidReceiverTyHint {
16101610
NonNull,
16111611
}
16121612

1613-
#[derive(Diagnostic)]
1614-
#[diag(hir_analysis_invalid_receiver_ty_no_arbitrary_self_types, code = E0307)]
1615-
#[note]
1616-
#[help(hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types)]
1617-
pub(crate) struct InvalidReceiverTyNoArbitrarySelfTypes<'tcx> {
1618-
#[primary_span]
1619-
pub span: Span,
1620-
pub receiver_ty: Ty<'tcx>,
1621-
}
1622-
16231613
#[derive(Diagnostic)]
16241614
#[diag(hir_analysis_invalid_receiver_ty, code = E0307)]
16251615
#[note]

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

+4-27
Original file line numberDiff line numberDiff line change
@@ -352,15 +352,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
352352
// yield an object-type (e.g., `&Object` or `Box<Object>`
353353
// etc).
354354

355-
let mut autoderef = self.fcx.autoderef(self.span, self_ty);
356-
357-
// We don't need to gate this behind arbitrary self types
358-
// per se, but it does make things a bit more gated.
359-
if self.tcx.features().arbitrary_self_types()
360-
|| self.tcx.features().arbitrary_self_types_pointers()
361-
{
362-
autoderef = autoderef.use_receiver_trait();
363-
}
355+
let autoderef = self.fcx.autoderef(self.span, self_ty).use_receiver_trait();
364356

365357
autoderef
366358
.include_raw_pointers()
@@ -540,24 +532,9 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
540532
self.register_predicates(obligations);
541533
}
542534
Err(terr) => {
543-
if self.tcx.features().arbitrary_self_types() {
544-
self.err_ctxt()
545-
.report_mismatched_types(
546-
&cause,
547-
self.param_env,
548-
method_self_ty,
549-
self_ty,
550-
terr,
551-
)
552-
.emit();
553-
} else {
554-
// This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions
555-
// may run before wfcheck if the function is used in const eval.
556-
self.dcx().span_delayed_bug(
557-
cause.span,
558-
format!("{self_ty} was a subtype of {method_self_ty} but now is not?"),
559-
);
560-
}
535+
self.err_ctxt()
536+
.report_mismatched_types(&cause, self.param_env, method_self_ty, self_ty, terr)
537+
.emit();
561538
}
562539
}
563540
}

0 commit comments

Comments
 (0)