Make everything builtin!

This commit is contained in:
Michael Goulet
2023-07-24 22:02:52 +00:00
parent de81007d13
commit a7ed9c1da7
23 changed files with 345 additions and 444 deletions

View File

@@ -11,7 +11,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
use rustc_middle::traits::{BuiltinImplSource, SelectionOutputTypeParameterMismatch};
use rustc_middle::ty::{
self, Binder, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt,
@@ -26,9 +26,9 @@ use crate::traits::vtable::{
};
use crate::traits::{
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
Obligation, ObligationCause, OutputTypeParameterMismatch, PolyTraitObligation,
PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, Unimplemented,
ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
OutputTypeParameterMismatch, PolyTraitObligation, PredicateObligation, Selection,
SelectionError, TraitNotObjectSafe, Unimplemented,
};
use super::BuiltinImplConditions;
@@ -48,18 +48,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut impl_src = match candidate {
BuiltinCandidate { has_nested } => {
let data = self.confirm_builtin_candidate(obligation, has_nested);
ImplSource::Builtin(data)
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}
TransmutabilityCandidate => {
let data = self.confirm_transmutability_candidate(obligation)?;
ImplSource::Builtin(data)
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}
ParamCandidate(param) => {
let obligations =
self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
ImplSource::Param(obligations, param.skip_binder().constness)
ImplSource::Param(param.skip_binder().constness, obligations)
}
ImplCandidate(impl_def_id) => {
@@ -68,76 +68,57 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
AutoImplCandidate => {
let data = self.confirm_auto_impl_candidate(obligation)?;
ImplSource::Builtin(data)
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}
ProjectionCandidate(idx, constness) => {
let obligations = self.confirm_projection_candidate(obligation, idx)?;
ImplSource::Param(obligations, constness)
ImplSource::Param(constness, obligations)
}
ObjectCandidate(idx) => {
let data = self.confirm_object_candidate(obligation, idx)?;
ImplSource::Object(data)
}
ObjectCandidate(idx) => self.confirm_object_candidate(obligation, idx)?,
ClosureCandidate { .. } => {
let vtable_closure = self.confirm_closure_candidate(obligation)?;
ImplSource::Builtin(vtable_closure)
ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure)
}
GeneratorCandidate => {
let vtable_generator = self.confirm_generator_candidate(obligation)?;
ImplSource::Builtin(vtable_generator)
ImplSource::Builtin(BuiltinImplSource::Misc, vtable_generator)
}
FutureCandidate => {
let vtable_future = self.confirm_future_candidate(obligation)?;
ImplSource::Builtin(vtable_future)
ImplSource::Builtin(BuiltinImplSource::Misc, vtable_future)
}
FnPointerCandidate { is_const } => {
let data = self.confirm_fn_pointer_candidate(obligation, is_const)?;
ImplSource::Builtin(data)
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}
TraitAliasCandidate => {
let data = self.confirm_trait_alias_candidate(obligation);
ImplSource::Builtin(data)
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}
BuiltinObjectCandidate => {
// This indicates something like `Trait + Send: Send`. In this case, we know that
// this holds because that's what the object type is telling us, and there's really
// no additional obligations to prove and no types in particular to unify, etc.
ImplSource::Builtin(Vec::new())
ImplSource::Builtin(BuiltinImplSource::Misc, Vec::new())
}
BuiltinUnsizeCandidate => {
let source =
self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
let target = self.infcx.shallow_resolve(target);
let data = self.confirm_builtin_unsize_candidate(obligation, source, target)?;
// If the source and target are both unsize goals, then we need to signify that
// this is tuple unsizing so that during unsized coercion we require the proper
// feature gate.
if matches!(source.kind(), ty::Tuple(..)) && matches!(target.kind(), ty::Tuple(..))
{
ImplSource::TupleUnsizing(data)
} else {
ImplSource::Builtin(data)
}
}
BuiltinUnsizeCandidate => self.confirm_builtin_unsize_candidate(obligation)?,
TraitUpcastingUnsizeCandidate(idx) => {
let data = self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?;
ImplSource::TraitUpcasting(data)
self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?
}
ConstDestructCandidate(def_id) => {
let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
ImplSource::Builtin(data)
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}
};
@@ -496,7 +477,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &PolyTraitObligation<'tcx>,
index: usize,
) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx();
debug!(?obligation, ?index, "confirm_object_candidate");
@@ -660,7 +641,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
(unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)),
);
Ok(ImplSourceObjectData { vtable_base, nested })
Ok(ImplSource::Builtin(BuiltinImplSource::Object { vtable_base: vtable_base }, nested))
}
fn confirm_fn_pointer_candidate(
@@ -909,7 +890,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &PolyTraitObligation<'tcx>,
idx: usize,
) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx();
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
@@ -1006,19 +987,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let vtable_vptr_slot =
prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback).unwrap();
Ok(ImplSourceTraitUpcastingData { vtable_vptr_slot, nested })
Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { vtable_vptr_slot }, nested))
}
fn confirm_builtin_unsize_candidate(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
source: Ty<'tcx>,
target: Ty<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let tcx = self.tcx();
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
// regions here. See the comment there for more details.
let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
let target = self.infcx.shallow_resolve(target);
debug!(?source, ?target, "confirm_builtin_unsize_candidate");
let mut nested = vec![];
let src;
match (source.kind(), target.kind()) {
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
(&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
@@ -1062,6 +1048,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.param_env,
obligation.predicate.rebind(outlives),
));
src = BuiltinImplSource::Misc;
}
// `T` -> `Trait`
@@ -1108,6 +1096,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
nested.push(predicate_to_obligation(
ty::Binder::dummy(ty::ClauseKind::TypeOutlives(outlives)).to_predicate(tcx),
));
src = BuiltinImplSource::Misc;
}
// `[T; n]` -> `[T]`
@@ -1118,6 +1108,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.eq(DefineOpaqueTypes::No, b, a)
.map_err(|_| Unimplemented)?;
nested.extend(obligations);
src = BuiltinImplSource::Misc;
}
// `Struct<T>` -> `Struct<U>`
@@ -1174,6 +1166,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
),
);
nested.push(tail_unsize_obligation);
src = BuiltinImplSource::Misc;
}
// `(.., T)` -> `(.., U)`
@@ -1201,12 +1195,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]),
);
nested.push(last_unsize_obligation);
src = BuiltinImplSource::TupleUnsizing;
}
_ => bug!("source: {source}, target: {target}"),
};
Ok(nested)
Ok(ImplSource::Builtin(src, nested))
}
fn confirm_const_destruct_candidate(