Skip to content

Commit 47974c6

Browse files
Finish uplifting all of structural_traits
1 parent be7f506 commit 47974c6

File tree

14 files changed

+385
-205
lines changed

14 files changed

+385
-205
lines changed

compiler/rustc_infer/src/infer/at.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,50 @@ impl<'a, 'tcx> At<'a, 'tcx> {
225225
}
226226
}
227227

228+
/// Used in the new solver since we don't care about tracking an `ObligationCause`.
229+
pub fn relate_no_trace<T>(
230+
self,
231+
expected: T,
232+
variance: ty::Variance,
233+
actual: T,
234+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>
235+
where
236+
T: Relate<TyCtxt<'tcx>>,
237+
{
238+
let mut fields = CombineFields::new(
239+
self.infcx,
240+
TypeTrace::dummy(self.cause),
241+
self.param_env,
242+
DefineOpaqueTypes::Yes,
243+
);
244+
fields.sub().relate_with_variance(
245+
variance,
246+
ty::VarianceDiagInfo::default(),
247+
expected,
248+
actual,
249+
)?;
250+
Ok(fields.goals)
251+
}
252+
253+
/// Used in the new solver since we don't care about tracking an `ObligationCause`.
254+
pub fn eq_structurally_relating_aliases_no_trace<T>(
255+
self,
256+
expected: T,
257+
actual: T,
258+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>
259+
where
260+
T: Relate<TyCtxt<'tcx>>,
261+
{
262+
let mut fields = CombineFields::new(
263+
self.infcx,
264+
TypeTrace::dummy(self.cause),
265+
self.param_env,
266+
DefineOpaqueTypes::Yes,
267+
);
268+
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
269+
Ok(fields.goals)
270+
}
271+
228272
/// Computes the least-upper-bound, or mutual supertype, of two
229273
/// values. The order of the arguments doesn't matter, but since
230274
/// this can result in an error (e.g., if asked to compute LUB of

compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
17071707
ValuePairs::ExistentialProjection(_) => {
17081708
(false, Mismatch::Fixed("existential projection"))
17091709
}
1710+
infer::DummyPair => (false, Mismatch::Fixed("values")),
17101711
};
17111712
let Some(vals) = self.values_str(values) else {
17121713
// Derived error. Cancel the emitter.
@@ -2275,6 +2276,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22752276
let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
22762277
Some((exp, fnd, None))
22772278
}
2279+
infer::DummyPair => None,
22782280
}
22792281
}
22802282

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub use RegionVariableOrigin::*;
1111
pub use SubregionOrigin::*;
1212
pub use ValuePairs::*;
1313

14-
use crate::infer::relate::RelateResult;
14+
use crate::infer::relate::{Relate, RelateResult};
1515
use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
1616
use error_reporting::TypeErrCtxt;
1717
use free_regions::RegionRelations;
@@ -35,6 +35,7 @@ use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
3535
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
3636
use rustc_middle::mir::ConstraintCategory;
3737
use rustc_middle::traits::select;
38+
use rustc_middle::traits::solve::{Goal, NoSolution};
3839
use rustc_middle::ty::error::{ExpectedFound, TypeError};
3940
use rustc_middle::ty::fold::BoundVarReplacerDelegate;
4041
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
@@ -352,29 +353,21 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
352353
}
353354
}
354355

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

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

370-
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
371-
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
372-
}
373-
374-
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
375-
self.defining_opaque_types
376-
}
377-
378371
fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'tcx> {
379372
match self.probe_ty_var(vid) {
380373
Ok(ty) => ty,
@@ -406,6 +399,26 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
406399
}
407400
}
408401

402+
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
403+
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
404+
}
405+
406+
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
407+
self.defining_opaque_types
408+
}
409+
410+
fn next_ty_infer(&self) -> Ty<'tcx> {
411+
self.next_ty_var(DUMMY_SP)
412+
}
413+
414+
fn next_const_infer(&self) -> ty::Const<'tcx> {
415+
self.next_const_var(DUMMY_SP)
416+
}
417+
418+
fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
419+
self.fresh_args_for_item(DUMMY_SP, def_id)
420+
}
421+
409422
fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>(
410423
&self,
411424
value: ty::Binder<'tcx, T>,
@@ -417,13 +430,40 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
417430
)
418431
}
419432

420-
fn enter_forall<T: TypeFoldable<Self::Interner> + Copy, U>(
433+
fn enter_forall<T: TypeFoldable<TyCtxt<'tcx>> + Copy, U>(
421434
&self,
422435
value: ty::Binder<'tcx, T>,
423436
f: impl FnOnce(T) -> U,
424437
) -> U {
425438
self.enter_forall(value, f)
426439
}
440+
441+
fn relate<T: Relate<TyCtxt<'tcx>>>(
442+
&self,
443+
param_env: ty::ParamEnv<'tcx>,
444+
lhs: T,
445+
variance: ty::Variance,
446+
rhs: T,
447+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
448+
self.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs)
449+
}
450+
451+
fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>(
452+
&self,
453+
param_env: ty::ParamEnv<'tcx>,
454+
lhs: T,
455+
rhs: T,
456+
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
457+
self.at(&ObligationCause::dummy(), param_env)
458+
.eq_structurally_relating_aliases_no_trace(lhs, rhs)
459+
}
460+
461+
fn resolve_vars_if_possible<T>(&self, value: T) -> T
462+
where
463+
T: TypeFoldable<TyCtxt<'tcx>>,
464+
{
465+
self.resolve_vars_if_possible(value)
466+
}
427467
}
428468

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

441482
impl<'tcx> ValuePairs<'tcx> {
@@ -1858,6 +1899,10 @@ impl<'tcx> TypeTrace<'tcx> {
18581899
values: Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
18591900
}
18601901
}
1902+
1903+
fn dummy(cause: &ObligationCause<'tcx>) -> TypeTrace<'tcx> {
1904+
TypeTrace { cause: cause.clone(), values: ValuePairs::DummyPair }
1905+
}
18611906
}
18621907

18631908
impl<'tcx> SubregionOrigin<'tcx> {

compiler/rustc_middle/src/ty/context.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ use rustc_span::{Span, DUMMY_SP};
7070
use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx};
7171
use rustc_target::spec::abi;
7272
use rustc_type_ir::fold::TypeFoldable;
73+
use rustc_type_ir::lang_items::TraitSolverLangItem;
7374
use rustc_type_ir::TyKind::*;
74-
use rustc_type_ir::WithCachedTypeInfo;
75-
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
75+
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags, WithCachedTypeInfo};
7676
use tracing::{debug, instrument};
7777

7878
use std::assert_matches::assert_matches;
@@ -302,6 +302,25 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
302302
fn has_target_features(self, def_id: DefId) -> bool {
303303
!self.codegen_fn_attrs(def_id).target_features.is_empty()
304304
}
305+
306+
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
307+
self.require_lang_item(
308+
match lang_item {
309+
TraitSolverLangItem::Future => hir::LangItem::Future,
310+
TraitSolverLangItem::FutureOutput => hir::LangItem::FutureOutput,
311+
TraitSolverLangItem::AsyncFnKindHelper => hir::LangItem::AsyncFnKindHelper,
312+
TraitSolverLangItem::AsyncFnKindUpvars => hir::LangItem::AsyncFnKindUpvars,
313+
},
314+
None,
315+
)
316+
}
317+
318+
fn associated_type_def_ids(self, def_id: DefId) -> impl Iterator<Item = DefId> {
319+
self.associated_items(def_id)
320+
.in_definition_order()
321+
.filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type))
322+
.map(|assoc_item| assoc_item.def_id)
323+
}
305324
}
306325

307326
impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {

compiler/rustc_middle/src/ty/predicate.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx>
5151
}
5252
}
5353

54+
impl<'tcx> rustc_type_ir::inherent::IntoKind for Predicate<'tcx> {
55+
type Kind = ty::Binder<'tcx, ty::PredicateKind<'tcx>>;
56+
57+
fn kind(self) -> Self::Kind {
58+
self.kind()
59+
}
60+
}
61+
5462
impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
5563
fn flags(&self) -> TypeFlags {
5664
self.0.flags
@@ -120,6 +128,7 @@ impl<'tcx> Predicate<'tcx> {
120128
/// unsoundly accept some programs. See #91068.
121129
#[inline]
122130
pub fn allow_normalization(self) -> bool {
131+
// Keep this in sync with the one in `rustc_type_ir::inherent`!
123132
match self.kind().skip_binder() {
124133
PredicateKind::Clause(ClauseKind::WellFormed(_))
125134
| PredicateKind::AliasRelate(..)

compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
66
use rustc_next_trait_solver::solve::{Goal, NoSolution};
77
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
88
use rustc_type_ir::inherent::*;
9+
use rustc_type_ir::lang_items::TraitSolverLangItem;
910
use rustc_type_ir::{self as ty, InferCtxtLike, Interner, Upcast};
1011
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
1112

@@ -428,7 +429,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
428429
nested.push(
429430
ty::TraitRef::new(
430431
tcx,
431-
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None),
432+
tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper),
432433
[kind_ty, Ty::from_closure_kind(tcx, goal_kind)],
433434
)
434435
.upcast(tcx),
@@ -452,15 +453,15 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
452453
ty::FnDef(..) | ty::FnPtr(..) => {
453454
let bound_sig = self_ty.fn_sig(tcx);
454455
let sig = bound_sig.skip_binder();
455-
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
456+
let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future);
456457
// `FnDef` and `FnPtr` only implement `AsyncFn*` when their
457458
// return type implements `Future`.
458459
let nested = vec![
459460
bound_sig
460461
.rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()]))
461462
.upcast(tcx),
462463
];
463-
let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
464+
let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput);
464465
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
465466
Ok((
466467
bound_sig.rebind(AsyncCallableRelevantTypes {
@@ -475,7 +476,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
475476
let args = args.as_closure();
476477
let bound_sig = args.sig();
477478
let sig = bound_sig.skip_binder();
478-
let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
479+
let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future);
479480
// `Closure`s only implement `AsyncFn*` when their return type
480481
// implements `Future`.
481482
let mut nested = vec![
@@ -493,7 +494,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
493494
}
494495
} else {
495496
let async_fn_kind_trait_def_id =
496-
tcx.require_lang_item(LangItem::AsyncFnKindHelper, None);
497+
tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper);
497498
// When we don't know the closure kind (and therefore also the closure's upvars,
498499
// which are computed at the same time), we must delay the computation of the
499500
// generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
@@ -511,7 +512,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
511512
);
512513
}
513514

514-
let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None);
515+
let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput);
515516
let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]);
516517
Ok((
517518
bound_sig.rebind(AsyncCallableRelevantTypes {
@@ -588,7 +589,7 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
588589
args: ty::CoroutineClosureArgs<I>,
589590
sig: ty::CoroutineClosureSignature<I>,
590591
) -> I::Ty {
591-
let upvars_projection_def_id = tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None);
592+
let upvars_projection_def_id = tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars);
592593
let tupled_upvars_ty = Ty::new_projection(
593594
tcx,
594595
upvars_projection_def_id,
@@ -663,19 +664,19 @@ pub(in crate::solve) fn predicates_for_object_candidate<
663664
let mut requirements = vec![];
664665
requirements
665666
.extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, &trait_ref.args));
666-
for item in tcx.associated_items(trait_ref.def_id).in_definition_order() {
667-
// FIXME(associated_const_equality): Also add associated consts to
668-
// the requirements here.
669-
if item.kind == ty::AssocKind::Type {
670-
// associated types that require `Self: Sized` do not show up in the built-in
671-
// implementation of `Trait for dyn Trait`, and can be dropped here.
672-
if tcx.generics_require_sized_self(item.def_id) {
673-
continue;
674-
}
675667

676-
requirements
677-
.extend(tcx.item_bounds(item.def_id).iter_instantiated(tcx, &trait_ref.args));
668+
// FIXME(associated_const_equality): Also add associated consts to
669+
// the requirements here.
670+
for associated_type_def_id in tcx.associated_type_def_ids(trait_ref.def_id) {
671+
// associated types that require `Self: Sized` do not show up in the built-in
672+
// implementation of `Trait for dyn Trait`, and can be dropped here.
673+
if tcx.generics_require_sized_self(associated_type_def_id) {
674+
continue;
678675
}
676+
677+
requirements.extend(
678+
tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, &trait_ref.args),
679+
);
679680
}
680681

681682
let mut replace_projection_with = FxHashMap::default();

0 commit comments

Comments
 (0)