Skip to content

Commit

Permalink
Make everything builtin!
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jul 25, 2023
1 parent de81007 commit a7ed9c1
Show file tree
Hide file tree
Showing 23 changed files with 344 additions and 443 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use rustc_middle::traits::BuiltinImplSource;
use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgs};
use rustc_middle::ty::{TraitRef, TypeVisitableExt};
Expand Down Expand Up @@ -766,15 +767,15 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
};

match implsrc {
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
Ok(Some(ImplSource::Param(ty::BoundConstness::ConstIfConst, _))) => {
debug!(
"const_trait_impl: provided {:?} via where-clause in {:?}",
trait_ref, param_env
);
return;
}
// Closure: Fn{Once|Mut}
Ok(Some(ImplSource::Builtin(_)))
Ok(Some(ImplSource::Builtin(BuiltinImplSource::Misc, _)))
if trait_ref.self_ty().is_closure()
&& tcx.fn_trait_kind_from_def_id(trait_id).is_some() =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_hir::LangItem;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir;
use rustc_middle::mir::*;
use rustc_middle::traits::BuiltinImplSource;
use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
use rustc_trait_selection::traits::{
self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
Expand Down Expand Up @@ -172,7 +173,8 @@ impl Qualif for NeedsNonConstDrop {

if !matches!(
impl_src,
ImplSource::Builtin(_) | ImplSource::Param(_, ty::BoundConstness::ConstIfConst)
ImplSource::Builtin(BuiltinImplSource::Misc, _)
| ImplSource::Param(ty::BoundConstness::ConstIfConst, _)
) {
// If our const destruct candidate is not ConstDestruct or implied by the param env,
// then it's bad
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
use rustc_infer::traits::{Obligation, PredicateObligation};
use rustc_middle::lint::in_external_macro;
use rustc_middle::traits::BuiltinImplSource;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
};
Expand Down Expand Up @@ -687,12 +688,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
}

Ok(Some(impl_source)) => {
// Some builtin coercions are still unstable so we detect
// these here and emit a feature error if coercion doesn't fail
// due to another reason.
match impl_source {
traits::ImplSource::TraitUpcasting(..) => {
traits::ImplSource::Builtin(
BuiltinImplSource::TraitUpcasting { .. },
_,
) => {
has_trait_upcasting_coercion =
Some((trait_pred.self_ty(), trait_pred.trait_ref.args.type_at(1)));
}
traits::ImplSource::TupleUnsizing(_) => {
traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
has_unsized_tuple_coercion = true;
}
_ => {}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ macro_rules! span_bug {

#[macro_export]
macro_rules! CloneLiftImpls {
($($ty:ty,)+) => {
($($ty:ty),+ $(,)?) => {
$(
impl<'tcx> $crate::ty::Lift<'tcx> for $ty {
type Lifted = Self;
Expand All @@ -59,7 +59,7 @@ macro_rules! CloneLiftImpls {
/// allocated data** (i.e., don't need to be folded).
#[macro_export]
macro_rules! TrivialTypeTraversalImpls {
($($ty:ty,)+) => {
($($ty:ty),+ $(,)?) => {
$(
impl<'tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<'tcx>> for $ty {
fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<'tcx>>>(
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/mir/basic_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,7 @@ impl<'tcx> graph::WithPredecessors for BasicBlocks<'tcx> {
}
}

TrivialTypeTraversalAndLiftImpls! {
Cache,
}
TrivialTypeTraversalAndLiftImpls! { Cache }

impl<S: Encoder> Encodable<S> for Cache {
#[inline]
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo {
}
}

TrivialTypeTraversalAndLiftImpls! {
ErrorHandled,
}
TrivialTypeTraversalAndLiftImpls! { ErrorHandled }

pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,7 @@ pub enum BindingForm<'tcx> {
RefForGuard,
}

TrivialTypeTraversalAndLiftImpls! {
BindingForm<'tcx>,
}
TrivialTypeTraversalAndLiftImpls! { BindingForm<'tcx> }

mod binding_form_impl {
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
Expand Down
80 changes: 28 additions & 52 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,46 +649,31 @@ pub enum ImplSource<'tcx, N> {
/// for some type parameter. The `Vec<N>` represents the
/// obligations incurred from normalizing the where-clause (if
/// any).
Param(Vec<N>, ty::BoundConstness),
Param(ty::BoundConstness, Vec<N>),

/// Virtual calls through an object.
Object(ImplSourceObjectData<N>),

/// Successful resolution for a builtin trait.
Builtin(Vec<N>),

// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`
TupleUnsizing(Vec<N>),

/// ImplSource for trait upcasting coercion
TraitUpcasting(ImplSourceTraitUpcastingData<N>),
/// Successful resolution for a builtin impl.
Builtin(BuiltinImplSource, Vec<N>),
}

impl<'tcx, N> ImplSource<'tcx, N> {
pub fn nested_obligations(self) -> Vec<N> {
match self {
ImplSource::UserDefined(i) => i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) | ImplSource::TupleUnsizing(n) => n,
ImplSource::Object(d) => d.nested,
ImplSource::TraitUpcasting(d) => d.nested,
ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n,
}
}

pub fn borrow_nested_obligations(&self) -> &[N] {
match self {
ImplSource::UserDefined(i) => &i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) | ImplSource::TupleUnsizing(n) => &n,
ImplSource::Object(d) => &d.nested,
ImplSource::TraitUpcasting(d) => &d.nested,
ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => &n,
}
}

pub fn borrow_nested_obligations_mut(&mut self) -> &mut [N] {
match self {
ImplSource::UserDefined(i) => &mut i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) | ImplSource::TupleUnsizing(n) => n,
ImplSource::Object(d) => &mut d.nested,
ImplSource::TraitUpcasting(d) => &mut d.nested,
ImplSource::Param(_, n) | ImplSource::Builtin(_, n) => n,
}
}

Expand All @@ -702,20 +687,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
args: i.args,
nested: i.nested.into_iter().map(f).collect(),
}),
ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
ImplSource::TupleUnsizing(n) => {
ImplSource::TupleUnsizing(n.into_iter().map(f).collect())
}
ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
vtable_base: o.vtable_base,
nested: o.nested.into_iter().map(f).collect(),
}),
ImplSource::TraitUpcasting(d) => {
ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
vtable_vptr_slot: d.vtable_vptr_slot,
nested: d.nested.into_iter().map(f).collect(),
})
ImplSource::Param(ct, n) => ImplSource::Param(ct, n.into_iter().map(f).collect()),
ImplSource::Builtin(source, n) => {
ImplSource::Builtin(source, n.into_iter().map(f).collect())
}
}
}
Expand All @@ -739,29 +713,31 @@ pub struct ImplSourceUserDefinedData<'tcx, N> {
pub nested: Vec<N>,
}

#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceTraitUpcastingData<N> {
#[derive(Copy, Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Debug)]
pub enum BuiltinImplSource {
/// Some builtin impl we don't need to differentiate. This should be used
/// unless more specific information is necessary.
Misc,
/// A builtin impl for trait objects.
///
/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
/// in that vtable.
Object { vtable_base: usize },
/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
/// within that vtable.
pub vtable_vptr_slot: Option<usize>,

pub nested: Vec<N>,
TraitUpcasting { vtable_vptr_slot: Option<usize> },
/// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`.
///
/// This needs to be a separate variant as it is still unstable and we need to emit
/// a feature error when using it on stable.
TupleUnsizing,
}

#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceObjectData<N> {
/// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
/// in that vtable.
pub vtable_base: usize,

pub nested: Vec<N>,
}
TrivialTypeTraversalAndLiftImpls! { BuiltinImplSource }

#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum ObjectSafetyViolation {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,7 @@ impl From<ErrorGuaranteed> for OverflowError {
}
}

TrivialTypeTraversalAndLiftImpls! {
OverflowError,
}
TrivialTypeTraversalAndLiftImpls! { OverflowError }

impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
fn from(overflow_error: OverflowError) -> SelectionError<'tcx> {
Expand Down
36 changes: 6 additions & 30 deletions compiler/rustc_middle/src/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@ use std::fmt;

impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
super::ImplSource::UserDefined(ref v) => write!(f, "{:?}", v),
match self {
super::ImplSource::UserDefined(v) => write!(f, "{:?}", v),

super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),

super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
super::ImplSource::Builtin(source, d) => {
write!(f, "Builtin({source:?}, {d:?})")
}

super::ImplSource::Param(ref n, ct) => {
super::ImplSource::Param(ct, n) => {
write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
}

super::ImplSource::TupleUnsizing(ref d) => write!(f, "{:?}", d),

super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
}
}
}
Expand All @@ -33,23 +29,3 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceUserDefinedData<'tcx,
)
}
}

impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitUpcastingData<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ImplSourceTraitUpcastingData(vtable_vptr_slot={:?}, nested={:?})",
self.vtable_vptr_slot, self.nested
)
}
}

impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ImplSourceObjectData(vtable_base={}, nested={:?})",
self.vtable_base, self.nested
)
}
}
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/ty/abstract_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ impl From<ErrorGuaranteed> for NotConstEvaluatable {
}
}

TrivialTypeTraversalAndLiftImpls! {
NotConstEvaluatable,
}
TrivialTypeTraversalAndLiftImpls! { NotConstEvaluatable }

pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, ErrorGuaranteed>;

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub enum BindingMode {
BindByValue(Mutability),
}

TrivialTypeTraversalAndLiftImpls! { BindingMode, }
TrivialTypeTraversalAndLiftImpls! { BindingMode }

impl BindingMode {
pub fn convert(BindingAnnotation(by_ref, mutbl): BindingAnnotation) -> BindingMode {
Expand Down
Loading

0 comments on commit a7ed9c1

Please sign in to comment.