Skip to content

Commit 793a8bf

Browse files
committed
Auto merge of #117726 - eggyal:automatically_make_trivial_types_noop-traversable, r=<try>
Automatically make trivial types noop-traversable This is a second reincarnation of #108214 (or at least, what that PR ultimately became), the previous reincarnation in #117620 having been closed accidentally. It may be easier to review by commit, albeit there are quite a few of them. ## Terminology I refer to: * folds and visits as "traversals" * the types that are folded or visited as "traversables" * the folders and visitors as "traversers" * traversables on which traversers can act as "interesting" (there are currently only five: binders, types, consts, regions and predicates) and all others as "trivial" (traversals of which are no-ops) * the `TypeFoldable` and `TypeVisitable` traits (and only these traits) as the "traversable traits" ## Content This PR: * introduces a macro, `rustc_type_ir::noop_if_trivially_traversable` that uses [auto-deref specialisation](http://lukaskalbertodt.github.io/2019/12/05/generalized-autoref-based-specialization.html) to: * perform a no-op traversal on values of type `T` if the interner implements `rustc_type_ir::TriviallyTraverses<T>` (thereby obviating all need for most trivial types to implement the traversable traits—and indeed such implementations are removed) or * delegate to the relevant traversable trait implementation on `T` otherwise; * introduces an auto-trait, `rustc_middle::ty::TriviallyTraversable`, that is then "unimplemented" on the interesting types (and thereby remains implemented only on, but on all, trivial types); * implements `rustc_type_ir::TriviallyTraverses<T>` on the `TyCtxt<'tcx>` interner for all `T: rustc_middle::ty::TriviallyTraversable` (thus ensuring that, for that interner at least, trivial types do not require implementations of the traversable traits); * updates the traversable traits' derive macros to: * skip fields that reference neither any generic type parameters nor, if present, the `'tcx` lifetime parameter * use the above specialisation macro when traversing fields * if the traversable is not parameterised by a `'tcx` lifetime, generate implementations that are generic over the interner; * replaces those derive macros' distinct helper attributes (introduced in #108040) with a unified `#[skip_traversal]` helper attribute that requires a justifying reason to be provided (this does mean that the different types of traversal can no longer be independently skipped, but nowhere is that currently required or ever expected to be); * the derive macros by default refuse to be implemented on trivial types as specialisation usually negates any need—but this can be overridden with a `#[skip_traversal(impl_despite_trivial_because = "<reason>")]` attribute; * uses those derive macros in place of remaining usages of the `TrivialTypeTraversal` macros and some explicit implementations; and * a few other minor relevant refactorings. ## Commentary One limitation of auto-deref specialisation is that it cannot work for unconstrained generic types. Therefore, absent real specialisation, implementations of the traversable traits must constrain their generics: * by default, the derive macros constrain every field type `T` that references one or more generic type parameters to implementors of the relevant traversable trait—however this can be modified on a field (or variant) basis with a `#[skip_traversal(because_trivial)]` attribute so that instead the interner is constrained to implement `TriviallyTraverses<T>` (and the field is not traversed) * the constraints are applied to the field types rather than the generic type parameters to achieve a "[perfect derive](https://smallcultfollowing.com/babysteps/blog/2022/04/12/implied-bounds-and-perfect-derive/)" that not only avoids having to propagate `#[skip_traversal]` annotations into wrapping types but also works with associated types and other esoteric situations—however this could result in trait solver cycles if interesting generic field types are one day involved in recursive type definitions; * for exceptionally rare cases where traversal of an item/variant/field should be a no-op despite it being (potentially, if generic) interesting, it can be annotated with the explicit and deliberately cumbersome `#[skip_traversal(despite_potential_miscompilation_because = "<reason>")]` (which produces a no-op without adding any constraint). * (the few remaining) explicit implementations of the traversable traits over generic types are similarly constrained * indeed, for generic tuples *all element types* must implement the trait—however, since (most) trivial types no longer do, this unfortunately means that the implementations are not applicable to tuples with trivial elements and hence some such tuples have been replaced with more concrete newtypes that have appropriate constraints: c5e9447 is a particularly hefty example of this (where tuples containing `Span` are replaced with `Spanned<T>` instead). r? `@lcnr` cc `@oli-obk` `@rustbot` label A-query-system T-compiler WG-trait-system-refactor
2 parents 492e57c + 37bab7a commit 793a8bf

File tree

163 files changed

+1881
-1231
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

163 files changed

+1881
-1231
lines changed

Cargo.lock

+6
Original file line numberDiff line numberDiff line change
@@ -3918,6 +3918,7 @@ dependencies = [
39183918
"rustc_serialize",
39193919
"rustc_span",
39203920
"rustc_target",
3921+
"rustc_type_ir",
39213922
"smallvec",
39223923
"tracing",
39233924
]
@@ -4032,6 +4033,7 @@ dependencies = [
40324033
"rustc_serialize",
40334034
"rustc_span",
40344035
"rustc_target",
4036+
"rustc_type_ir",
40354037
"smallvec",
40364038
"tracing",
40374039
]
@@ -4531,6 +4533,7 @@ dependencies = [
45314533
"rustc_index",
45324534
"rustc_macros",
45334535
"rustc_serialize",
4536+
"rustc_type_ir",
45344537
"scoped-tls",
45354538
"sha1",
45364539
"sha2",
@@ -4570,6 +4573,7 @@ dependencies = [
45704573
"rustc_macros",
45714574
"rustc_serialize",
45724575
"rustc_span",
4576+
"rustc_type_ir",
45734577
"serde_json",
45744578
"tracing",
45754579
]
@@ -4601,6 +4605,7 @@ dependencies = [
46014605
"rustc_span",
46024606
"rustc_target",
46034607
"rustc_transmute",
4608+
"rustc_type_ir",
46044609
"smallvec",
46054610
"tracing",
46064611
]
@@ -4630,6 +4635,7 @@ dependencies = [
46304635
"rustc_middle",
46314636
"rustc_span",
46324637
"rustc_target",
4638+
"rustc_type_ir",
46334639
"tracing",
46344640
]
46354641

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ use rustc_middle::hir::nested_filter::OnlyBodies;
1414
use rustc_middle::mir::tcx::PlaceTy;
1515
use rustc_middle::mir::{
1616
self, AggregateKind, BindingForm, BorrowKind, CallSource, ClearCrossCrate, ConstraintCategory,
17-
FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind, Operand, Place,
18-
PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
19-
VarBindingForm,
17+
FakeReadCause, FakeReadCauseAndPlace, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind,
18+
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
19+
TerminatorKind, VarBindingForm,
2020
};
2121
use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty};
2222
use rustc_middle::util::CallKind;
@@ -671,8 +671,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
671671
let tcx = self.infcx.tcx;
672672

673673
// Find out if the predicates show that the type is a Fn or FnMut
674-
let find_fn_kind_from_did = |(pred, _): (ty::Clause<'tcx>, _)| {
675-
if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
674+
let find_fn_kind_from_did = |pred: ty::Spanned<ty::Clause<'tcx>>| {
675+
if let ty::ClauseKind::Trait(pred) = pred.node.kind().skip_binder()
676676
&& pred.self_ty() == ty
677677
{
678678
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
@@ -698,7 +698,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
698698
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx
699699
.explicit_item_bounds(def_id)
700700
.iter_instantiated_copied(tcx, args)
701-
.find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
701+
.find_map(find_fn_kind_from_did),
702702
ty::Closure(_, args) => match args.as_closure().kind() {
703703
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
704704
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
@@ -3010,9 +3010,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
30103010
impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> {
30113011
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
30123012
match statement {
3013-
Statement { kind: StatementKind::FakeRead(box (cause, place)), .. }
3014-
if *place == self.place =>
3015-
{
3013+
Statement {
3014+
kind: StatementKind::FakeRead(box FakeReadCauseAndPlace(cause, place)),
3015+
..
3016+
} if *place == self.place => {
30163017
self.cause = Some(*cause);
30173018
}
30183019
_ => (),

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use rustc_hir::intravisit::Visitor;
66
use rustc_index::IndexSlice;
77
use rustc_infer::infer::NllRegionVariableOrigin;
88
use rustc_middle::mir::{
9-
Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location,
10-
Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
9+
Body, CallSource, CastKind, ConstraintCategory, FakeReadCause, FakeReadCauseAndPlace, Local,
10+
LocalInfo, Location, Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind,
1111
};
1212
use rustc_middle::ty::adjustment::PointerCoercion;
1313
use rustc_middle::ty::{self, RegionVid, TyCtxt};
@@ -477,7 +477,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
477477
let block = &self.body.basic_blocks[location.block];
478478

479479
let kind = if let Some(&Statement {
480-
kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), place)),
480+
kind:
481+
StatementKind::FakeRead(box FakeReadCauseAndPlace(
482+
FakeReadCause::ForLet(_),
483+
place,
484+
)),
481485
..
482486
}) = block.statements.get(location.statement_index)
483487
{

compiler/rustc_borrowck/src/diagnostics/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ use rustc_index::IndexSlice;
1313
use rustc_infer::infer::LateBoundRegionConversionTime;
1414
use rustc_middle::mir::tcx::PlaceTy;
1515
use rustc_middle::mir::{
16-
AggregateKind, CallSource, ConstOperand, FakeReadCause, Local, LocalInfo, LocalKind, Location,
17-
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
18-
TerminatorKind,
16+
AggregateKind, CallSource, ConstOperand, FakeReadCause, FakeReadCauseAndPlace, Local,
17+
LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement,
18+
StatementKind, Terminator, TerminatorKind,
1919
};
2020
use rustc_middle::ty::print::Print;
2121
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
@@ -797,7 +797,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
797797

798798
// StatementKind::FakeRead only contains a def_id if they are introduced as a result
799799
// of pattern matching within a closure.
800-
if let StatementKind::FakeRead(box (cause, place)) = stmt.kind {
800+
if let StatementKind::FakeRead(box FakeReadCauseAndPlace(cause, place)) = stmt.kind {
801801
match cause {
802802
FakeReadCause::ForMatchedPlace(Some(closure_def_id))
803803
| FakeReadCause::ForLet(Some(closure_def_id)) => {

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
130130
// opt_match_place is None for let [mut] x = ... statements,
131131
// whether or not the right-hand side is a place expression
132132
if let LocalInfo::User(BindingForm::Var(VarBindingForm {
133-
opt_match_place: Some((opt_match_place, match_span)),
133+
opt_match_place: Some(opt_match_place),
134134
binding_mode: _,
135135
opt_ty_info: _,
136136
pat_span: _,
@@ -143,8 +143,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
143143
original_path,
144144
*move_from,
145145
local,
146-
opt_match_place,
147-
match_span,
146+
opt_match_place.node,
147+
opt_match_place.span,
148148
stmt_source_info.span,
149149
);
150150
return;

compiler/rustc_borrowck/src/invalidation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
6262

6363
self.mutate_place(location, *lhs, Shallow(None));
6464
}
65-
StatementKind::FakeRead(box (_, _)) => {
65+
StatementKind::FakeRead(_) => {
6666
// Only relevant for initialized/liveness/safety checks.
6767
}
6868
StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => {

compiler/rustc_borrowck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
629629

630630
self.mutate_place(location, (*lhs, span), Shallow(None), flow_state);
631631
}
632-
StatementKind::FakeRead(box (_, place)) => {
632+
StatementKind::FakeRead(box FakeReadCauseAndPlace(_, place)) => {
633633
// Read for match doesn't access any memory and is used to
634634
// assert that a place is safe and live. So we don't have to
635635
// do any checks here.

compiler/rustc_borrowck/src/type_check/canonical.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
9999
instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
100100
locations: Locations,
101101
) {
102-
for (predicate, span) in instantiated_predicates {
103-
debug!(?predicate);
104-
let category = ConstraintCategory::Predicate(span);
105-
let predicate = self.normalize_with_category(predicate, locations, category);
102+
for predicate in instantiated_predicates {
103+
debug!(?predicate.node);
104+
let category = ConstraintCategory::Predicate(predicate.span);
105+
let predicate = self.normalize_with_category(predicate.node, locations, category);
106106
self.prove_predicate(predicate, locations, category);
107107
}
108108
}

compiler/rustc_borrowck/src/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12971297
);
12981298
}
12991299
}
1300-
StatementKind::AscribeUserType(box (place, projection), variance) => {
1300+
StatementKind::AscribeUserType(box AscribeUserType(place, projection), variance) => {
13011301
let place_ty = place.ty(body, tcx).ty;
13021302
if let Err(terr) = self.relate_type_and_user_type(
13031303
place_ty,

compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ fn make_mir_scope<'ll, 'tcx>(
9090
let file_metadata = file_metadata(cx, &loc.file);
9191

9292
let parent_dbg_scope = match scope_data.inlined {
93-
Some((callee, _)) => {
93+
Some(callee) => {
9494
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
9595
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
9696
let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
9797
instance.args,
9898
ty::ParamEnv::reveal_all(),
99-
ty::EarlyBinder::bind(callee),
99+
ty::EarlyBinder::bind(callee.node),
100100
);
101101
debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| {
102102
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
@@ -116,11 +116,11 @@ fn make_mir_scope<'ll, 'tcx>(
116116
)
117117
};
118118

119-
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
119+
let inlined_at = scope_data.inlined.map(|callee| {
120120
// FIXME(eddyb) this doesn't account for the macro-related
121121
// `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does.
122-
let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
123-
cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span)
122+
let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callee.span);
123+
cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callee.span)
124124
});
125125

126126
debug_context.scopes[scope] = DebugScope {

compiler/rustc_const_eval/src/interpret/eval_context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1165,9 +1165,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
11651165
// If the stacktrace passes through MIR-inlined source scopes, add them.
11661166
let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
11671167
let mut scope_data = &frame.body.source_scopes[scope];
1168-
while let Some((instance, call_span)) = scope_data.inlined {
1169-
frames.push(FrameInfo { span, instance });
1170-
span = call_span;
1168+
while let Some(instance) = scope_data.inlined {
1169+
frames.push(FrameInfo { span, instance: instance.node });
1170+
span = instance.span;
11711171
scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
11721172
}
11731173
span

compiler/rustc_data_structures/src/intern.rs

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ mod private {
2424
#[rustc_pass_by_value]
2525
pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst);
2626

27+
pub trait Internable<'a, I>: Sized {
28+
fn intern(self, interner: I) -> Interned<'a, Self>;
29+
}
30+
2731
impl<'a, T> Interned<'a, T> {
2832
/// Create a new `Interned` value. The value referred to *must* be interned
2933
/// and thus be unique, and it *must* remain unique in the future. This

compiler/rustc_hir/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ rustc_macros = { path = "../rustc_macros" }
1515
rustc_serialize = { path = "../rustc_serialize" }
1616
rustc_span = { path = "../rustc_span" }
1717
rustc_target = { path = "../rustc_target" }
18+
rustc_type_ir = { path = "../rustc_type_ir" }
1819
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
1920
tracing = "0.1"
2021
# tidy-alphabetical-end

compiler/rustc_hir/src/hir.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -3256,7 +3256,10 @@ impl<'hir> Item<'hir> {
32563256
}
32573257

32583258
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
3259-
#[derive(Encodable, Decodable, HashStable_Generic)]
3259+
#[derive(Encodable, Decodable, HashStable_Generic, TypeFoldable, TypeVisitable)]
3260+
#[skip_traversal(
3261+
but_impl_despite_trivial_because = "`Unsafety` impls `Relate`, which is a subtrait of `TypeFoldable`."
3262+
)]
32603263
pub enum Unsafety {
32613264
Unsafe,
32623265
Normal,

compiler/rustc_hir_analysis/src/astconv/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10571057
tcx,
10581058
predicates
10591059
.iter()
1060-
.filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
1060+
.filter_map(|p| Some(p.node.as_trait_clause()?.map_bound(|t| t.trait_ref))),
10611061
assoc_name,
10621062
)
10631063
},

compiler/rustc_hir_analysis/src/astconv/object_safety.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
5757

5858
let mut trait_bounds = vec![];
5959
let mut projection_bounds = vec![];
60-
for (pred, span) in bounds.clauses() {
61-
let bound_pred = pred.kind();
60+
for pred in bounds.clauses() {
61+
let bound_pred = pred.node.kind();
6262
match bound_pred.skip_binder() {
6363
ty::ClauseKind::Trait(trait_pred) => {
6464
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
65-
trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), span));
65+
trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), pred.span));
6666
}
6767
ty::ClauseKind::Projection(proj) => {
68-
projection_bounds.push((bound_pred.rebind(proj), span));
68+
projection_bounds.push((bound_pred.rebind(proj), pred.span));
6969
}
7070
ty::ClauseKind::TypeOutlives(_) => {
7171
// Do nothing, we deal with regions separately

compiler/rustc_hir_analysis/src/bounds.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_span::Span;
2323
/// include the self type (e.g., `trait_bounds`) but in others we do not
2424
#[derive(Default, PartialEq, Eq, Clone, Debug)]
2525
pub struct Bounds<'tcx> {
26-
pub clauses: Vec<(ty::Clause<'tcx>, Span)>,
26+
pub clauses: Vec<ty::Spanned<ty::Clause<'tcx>>>,
2727
}
2828

2929
impl<'tcx> Bounds<'tcx> {
@@ -33,8 +33,10 @@ impl<'tcx> Bounds<'tcx> {
3333
region: ty::PolyTypeOutlivesPredicate<'tcx>,
3434
span: Span,
3535
) {
36-
self.clauses
37-
.push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).to_predicate(tcx), span));
36+
self.clauses.push(ty::Spanned {
37+
node: region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).to_predicate(tcx),
38+
span,
39+
});
3840
}
3941

4042
pub fn push_trait_bound(
@@ -72,14 +74,14 @@ impl<'tcx> Bounds<'tcx> {
7274
span: Span,
7375
polarity: ty::ImplPolarity,
7476
) {
75-
self.clauses.push((
76-
trait_ref
77+
self.clauses.push(ty::Spanned {
78+
node: trait_ref
7779
.map_bound(|trait_ref| {
7880
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
7981
})
8082
.to_predicate(tcx),
8183
span,
82-
));
84+
});
8385
}
8486

8587
pub fn push_projection_bound(
@@ -88,20 +90,20 @@ impl<'tcx> Bounds<'tcx> {
8890
projection: ty::PolyProjectionPredicate<'tcx>,
8991
span: Span,
9092
) {
91-
self.clauses.push((
92-
projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).to_predicate(tcx),
93+
self.clauses.push(ty::Spanned {
94+
node: projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).to_predicate(tcx),
9395
span,
94-
));
96+
});
9597
}
9698

9799
pub fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) {
98100
let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span));
99101
let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]);
100102
// Preferable to put this obligation first, since we report better errors for sized ambiguity.
101-
self.clauses.insert(0, (trait_ref.to_predicate(tcx), span));
103+
self.clauses.insert(0, ty::Spanned { node: trait_ref.to_predicate(tcx), span });
102104
}
103105

104-
pub fn clauses(&self) -> impl Iterator<Item = (ty::Clause<'tcx>, Span)> + '_ {
106+
pub fn clauses(&self) -> impl Iterator<Item = ty::Spanned<ty::Clause<'tcx>>> + '_ {
105107
self.clauses.iter().cloned()
106108
}
107109
}

0 commit comments

Comments
 (0)