stabilize feature(trait_upcasting)
This commit is contained in:
parent
942db6782f
commit
da9a85a1a6
6 changed files with 6 additions and 90 deletions
|
@ -400,6 +400,9 @@ declare_features! (
|
||||||
/// Allows `#[track_caller]` to be used which provides
|
/// Allows `#[track_caller]` to be used which provides
|
||||||
/// accurate caller location reporting during panic (RFC 2091).
|
/// accurate caller location reporting during panic (RFC 2091).
|
||||||
(accepted, track_caller, "1.46.0", Some(47809)),
|
(accepted, track_caller, "1.46.0", Some(47809)),
|
||||||
|
/// Allows dyn upcasting trait objects via supertraits.
|
||||||
|
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
|
||||||
|
(accepted, trait_upcasting, "CURRENT_RUSTC_VERSION", Some(65991)),
|
||||||
/// Allows #[repr(transparent)] on univariant enums (RFC 2645).
|
/// Allows #[repr(transparent)] on univariant enums (RFC 2645).
|
||||||
(accepted, transparent_enums, "1.42.0", Some(60405)),
|
(accepted, transparent_enums, "1.42.0", Some(60405)),
|
||||||
/// Allows indexing tuples.
|
/// Allows indexing tuples.
|
||||||
|
|
|
@ -634,9 +634,6 @@ declare_features! (
|
||||||
(unstable, thread_local, "1.0.0", Some(29594)),
|
(unstable, thread_local, "1.0.0", Some(29594)),
|
||||||
/// Allows defining `trait X = A + B;` alias items.
|
/// Allows defining `trait X = A + B;` alias items.
|
||||||
(unstable, trait_alias, "1.24.0", Some(41517)),
|
(unstable, trait_alias, "1.24.0", Some(41517)),
|
||||||
/// Allows dyn upcasting trait objects via supertraits.
|
|
||||||
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
|
|
||||||
(unstable, trait_upcasting, "1.56.0", Some(65991)),
|
|
||||||
/// Allows for transmuting between arrays with sizes that contain generic consts.
|
/// Allows for transmuting between arrays with sizes that contain generic consts.
|
||||||
(unstable, transmute_generic_consts, "1.70.0", Some(109929)),
|
(unstable, transmute_generic_consts, "1.70.0", Some(109929)),
|
||||||
/// Allows #[repr(transparent)] on unions (RFC 2645).
|
/// Allows #[repr(transparent)] on unions (RFC 2645).
|
||||||
|
|
|
@ -605,7 +605,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
)];
|
)];
|
||||||
|
|
||||||
let mut has_unsized_tuple_coercion = false;
|
let mut has_unsized_tuple_coercion = false;
|
||||||
let mut has_trait_upcasting_coercion = None;
|
|
||||||
|
|
||||||
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
|
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
|
||||||
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
|
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
|
||||||
|
@ -690,13 +689,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
// these here and emit a feature error if coercion doesn't fail
|
// these here and emit a feature error if coercion doesn't fail
|
||||||
// due to another reason.
|
// due to another reason.
|
||||||
match impl_source {
|
match impl_source {
|
||||||
traits::ImplSource::Builtin(
|
|
||||||
BuiltinImplSource::TraitUpcasting { .. },
|
|
||||||
_,
|
|
||||||
) => {
|
|
||||||
has_trait_upcasting_coercion =
|
|
||||||
Some((trait_pred.self_ty(), trait_pred.trait_ref.args.type_at(1)));
|
|
||||||
}
|
|
||||||
traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
|
traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
|
||||||
has_unsized_tuple_coercion = true;
|
has_unsized_tuple_coercion = true;
|
||||||
}
|
}
|
||||||
|
@ -707,21 +699,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((sub, sup)) = has_trait_upcasting_coercion
|
|
||||||
&& !self.tcx().features().trait_upcasting()
|
|
||||||
{
|
|
||||||
// Renders better when we erase regions, since they're not really the point here.
|
|
||||||
let (sub, sup) = self.tcx.erase_regions((sub, sup));
|
|
||||||
let mut err = feature_err(
|
|
||||||
&self.tcx.sess,
|
|
||||||
sym::trait_upcasting,
|
|
||||||
self.cause.span,
|
|
||||||
format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"),
|
|
||||||
);
|
|
||||||
err.note(format!("required when coercing `{source}` into `{target}`"));
|
|
||||||
err.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() {
|
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() {
|
||||||
feature_err(
|
feature_err(
|
||||||
&self.tcx.sess,
|
&self.tcx.sess,
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
#![cfg_attr(bootstrap, feature(trait_upcasting))]
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(array_windows)]
|
#![feature(array_windows)]
|
||||||
|
@ -32,7 +33,6 @@
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(trait_upcasting)]
|
|
||||||
#![warn(unreachable_pub)]
|
#![warn(unreachable_pub)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
#![allow(rustc::untranslatable_diagnostic)]
|
#![allow(rustc::untranslatable_diagnostic)]
|
||||||
|
#![cfg_attr(bootstrap, feature(trait_upcasting))]
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(allocator_api)]
|
#![feature(allocator_api)]
|
||||||
|
@ -56,7 +57,6 @@
|
||||||
#![feature(ptr_alignment_type)]
|
#![feature(ptr_alignment_type)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(trait_upcasting)]
|
|
||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(try_trait_v2)]
|
#![feature(try_trait_v2)]
|
||||||
|
|
|
@ -12,9 +12,7 @@ use hir::LangItem;
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_infer::traits::{
|
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
|
||||||
Obligation, ObligationCause, PolyTraitObligation, PredicateObligations, SelectionError,
|
|
||||||
};
|
|
||||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode};
|
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
|
@ -23,8 +21,6 @@ use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use super::SelectionCandidate::*;
|
use super::SelectionCandidate::*;
|
||||||
use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack};
|
use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack};
|
||||||
use crate::traits;
|
|
||||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
|
||||||
use crate::traits::util;
|
use crate::traits::util;
|
||||||
|
|
||||||
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
@ -904,54 +900,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Temporary migration for #89190
|
|
||||||
fn need_migrate_deref_output_trait_object(
|
|
||||||
&mut self,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
cause: &ObligationCause<'tcx>,
|
|
||||||
) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
|
|
||||||
// Don't drop any candidates in intercrate mode, as it's incomplete.
|
|
||||||
// (Not that it matters, since `Unsize` is not a stable trait.)
|
|
||||||
//
|
|
||||||
// FIXME(@lcnr): This should probably only trigger during analysis,
|
|
||||||
// disabling candidates during codegen is also questionable.
|
|
||||||
if let TypingMode::Coherence = self.infcx.typing_mode() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let tcx = self.tcx();
|
|
||||||
if tcx.features().trait_upcasting() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// <ty as Deref>
|
|
||||||
let trait_ref = ty::TraitRef::new(tcx, tcx.lang_items().deref_trait()?, [ty]);
|
|
||||||
|
|
||||||
let obligation =
|
|
||||||
traits::Obligation::new(tcx, cause.clone(), param_env, ty::Binder::dummy(trait_ref));
|
|
||||||
if !self.infcx.predicate_may_hold(&obligation) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.infcx.probe(|_| {
|
|
||||||
let ty = traits::normalize_projection_ty(
|
|
||||||
self,
|
|
||||||
param_env,
|
|
||||||
ty::AliasTy::new_from_args(tcx, tcx.lang_items().deref_target()?, trait_ref.args),
|
|
||||||
cause.clone(),
|
|
||||||
0,
|
|
||||||
// We're *intentionally* throwing these away,
|
|
||||||
// since we don't actually use them.
|
|
||||||
&mut PredicateObligations::new(),
|
|
||||||
)
|
|
||||||
.as_type()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Searches for unsizing that might apply to `obligation`.
|
/// Searches for unsizing that might apply to `obligation`.
|
||||||
fn assemble_candidates_for_unsizing(
|
fn assemble_candidates_for_unsizing(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1019,15 +967,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
let principal_a = a_data.principal().unwrap();
|
let principal_a = a_data.principal().unwrap();
|
||||||
let target_trait_did = principal_def_id_b.unwrap();
|
let target_trait_did = principal_def_id_b.unwrap();
|
||||||
let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
|
let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
|
||||||
if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
|
|
||||||
source,
|
|
||||||
obligation.param_env,
|
|
||||||
&obligation.cause,
|
|
||||||
) {
|
|
||||||
if deref_trait_ref.def_id() == target_trait_did {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (idx, upcast_trait_ref) in
|
for (idx, upcast_trait_ref) in
|
||||||
util::supertraits(self.tcx(), source_trait_ref).enumerate()
|
util::supertraits(self.tcx(), source_trait_ref).enumerate()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue