Compiler: Rename "object safe" to "dyn compatible"

This commit is contained in:
León Orell Valerian Liehr 2024-09-25 10:38:40 +02:00
parent f5cd2c5888
commit 01a063f9df
No known key found for this signature in database
GPG key ID: D17A07215F68E713
183 changed files with 523 additions and 510 deletions

View file

@ -37,7 +37,7 @@ use super::{
};
use crate::error_reporting::TypeErrCtxt;
use crate::error_reporting::infer::TyCategory;
use crate::error_reporting::traits::report_object_safety_error;
use crate::error_reporting::traits::report_dyn_incompatibility;
use crate::errors::{
AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,
};
@ -46,7 +46,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::{
MismatchedProjectionTypes, NormalizeExt, Obligation, ObligationCause, ObligationCauseCode,
ObligationCtxt, Overflow, PredicateObligation, SelectionError, SignatureMismatch,
TraitNotObjectSafe, elaborate,
TraitDynIncompatible, elaborate,
};
impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
@ -547,9 +547,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
)
}
ty::PredicateKind::ObjectSafe(trait_def_id) => {
let violations = self.tcx.object_safety_violations(trait_def_id);
report_object_safety_error(self.tcx, span, None, trait_def_id, violations)
ty::PredicateKind::DynCompatible(trait_def_id) => {
let violations = self.tcx.dyn_compatibility_violations(trait_def_id);
report_dyn_incompatibility(self.tcx, span, None, trait_def_id, violations)
}
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {
@ -624,9 +624,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
def_id,
),
TraitNotObjectSafe(did) => {
let violations = self.tcx.object_safety_violations(did);
report_object_safety_error(self.tcx, span, None, did, violations)
TraitDynIncompatible(did) => {
let violations = self.tcx.dyn_compatibility_violations(did);
report_dyn_incompatibility(self.tcx, span, None, did, violations)
}
SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsInfer) => {

View file

@ -12,8 +12,8 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, LangItem};
use rustc_infer::traits::{
ObjectSafetyViolation, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
SelectionError,
DynCompatibilityViolation, Obligation, ObligationCause, ObligationCauseCode,
PredicateObligation, SelectionError,
};
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -406,12 +406,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}
pub fn report_object_safety_error<'tcx>(
pub fn report_dyn_incompatibility<'tcx>(
tcx: TyCtxt<'tcx>,
span: Span,
hir_id: Option<hir::HirId>,
trait_def_id: DefId,
violations: &[ObjectSafetyViolation],
violations: &[DynCompatibilityViolation],
) -> Diag<'tcx> {
let trait_str = tcx.def_path_str(trait_def_id);
let trait_span = tcx.hir().get_if_local(trait_def_id).and_then(|node| match node {
@ -449,12 +449,12 @@ pub fn report_object_safety_error<'tcx>(
let mut multi_span = vec![];
let mut messages = vec![];
for violation in violations {
if let ObjectSafetyViolation::SizedSelf(sp) = &violation
if let DynCompatibilityViolation::SizedSelf(sp) = &violation
&& !sp.is_empty()
{
// Do not report `SizedSelf` without spans pointing at `SizedSelf` obligations
// with a `Span`.
reported_violations.insert(ObjectSafetyViolation::SizedSelf(vec![].into()));
reported_violations.insert(DynCompatibilityViolation::SizedSelf(vec![].into()));
}
if reported_violations.insert(violation.clone()) {
let spans = violation.spans();
@ -481,9 +481,10 @@ pub fn report_object_safety_error<'tcx>(
for (span, msg) in iter::zip(multi_span, messages) {
note_span.push_span_label(span, msg);
}
// FIXME(dyn_compat_renaming): Update the URL.
err.span_note(
note_span,
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
"for a trait to be \"dyn-compatible\" it needs to allow building a vtable to allow the call \
to be resolvable dynamically; for more information visit \
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
);

View file

@ -275,7 +275,7 @@ fn fulfillment_error_for_no_solution<'tcx>(
FulfillmentErrorCode::Subtype(expected_found, TypeError::Sorts(expected_found))
}
ty::PredicateKind::Clause(_)
| ty::PredicateKind::ObjectSafe(_)
| ty::PredicateKind::DynCompatible(_)
| ty::PredicateKind::Ambiguous => {
FulfillmentErrorCode::Select(SelectionError::Unimplemented)
}

View file

@ -802,7 +802,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
| ty::PredicateKind::NormalizesTo(..)
| ty::PredicateKind::AliasRelate(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::DynCompatible(..)
| ty::PredicateKind::Subtype(..)
// FIXME(generic_const_exprs): you can absolutely add this as a where clauses
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))

View file

@ -28,43 +28,43 @@ use tracing::{debug, instrument};
use super::elaborate;
use crate::infer::TyCtxtInferExt;
pub use crate::traits::ObjectSafetyViolation;
pub use crate::traits::DynCompatibilityViolation;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{MethodViolationCode, Obligation, ObligationCause, util};
/// Returns the object safety violations that affect HIR ty lowering.
/// Returns the dyn-compatibility violations that affect HIR ty lowering.
///
/// Currently that is `Self` in supertraits. This is needed
/// because `object_safety_violations` can't be used during
/// because `dyn_compatibility_violations` can't be used during
/// type collection.
#[instrument(level = "debug", skip(tcx))]
pub fn hir_ty_lowering_object_safety_violations(
#[instrument(level = "debug", skip(tcx), ret)]
pub fn hir_ty_lowering_dyn_compatibility_violations(
tcx: TyCtxt<'_>,
trait_def_id: DefId,
) -> Vec<ObjectSafetyViolation> {
) -> Vec<DynCompatibilityViolation> {
debug_assert!(tcx.generics_of(trait_def_id).has_self);
let violations = tcx
.supertrait_def_ids(trait_def_id)
tcx.supertrait_def_ids(trait_def_id)
.map(|def_id| predicates_reference_self(tcx, def_id, true))
.filter(|spans| !spans.is_empty())
.map(ObjectSafetyViolation::SupertraitSelf)
.collect();
debug!(?violations);
violations
.map(DynCompatibilityViolation::SupertraitSelf)
.collect()
}
fn object_safety_violations(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &'_ [ObjectSafetyViolation] {
fn dyn_compatibility_violations(
tcx: TyCtxt<'_>,
trait_def_id: DefId,
) -> &'_ [DynCompatibilityViolation] {
debug_assert!(tcx.generics_of(trait_def_id).has_self);
debug!("object_safety_violations: {:?}", trait_def_id);
debug!("dyn_compatibility_violations: {:?}", trait_def_id);
tcx.arena.alloc_from_iter(
tcx.supertrait_def_ids(trait_def_id)
.flat_map(|def_id| object_safety_violations_for_trait(tcx, def_id)),
.flat_map(|def_id| dyn_compatibility_violations_for_trait(tcx, def_id)),
)
}
fn is_object_safe(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
tcx.object_safety_violations(trait_def_id).is_empty()
fn is_dyn_compatible(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool {
tcx.dyn_compatibility_violations(trait_def_id).is_empty()
}
/// We say a method is *vtable safe* if it can be invoked on a trait
@ -82,34 +82,35 @@ pub fn is_vtable_safe_method(tcx: TyCtxt<'_>, trait_def_id: DefId, method: ty::A
virtual_call_violations_for_method(tcx, trait_def_id, method).is_empty()
}
fn object_safety_violations_for_trait(
#[instrument(level = "debug", skip(tcx), ret)]
fn dyn_compatibility_violations_for_trait(
tcx: TyCtxt<'_>,
trait_def_id: DefId,
) -> Vec<ObjectSafetyViolation> {
) -> Vec<DynCompatibilityViolation> {
// Check assoc items for violations.
let mut violations: Vec<_> = tcx
.associated_items(trait_def_id)
.in_definition_order()
.flat_map(|&item| object_safety_violations_for_assoc_item(tcx, trait_def_id, item))
.flat_map(|&item| dyn_compatibility_violations_for_assoc_item(tcx, trait_def_id, item))
.collect();
// Check the trait itself.
if trait_has_sized_self(tcx, trait_def_id) {
// We don't want to include the requirement from `Sized` itself to be `Sized` in the list.
let spans = get_sized_bounds(tcx, trait_def_id);
violations.push(ObjectSafetyViolation::SizedSelf(spans));
violations.push(DynCompatibilityViolation::SizedSelf(spans));
}
let spans = predicates_reference_self(tcx, trait_def_id, false);
if !spans.is_empty() {
violations.push(ObjectSafetyViolation::SupertraitSelf(spans));
violations.push(DynCompatibilityViolation::SupertraitSelf(spans));
}
let spans = bounds_reference_self(tcx, trait_def_id);
if !spans.is_empty() {
violations.push(ObjectSafetyViolation::SupertraitSelf(spans));
violations.push(DynCompatibilityViolation::SupertraitSelf(spans));
}
let spans = super_predicates_have_non_lifetime_binders(tcx, trait_def_id);
if !spans.is_empty() {
violations.push(ObjectSafetyViolation::SupertraitNonLifetimeBinder(spans));
violations.push(DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans));
}
if violations.is_empty() {
@ -120,11 +121,6 @@ fn object_safety_violations_for_trait(
}
}
debug!(
"object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
trait_def_id, violations
);
violations
}
@ -296,13 +292,13 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
})
}
/// Returns `Some(_)` if this item makes the containing trait not object safe.
/// Returns `Some(_)` if this item makes the containing trait dyn-incompatible.
#[instrument(level = "debug", skip(tcx), ret)]
pub fn object_safety_violations_for_assoc_item(
pub fn dyn_compatibility_violations_for_assoc_item(
tcx: TyCtxt<'_>,
trait_def_id: DefId,
item: ty::AssocItem,
) -> Vec<ObjectSafetyViolation> {
) -> Vec<DynCompatibilityViolation> {
// Any item that has a `Self : Sized` requisite is otherwise
// exempt from the regulations.
if tcx.generics_require_sized_self(item.def_id) {
@ -310,10 +306,10 @@ pub fn object_safety_violations_for_assoc_item(
}
match item.kind {
// Associated consts are never object safe, as they can't have `where` bounds yet at all,
// Associated consts are never dyn-compatible, as they can't have `where` bounds yet at all,
// and associated const bounds in trait objects aren't a thing yet either.
ty::AssocKind::Const => {
vec![ObjectSafetyViolation::AssocConst(item.name, item.ident(tcx).span)]
vec![DynCompatibilityViolation::AssocConst(item.name, item.ident(tcx).span)]
}
ty::AssocKind::Fn => virtual_call_violations_for_method(tcx, trait_def_id, item)
.into_iter()
@ -330,16 +326,16 @@ pub fn object_safety_violations_for_assoc_item(
_ => item.ident(tcx).span,
};
ObjectSafetyViolation::Method(item.name, v, span)
DynCompatibilityViolation::Method(item.name, v, span)
})
.collect(),
// Associated types can only be object safe if they have `Self: Sized` bounds.
// Associated types can only be dyn-compatible if they have `Self: Sized` bounds.
ty::AssocKind::Type => {
if !tcx.features().generic_associated_types_extended
&& !tcx.generics_of(item.def_id).is_own_empty()
&& !item.is_impl_trait_in_trait()
{
vec![ObjectSafetyViolation::GAT(item.name, item.ident(tcx).span)]
vec![DynCompatibilityViolation::GAT(item.name, item.ident(tcx).span)]
} else {
// We will permit associated types if they are explicitly mentioned in the trait object.
// We can't check this here, as here we only check if it is guaranteed to not be possible.
@ -351,8 +347,8 @@ pub fn object_safety_violations_for_assoc_item(
/// Returns `Some(_)` if this method cannot be called on a trait
/// object; this does not necessarily imply that the enclosing trait
/// is not object safe, because the method might have a where clause
/// `Self:Sized`.
/// is dyn-incompatible, because the method might have a where clause
/// `Self: Sized`.
fn virtual_call_violations_for_method<'tcx>(
tcx: TyCtxt<'tcx>,
trait_def_id: DefId,
@ -932,8 +928,8 @@ fn contains_illegal_impl_trait_in_trait<'tcx>(
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
object_safety_violations,
is_object_safe,
dyn_compatibility_violations,
is_dyn_compatible,
generics_require_sized_self,
..*providers
};

View file

@ -363,7 +363,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_))
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
| ty::PredicateKind::ObjectSafe(_)
| ty::PredicateKind::DynCompatible(_)
| ty::PredicateKind::Subtype(_)
| ty::PredicateKind::Coerce(_)
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
@ -418,8 +418,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
)
}
ty::PredicateKind::ObjectSafe(trait_def_id) => {
if !self.selcx.tcx().is_object_safe(trait_def_id) {
ty::PredicateKind::DynCompatible(trait_def_id) => {
if !self.selcx.tcx().is_dyn_compatible(trait_def_id) {
ProcessResult::Error(FulfillmentErrorCode::Select(Unimplemented))
} else {
ProcessResult::Changed(vec![])

View file

@ -5,11 +5,11 @@
pub mod auto_trait;
pub(crate) mod coherence;
pub mod const_evaluatable;
mod dyn_compatibility;
mod engine;
mod fulfill;
pub mod misc;
pub mod normalize;
mod object_safety;
pub mod outlives_bounds;
pub mod project;
pub mod query;
@ -43,13 +43,13 @@ pub use self::coherence::{
InCrate, IsFirstInputType, OrphanCheckErr, OrphanCheckMode, OverlapResult, UncoveredTyParams,
add_placeholder_note, orphan_check_trait_ref, overlapping_impls,
};
pub use self::dyn_compatibility::{
DynCompatibilityViolation, dyn_compatibility_violations_for_assoc_item,
hir_ty_lowering_dyn_compatibility_violations, is_vtable_safe_method,
};
pub use self::engine::{ObligationCtxt, TraitEngineExt};
pub use self::fulfill::{FulfillmentContext, OldSolverError, PendingPredicateObligation};
pub use self::normalize::NormalizeExt;
pub use self::object_safety::{
ObjectSafetyViolation, hir_ty_lowering_object_safety_violations, is_vtable_safe_method,
object_safety_violations_for_assoc_item,
};
pub use self::project::{normalize_inherent_projection, normalize_projection_ty};
pub use self::select::{
EvaluationCache, EvaluationResult, IntercrateAmbiguityCause, OverflowError, SelectionCache,
@ -593,7 +593,7 @@ fn is_impossible_associated_item(
}
pub fn provide(providers: &mut Providers) {
object_safety::provide(providers);
dyn_compatibility::provide(providers);
vtable::provide(providers);
*providers = Providers {
specialization_graph_of: specialize::specialization_graph_provider,

View file

@ -113,7 +113,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::DynCompatible(..)
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::Ambiguous
@ -217,7 +217,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::DynCompatible(..)
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::Ambiguous

View file

@ -883,7 +883,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let Some(principal) = data.principal() {
if !self.infcx.tcx.features().object_safe_for_dispatch {
principal.with_self_ty(self.tcx(), self_ty)
} else if self.tcx().is_object_safe(principal.def_id()) {
} else if self.tcx().is_dyn_compatible(principal.def_id()) {
principal.with_self_ty(self.tcx(), self_ty)
} else {
return;

View file

@ -30,7 +30,7 @@ use crate::traits::util::{self, closure_trait_ref_and_return_type};
use crate::traits::{
ImplDerivedCause, ImplSource, ImplSourceUserDefinedData, Normalized, Obligation,
ObligationCause, PolyTraitObligation, PredicateObligation, Selection, SelectionError,
SignatureMismatch, TraitNotObjectSafe, TraitObligation, Unimplemented,
SignatureMismatch, TraitDynIncompatible, TraitObligation, Unimplemented,
};
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
@ -630,7 +630,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.cause.span,
"GATs in trait object shouldn't have been considered",
);
return Err(SelectionError::TraitNotObjectSafe(trait_predicate.trait_ref.def_id));
return Err(SelectionError::TraitDynIncompatible(trait_predicate.trait_ref.def_id));
}
// This maybe belongs in wf, but that can't (doesn't) handle
@ -1187,11 +1187,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
}
// `T` -> `Trait`
// `T` -> `dyn Trait`
(_, &ty::Dynamic(data, r, ty::Dyn)) => {
let mut object_dids = data.auto_traits().chain(data.principal_def_id());
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
return Err(TraitNotObjectSafe(did));
if let Some(did) = object_dids.find(|did| !tcx.is_dyn_compatible(*did)) {
return Err(TraitDynIncompatible(did));
}
let predicate_to_obligation = |predicate| {

View file

@ -772,8 +772,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Ok(EvaluatedToOkModuloRegions)
}
ty::PredicateKind::ObjectSafe(trait_def_id) => {
if self.tcx().is_object_safe(trait_def_id) {
ty::PredicateKind::DynCompatible(trait_def_id) => {
if self.tcx().is_dyn_compatible(trait_def_id) {
Ok(EvaluatedToOk)
} else {
Ok(EvaluatedToErr)

View file

@ -838,7 +838,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
self.cause(ObligationCauseCode::WellFormed(None)),
self.recursion_depth,
self.param_env,
ty::Binder::dummy(ty::PredicateKind::ObjectSafe(principal)),
ty::Binder::dummy(ty::PredicateKind::DynCompatible(principal)),
));
}
}