Skip to content

Commit 9a2ac67

Browse files
authored
Rollup merge of rust-lang#72508 - ecstatic-morse:poly-self-ty, r=nikomatsakis
Make `PolyTraitRef::self_ty` return `Binder<Ty>` This came up during review of rust-lang#71618. The current implementation is the same as a call to `skip_binder` but harder to audit. Make it preserve binding levels and add a call to `skip_binder` at all use sites so they can be audited as part of rust-lang#72507.
2 parents a6111b1 + 09cd547 commit 9a2ac67

File tree

7 files changed

+41
-24
lines changed

7 files changed

+41
-24
lines changed

src/librustc_middle/ty/sty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -764,8 +764,8 @@ impl<'tcx> TraitRef<'tcx> {
764764
pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
765765

766766
impl<'tcx> PolyTraitRef<'tcx> {
767-
pub fn self_ty(&self) -> Ty<'tcx> {
768-
self.skip_binder().self_ty()
767+
pub fn self_ty(&self) -> Binder<Ty<'tcx>> {
768+
self.map_bound_ref(|tr| tr.self_ty())
769769
}
770770

771771
pub fn def_id(&self) -> DefId {

src/librustc_trait_selection/traits/error_reporting/mod.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
289289
(
290290
Some(format!(
291291
"`?` couldn't convert the error to `{}`",
292-
trait_ref.self_ty(),
292+
trait_ref.skip_binder().self_ty(),
293293
)),
294294
Some(
295295
"the question mark operation (`?`) implicitly performs a \
@@ -339,7 +339,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
339339
if let Some(ret_span) = self.return_type_span(obligation) {
340340
err.span_label(
341341
ret_span,
342-
&format!("expected `{}` because of this", trait_ref.self_ty()),
342+
&format!(
343+
"expected `{}` because of this",
344+
trait_ref.skip_binder().self_ty()
345+
),
343346
);
344347
}
345348
}
@@ -352,7 +355,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
352355
"{}the trait `{}` is not implemented for `{}`",
353356
pre_message,
354357
trait_ref.print_only_trait_path(),
355-
trait_ref.self_ty(),
358+
trait_ref.skip_binder().self_ty(),
356359
)
357360
};
358361

@@ -642,7 +645,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
642645
return;
643646
}
644647

645-
let found_trait_ty = found_trait_ref.self_ty();
648+
let found_trait_ty = match found_trait_ref.self_ty().no_bound_vars() {
649+
Some(ty) => ty,
650+
None => return,
651+
};
646652

647653
let found_did = match found_trait_ty.kind {
648654
ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
@@ -1359,11 +1365,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
13591365
) {
13601366
let get_trait_impl = |trait_def_id| {
13611367
let mut trait_impl = None;
1362-
self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| {
1363-
if trait_impl.is_none() {
1364-
trait_impl = Some(impl_def_id);
1365-
}
1366-
});
1368+
self.tcx.for_each_relevant_impl(
1369+
trait_def_id,
1370+
trait_ref.skip_binder().self_ty(),
1371+
|impl_def_id| {
1372+
if trait_impl.is_none() {
1373+
trait_impl = Some(impl_def_id);
1374+
}
1375+
},
1376+
);
13671377
trait_impl
13681378
};
13691379
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
@@ -1434,7 +1444,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
14341444
let mut err = match predicate.kind() {
14351445
ty::PredicateKind::Trait(ref data, _) => {
14361446
let trait_ref = data.to_poly_trait_ref();
1437-
let self_ty = trait_ref.self_ty();
1447+
let self_ty = trait_ref.skip_binder().self_ty();
14381448
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);
14391449

14401450
if predicate.references_error() {
@@ -1552,7 +1562,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
15521562
}
15531563
ty::PredicateKind::Projection(ref data) => {
15541564
let trait_ref = data.to_poly_trait_ref(self.tcx);
1555-
let self_ty = trait_ref.self_ty();
1565+
let self_ty = trait_ref.skip_binder().self_ty();
15561566
let ty = data.skip_binder().ty;
15571567
if predicate.references_error() {
15581568
return;

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
318318
trait_ref: ty::PolyTraitRef<'tcx>,
319319
body_id: hir::HirId,
320320
) {
321-
let self_ty = trait_ref.self_ty();
321+
let self_ty = trait_ref.skip_binder().self_ty();
322322
let (param_ty, projection) = match &self_ty.kind {
323323
ty::Param(_) => (true, None),
324324
ty::Projection(projection) => (false, Some(projection)),
@@ -524,7 +524,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
524524
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
525525
points_at_arg: bool,
526526
) {
527-
let self_ty = trait_ref.self_ty();
527+
let self_ty = match trait_ref.self_ty().no_bound_vars() {
528+
None => return,
529+
Some(ty) => ty,
530+
};
531+
528532
let (def_id, output_ty, callable) = match self_ty.kind {
529533
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig().output(), "closure"),
530534
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
@@ -829,6 +833,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
829833
span: Span,
830834
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
831835
) {
836+
let is_empty_tuple =
837+
|ty: ty::Binder<Ty<'_>>| ty.skip_binder().kind == ty::Tuple(ty::List::empty());
838+
832839
let hir = self.tcx.hir();
833840
let parent_node = hir.get_parent_node(obligation.cause.body_id);
834841
let node = hir.find(parent_node);
@@ -840,7 +847,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
840847
if let hir::ExprKind::Block(blk, _) = &body.value.kind {
841848
if sig.decl.output.span().overlaps(span)
842849
&& blk.expr.is_none()
843-
&& "()" == &trait_ref.self_ty().to_string()
850+
&& is_empty_tuple(trait_ref.self_ty())
844851
{
845852
// FIXME(estebank): When encountering a method with a trait
846853
// bound not satisfied in the return type with a body that has
@@ -1271,7 +1278,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
12711278
ObligationCauseCode::DerivedObligation(derived_obligation)
12721279
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
12731280
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {
1274-
let ty = derived_obligation.parent_trait_ref.self_ty();
1281+
let ty = derived_obligation.parent_trait_ref.skip_binder().self_ty();
12751282
debug!(
12761283
"maybe_note_obligation_cause_for_async_await: \
12771284
parent_trait_ref={:?} self_ty.kind={:?}",
@@ -1911,7 +1918,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
19111918

19121919
let impls_future = self.tcx.type_implements_trait((
19131920
future_trait,
1914-
self_ty,
1921+
self_ty.skip_binder(),
19151922
ty::List::empty(),
19161923
obligation.param_env,
19171924
));
@@ -1927,7 +1934,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
19271934
let projection_ty = ty::ProjectionTy {
19281935
// `T`
19291936
substs: self.tcx.mk_substs_trait(
1930-
trait_ref.self_ty(),
1937+
trait_ref.self_ty().skip_binder(),
19311938
self.fresh_substs_for_item(span, item_def_id),
19321939
),
19331940
// `Future::Output`

src/librustc_trait_selection/traits/specialize/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
496496
for (p, _) in predicates {
497497
if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
498498
if Some(poly_trait_ref.def_id()) == sized_trait {
499-
types_without_default_bounds.remove(poly_trait_ref.self_ty());
499+
types_without_default_bounds.remove(poly_trait_ref.self_ty().skip_binder());
500500
continue;
501501
}
502502
}

src/librustc_typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3810,7 +3810,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38103810
trait_ref: ty::PolyTraitRef<'tcx>,
38113811
expected_vid: ty::TyVid,
38123812
) -> bool {
3813-
let self_ty = self.shallow_resolve(trait_ref.self_ty());
3813+
let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
38143814
debug!(
38153815
"self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
38163816
trait_ref, self_ty, expected_vid

src/librustdoc/clean/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
500500
fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
501501
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
502502
WherePredicate::BoundPredicate {
503-
ty: poly_trait_ref.self_ty().clean(cx),
503+
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
504504
bounds: vec![poly_trait_ref.clean(cx)],
505505
}
506506
}
@@ -755,7 +755,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
755755
let mut projection = None;
756756
let param_idx = (|| {
757757
if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
758-
if let ty::Param(param) = trait_ref.self_ty().kind {
758+
if let ty::Param(param) = trait_ref.skip_binder().self_ty().kind {
759759
return Some(param.index);
760760
}
761761
} else if let Some(outlives) = p.to_opt_type_outlives() {

src/tools/clippy/clippy_lints/src/future_not_send.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FutureNotSend {
9595
let trait_ref = trait_pred.to_poly_trait_ref();
9696
db.note(&*format!(
9797
"`{}` doesn't implement `{}`",
98-
trait_ref.self_ty(),
98+
trait_ref.skip_binder().self_ty(),
9999
trait_ref.print_only_trait_path(),
100100
));
101101
}

0 commit comments

Comments
 (0)