Skip to content

Commit

Permalink
Finish uplifting all of structural_traits
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jun 12, 2024
1 parent be7f506 commit 47974c6
Show file tree
Hide file tree
Showing 14 changed files with 385 additions and 205 deletions.
44 changes: 44 additions & 0 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,50 @@ impl<'a, 'tcx> At<'a, 'tcx> {
}
}

/// Used in the new solver since we don't care about tracking an `ObligationCause`.
pub fn relate_no_trace<T>(
self,
expected: T,
variance: ty::Variance,
actual: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>
where
T: Relate<TyCtxt<'tcx>>,
{
let mut fields = CombineFields::new(
self.infcx,
TypeTrace::dummy(self.cause),
self.param_env,
DefineOpaqueTypes::Yes,
);
fields.sub().relate_with_variance(
variance,
ty::VarianceDiagInfo::default(),
expected,
actual,
)?;
Ok(fields.goals)
}

/// Used in the new solver since we don't care about tracking an `ObligationCause`.
pub fn eq_structurally_relating_aliases_no_trace<T>(
self,
expected: T,
actual: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>
where
T: Relate<TyCtxt<'tcx>>,
{
let mut fields = CombineFields::new(
self.infcx,
TypeTrace::dummy(self.cause),
self.param_env,
DefineOpaqueTypes::Yes,
);
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
Ok(fields.goals)
}

/// Computes the least-upper-bound, or mutual supertype, of two
/// values. The order of the arguments doesn't matter, but since
/// this can result in an error (e.g., if asked to compute LUB of
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ValuePairs::ExistentialProjection(_) => {
(false, Mismatch::Fixed("existential projection"))
}
infer::DummyPair => (false, Mismatch::Fixed("values")),
};
let Some(vals) = self.values_str(values) else {
// Derived error. Cancel the emitter.
Expand Down Expand Up @@ -2275,6 +2276,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
Some((exp, fnd, None))
}
infer::DummyPair => None,
}
}

Expand Down
75 changes: 60 additions & 15 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub use RegionVariableOrigin::*;
pub use SubregionOrigin::*;
pub use ValuePairs::*;

use crate::infer::relate::RelateResult;
use crate::infer::relate::{Relate, RelateResult};
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
use error_reporting::TypeErrCtxt;
use free_regions::RegionRelations;
Expand All @@ -35,6 +35,7 @@ use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::traits::select;
use rustc_middle::traits::solve::{Goal, NoSolution};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::BoundVarReplacerDelegate;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
Expand Down Expand Up @@ -352,29 +353,21 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
}
}

fn universe_of_ct(&self, ct: ConstVid) -> Option<ty::UniverseIndex> {
// Same issue as with `universe_of_ty`
match self.probe_const_var(ct) {
fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
Err(universe) => Some(universe),
Ok(_) => None,
}
}

fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
match self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) {
fn universe_of_ct(&self, ct: ConstVid) -> Option<ty::UniverseIndex> {
// Same issue as with `universe_of_ty`
match self.probe_const_var(ct) {
Err(universe) => Some(universe),
Ok(_) => None,
}
}

fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
}

fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
self.defining_opaque_types
}

fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'tcx> {
match self.probe_ty_var(vid) {
Ok(ty) => ty,
Expand Down Expand Up @@ -406,6 +399,26 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
}
}

fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
}

fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
self.defining_opaque_types
}

fn next_ty_infer(&self) -> Ty<'tcx> {
self.next_ty_var(DUMMY_SP)
}

fn next_const_infer(&self) -> ty::Const<'tcx> {
self.next_const_var(DUMMY_SP)
}

fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
self.fresh_args_for_item(DUMMY_SP, def_id)
}

fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
&self,
value: ty::Binder<'tcx, T>,
Expand All @@ -417,13 +430,40 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
)
}

fn enter_forall<T: TypeFoldable<Self::Interner> + Copy, U>(
fn enter_forall<T: TypeFoldable<TyCtxt<'tcx>> + Copy, U>(
&self,
value: ty::Binder<'tcx, T>,
f: impl FnOnce(T) -> U,
) -> U {
self.enter_forall(value, f)
}

fn relate<T: Relate<TyCtxt<'tcx>>>(
&self,
param_env: ty::ParamEnv<'tcx>,
lhs: T,
variance: ty::Variance,
rhs: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs)
}

fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>(
&self,
param_env: ty::ParamEnv<'tcx>,
lhs: T,
rhs: T,
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
self.at(&ObligationCause::dummy(), param_env)
.eq_structurally_relating_aliases_no_trace(lhs, rhs)
}

fn resolve_vars_if_possible<T>(&self, value: T) -> T
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
self.resolve_vars_if_possible(value)
}
}

/// See the `error_reporting` module for more details.
Expand All @@ -436,6 +476,7 @@ pub enum ValuePairs<'tcx> {
PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>),
DummyPair,
}

impl<'tcx> ValuePairs<'tcx> {
Expand Down Expand Up @@ -1858,6 +1899,10 @@ impl<'tcx> TypeTrace<'tcx> {
values: Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
}
}

fn dummy(cause: &ObligationCause<'tcx>) -> TypeTrace<'tcx> {
TypeTrace { cause: cause.clone(), values: ValuePairs::DummyPair }
}
}

impl<'tcx> SubregionOrigin<'tcx> {
Expand Down
23 changes: 21 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
use rustc_type_ir::fold::TypeFoldable;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags, WithCachedTypeInfo};
use tracing::{debug, instrument};

use std::assert_matches::assert_matches;
Expand Down Expand Up @@ -302,6 +302,25 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn has_target_features(self, def_id: DefId) -> bool {
!self.codegen_fn_attrs(def_id).target_features.is_empty()
}

fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
self.require_lang_item(
match lang_item {
TraitSolverLangItem::Future => hir::LangItem::Future,
TraitSolverLangItem::FutureOutput => hir::LangItem::FutureOutput,
TraitSolverLangItem::AsyncFnKindHelper => hir::LangItem::AsyncFnKindHelper,
TraitSolverLangItem::AsyncFnKindUpvars => hir::LangItem::AsyncFnKindUpvars,
},
None,
)
}

fn associated_type_def_ids(self, def_id: DefId) -> impl Iterator<Item = DefId> {
self.associated_items(def_id)
.in_definition_order()
.filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type))
.map(|assoc_item| assoc_item.def_id)
}
}

impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/ty/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx>
}
}

impl<'tcx> rustc_type_ir::inherent::IntoKind for Predicate<'tcx> {
type Kind = ty::Binder<'tcx, ty::PredicateKind<'tcx>>;

fn kind(self) -> Self::Kind {
self.kind()
}
}

impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
fn flags(&self) -> TypeFlags {
self.0.flags
Expand Down Expand Up @@ -120,6 +128,7 @@ impl<'tcx> Predicate<'tcx> {
/// unsoundly accept some programs. See #91068.
#[inline]
pub fn allow_normalization(self) -> bool {
// Keep this in sync with the one in `rustc_type_ir::inherent`!
match self.kind().skip_binder() {
PredicateKind::Clause(ClauseKind::WellFormed(_))
| PredicateKind::AliasRelate(..)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_next_trait_solver::solve::{Goal, NoSolution};
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::{self as ty, InferCtxtLike, Interner, Upcast};
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};

Expand Down Expand Up @@ -428,7 +429,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
nested.push(
ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None),
tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper),
[kind_ty, Ty::from_closure_kind(tcx, goal_kind)],
)
.upcast(tcx),
Expand All @@ -452,15 +453,15 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
ty::FnDef(..) | ty::FnPtr(..) => {
let bound_sig = self_ty.fn_sig(tcx);
let sig = bound_sig.skip_binder();
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future);
// `FnDef` and `FnPtr` only implement `AsyncFn*` when their
// return type implements `Future`.
let nested = vec![
bound_sig
.rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]))
.upcast(tcx),
];
let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput);
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
Expand All @@ -475,7 +476,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
let args = args.as_closure();
let bound_sig = args.sig();
let sig = bound_sig.skip_binder();
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future);
// `Closure`s only implement `AsyncFn*` when their return type
// implements `Future`.
let mut nested = vec![
Expand All @@ -493,7 +494,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
}
} else {
let async_fn_kind_trait_def_id =
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None);
tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper);
// When we don't know the closure kind (and therefore also the closure's upvars,
// which are computed at the same time), we must delay the computation of the
// generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
Expand All @@ -511,7 +512,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
);
}

let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput);
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
Expand Down Expand Up @@ -588,7 +589,7 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
args: ty::CoroutineClosureArgs<I>,
sig: ty::CoroutineClosureSignature<I>,
) -> I::Ty {
let upvars_projection_def_id = tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
let upvars_projection_def_id = tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars);
let tupled_upvars_ty = Ty::new_projection(
tcx,
upvars_projection_def_id,
Expand Down Expand Up @@ -663,19 +664,19 @@ pub(in crate::solve) fn predicates_for_object_candidate<
let mut requirements = vec![];
requirements
.extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, &trait_ref.args));
for item in tcx.associated_items(trait_ref.def_id).in_definition_order() {
// FIXME(associated_const_equality): Also add associated consts to
// the requirements here.
if item.kind == ty::AssocKind::Type {
// associated types that require `Self: Sized` do not show up in the built-in
// implementation of `Trait for dyn Trait`, and can be dropped here.
if tcx.generics_require_sized_self(item.def_id) {
continue;
}

requirements
.extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, &trait_ref.args));
// FIXME(associated_const_equality): Also add associated consts to
// the requirements here.
for associated_type_def_id in tcx.associated_type_def_ids(trait_ref.def_id) {
// associated types that require `Self: Sized` do not show up in the built-in
// implementation of `Trait for dyn Trait`, and can be dropped here.
if tcx.generics_require_sized_self(associated_type_def_id) {
continue;
}

requirements.extend(
tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, &trait_ref.args),
);
}

let mut replace_projection_with = FxHashMap::default();
Expand Down
Loading

0 comments on commit 47974c6

Please sign in to comment.