Skip to content

Commit a4bb0b1

Browse files
committed
split ignore_qualifiers
1 parent 791de9b commit a4bb0b1

File tree

37 files changed

+242
-134
lines changed

37 files changed

+242
-134
lines changed

src/librustc_infer/infer/outlives/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn explicit_outlives_bounds<'tcx>(
1515
param_env
1616
.caller_bounds
1717
.into_iter()
18-
.filter_map(move |pred| pred.ignore_qualifiers(tcx).no_bound_vars())
18+
.filter_map(move |pred| pred.ignore_qualifiers_with_unbound_vars(tcx).no_bound_vars())
1919
.filter_map(|pred| match pred.kind() {
2020
ty::PredicateKind::Projection(..)
2121
| ty::PredicateKind::Trait(..)

src/librustc_infer/infer/outlives/verify.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
331331
compare_ty: impl Fn(Ty<'tcx>) -> bool,
332332
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
333333
) -> impl Iterator<Item = ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
334-
let tcx = self.tcx;
335334
predicates
336-
.filter_map(move |p| p.to_opt_type_outlives(tcx))
335+
.filter_map(|p| p.to_opt_type_outlives())
337336
.filter_map(|p| p.no_bound_vars())
338337
.filter(move |p| compare_ty(p.0))
339338
}

src/librustc_infer/traits/util.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,14 @@ fn predicate_obligation<'tcx>(
131131
}
132132

133133
impl Elaborator<'tcx> {
134-
pub fn filter_to_traits(self) -> FilterToTraits<'tcx, Self> {
135-
FilterToTraits::new(self.visited.tcx, self)
134+
pub fn filter_to_traits(self) -> FilterToTraits<Self> {
135+
FilterToTraits::new(self)
136136
}
137137

138138
fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
139139
let tcx = self.visited.tcx;
140140

141-
match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
141+
match obligation.predicate.ignore_qualifiers_with_unbound_vars(tcx).skip_binder().kind() {
142142
ty::PredicateKind::ForAll(_) => {
143143
bug!("unexpected predicate: {:?}", obligation.predicate)
144144
}
@@ -275,7 +275,7 @@ impl Iterator for Elaborator<'tcx> {
275275
// Supertrait iterator
276276
///////////////////////////////////////////////////////////////////////////
277277

278-
pub type Supertraits<'tcx> = FilterToTraits<'tcx, Elaborator<'tcx>>;
278+
pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
279279

280280
pub fn supertraits<'tcx>(
281281
tcx: TyCtxt<'tcx>,
@@ -297,23 +297,22 @@ pub fn transitive_bounds<'tcx>(
297297

298298
/// A filter around an iterator of predicates that makes it yield up
299299
/// just trait references.
300-
pub struct FilterToTraits<'tcx, I> {
301-
tcx: TyCtxt<'tcx>,
300+
pub struct FilterToTraits<I> {
302301
base_iterator: I,
303302
}
304303

305-
impl<'tcx, I> FilterToTraits<'tcx, I> {
306-
fn new(tcx: TyCtxt<'tcx>, base: I) -> FilterToTraits<'tcx, I> {
307-
FilterToTraits { tcx, base_iterator: base }
304+
impl<I> FilterToTraits<I> {
305+
fn new(base: I) -> FilterToTraits<I> {
306+
FilterToTraits { base_iterator: base }
308307
}
309308
}
310309

311-
impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<'tcx, I> {
310+
impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<I> {
312311
type Item = ty::PolyTraitRef<'tcx>;
313312

314313
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
315314
while let Some(obligation) = self.base_iterator.next() {
316-
if let Some(data) = obligation.predicate.to_opt_poly_trait_ref(self.tcx) {
315+
if let Some(data) = obligation.predicate.to_opt_poly_trait_ref() {
317316
return Some(data);
318317
}
319318
}

src/librustc_lint/builtin.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
12141214
for &(predicate, span) in predicates.predicates {
12151215
// We don't actually look inside of the predicate,
12161216
// so it is safe to skip this binder here.
1217-
let predicate_kind_name = match predicate.ignore_qualifiers(cx.tcx).skip_binder().kind() {
1217+
let predicate_kind_name = match predicate.ignore_qualifiers_with_unbound_vars(cx.tcx).skip_binder().kind() {
12181218
Trait(..) => "Trait",
12191219
TypeOutlives(..) |
12201220
RegionOutlives(..) => "Lifetime",
@@ -1505,12 +1505,14 @@ impl ExplicitOutlivesRequirements {
15051505
) -> Vec<ty::Region<'tcx>> {
15061506
inferred_outlives
15071507
.iter()
1508-
.filter_map(|(pred, _)| match pred.ignore_qualifiers(tcx).skip_binder().kind() {
1509-
&ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a {
1510-
ty::ReEarlyBound(ebr) if ebr.index == index => Some(b),
1508+
.filter_map(|(pred, _)| {
1509+
match pred.ignore_qualifiers_with_unbound_vars(tcx).skip_binder().kind() {
1510+
&ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a {
1511+
ty::ReEarlyBound(ebr) if ebr.index == index => Some(b),
1512+
_ => None,
1513+
},
15111514
_ => None,
1512-
},
1513-
_ => None,
1515+
}
15141516
})
15151517
.collect()
15161518
}
@@ -1522,11 +1524,13 @@ impl ExplicitOutlivesRequirements {
15221524
) -> Vec<ty::Region<'tcx>> {
15231525
inferred_outlives
15241526
.iter()
1525-
.filter_map(|(pred, _)| match pred.ignore_qualifiers(tcx).skip_binder().kind() {
1526-
&ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
1527-
a.is_param(index).then_some(b)
1527+
.filter_map(|(pred, _)| {
1528+
match pred.ignore_qualifiers_with_unbound_vars(tcx).skip_binder().kind() {
1529+
&ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
1530+
a.is_param(index).then_some(b)
1531+
}
1532+
_ => None,
15281533
}
1529-
_ => None,
15301534
})
15311535
.collect()
15321536
}

src/librustc_lint/unused.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
147147
let mut has_emitted = false;
148148
for (predicate, _) in cx.tcx.predicates_of(def).predicates {
149149
// We only look at the `DefId`, so it is safe to skip the binder here.
150-
if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) =
151-
predicate.ignore_qualifiers(cx.tcx).skip_binder().kind()
150+
if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) = predicate
151+
.ignore_qualifiers_with_unbound_vars(cx.tcx)
152+
.skip_binder()
153+
.kind()
152154
{
153155
let def_id = poly_trait_predicate.trait_ref.def_id;
154156
let descr_pre =

src/librustc_middle/ty/mod.rs

+29-9
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,30 @@ impl<'tcx> Predicate<'tcx> {
10421042
}
10431043

10441044
/// Skips `PredicateKind::ForAll`.
1045-
pub fn ignore_qualifiers(self, tcx: TyCtxt<'tcx>) -> Binder<Predicate<'tcx>> {
1045+
pub fn ignore_qualifiers(self) -> Binder<Predicate<'tcx>> {
1046+
match self.kind() {
1047+
&PredicateKind::ForAll(binder) => binder,
1048+
ty::PredicateKind::Projection(..)
1049+
| ty::PredicateKind::Trait(..)
1050+
| ty::PredicateKind::Subtype(..)
1051+
| ty::PredicateKind::WellFormed(..)
1052+
| ty::PredicateKind::ObjectSafe(..)
1053+
| ty::PredicateKind::ClosureKind(..)
1054+
| ty::PredicateKind::TypeOutlives(..)
1055+
| ty::PredicateKind::ConstEvaluatable(..)
1056+
| ty::PredicateKind::ConstEquate(..)
1057+
| ty::PredicateKind::RegionOutlives(..) => Binder::dummy(self),
1058+
}
1059+
}
1060+
1061+
/// Skips `PredicateKind::ForAll`, while allowing for unbound variables.
1062+
///
1063+
/// This method requires the `TyCtxt` as it has to shift the unbound variables
1064+
/// outwards.
1065+
///
1066+
/// Do not use this method if you may end up just skipping the binder, as this
1067+
/// would leave the unbound variables at an incorrect binding level.
1068+
pub fn ignore_qualifiers_with_unbound_vars(self, tcx: TyCtxt<'tcx>) -> Binder<Predicate<'tcx>> {
10461069
match self.kind() {
10471070
&PredicateKind::ForAll(binder) => binder,
10481071
ty::PredicateKind::Projection(..)
@@ -1218,7 +1241,7 @@ impl<'tcx> Predicate<'tcx> {
12181241
// from the substitution and the value being substituted into, and
12191242
// this trick achieves that).
12201243
let substs = trait_ref.skip_binder().substs;
1221-
let pred = *self.ignore_qualifiers(tcx).skip_binder();
1244+
let pred = *self.ignore_qualifiers().skip_binder();
12221245
let new = pred.subst(tcx, substs);
12231246
if new != pred { new.potentially_qualified(tcx, PredicateKind::ForAll) } else { self }
12241247
}
@@ -1419,8 +1442,8 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
14191442
}
14201443

14211444
impl<'tcx> Predicate<'tcx> {
1422-
pub fn to_opt_poly_trait_ref(self, tcx: TyCtxt<'tcx>) -> Option<PolyTraitRef<'tcx>> {
1423-
self.ignore_qualifiers(tcx)
1445+
pub fn to_opt_poly_trait_ref(self) -> Option<PolyTraitRef<'tcx>> {
1446+
self.ignore_qualifiers()
14241447
.map_bound(|pred| match pred.kind() {
14251448
&PredicateKind::Trait(ref t, _) => Some(t.trait_ref),
14261449
PredicateKind::Projection(..)
@@ -1437,11 +1460,8 @@ impl<'tcx> Predicate<'tcx> {
14371460
.transpose()
14381461
}
14391462

1440-
pub fn to_opt_type_outlives(
1441-
self,
1442-
tcx: TyCtxt<'tcx>,
1443-
) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
1444-
self.ignore_qualifiers(tcx)
1463+
pub fn to_opt_type_outlives(self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
1464+
self.ignore_qualifiers()
14451465
.map_bound(|pred| match pred.kind() {
14461466
&PredicateKind::TypeOutlives(data) => Some(data),
14471467
PredicateKind::Trait(..)

src/librustc_middle/ty/print/pretty.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,14 @@ pub trait PrettyPrinter<'tcx>:
573573
let mut is_sized = false;
574574
p!(write("impl"));
575575
for predicate in bounds.predicates {
576-
if let Some(trait_ref) = predicate.to_opt_poly_trait_ref(self.tcx()) {
576+
// Note: We can't use `to_opt_poly_trait_ref` here as `predicate`
577+
// may contain unbound variables. We therefore do this manually.
578+
if let ty::PredicateKind::Trait(pred, _) = predicate
579+
.ignore_qualifiers_with_unbound_vars(self.tcx())
580+
.skip_binder()
581+
.kind()
582+
{
583+
let trait_ref = ty::Binder::bind(pred.trait_ref);
577584
// Don't print +Sized, but rather +?Sized if absent.
578585
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
579586
is_sized = true;

src/librustc_mir/borrow_check/diagnostics/region_errors.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
598598
let mut found = false;
599599
for predicate in bounds.predicates {
600600
if let ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_, r)) =
601-
predicate.ignore_qualifiers(self.infcx.tcx).skip_binder().kind()
601+
predicate
602+
.ignore_qualifiers_with_unbound_vars(self.infcx.tcx)
603+
.skip_binder()
604+
.kind()
602605
{
603606
if let ty::RegionKind::ReStatic = r {
604607
found = true;

src/librustc_mir/transform/qualify_min_const_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
2323
loop {
2424
let predicates = tcx.predicates_of(current);
2525
for (predicate, _) in predicates.predicates {
26-
match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
26+
match predicate.ignore_qualifiers_with_unbound_vars(tcx).skip_binder().kind() {
2727
ty::PredicateKind::ForAll(_) => bug!("unexpected predicate: {:?}", predicate),
2828
ty::PredicateKind::RegionOutlives(_)
2929
| ty::PredicateKind::TypeOutlives(_)

src/librustc_privacy/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ where
8888
let ty::GenericPredicates { parent: _, predicates } = predicates;
8989
for (predicate, _span) in predicates {
9090
// This visitor does not care about bound regions.
91-
match predicate.ignore_qualifiers(self.def_id_visitor.tcx()).skip_binder().kind() {
91+
match predicate
92+
.ignore_qualifiers_with_unbound_vars(self.def_id_visitor.tcx())
93+
.skip_binder()
94+
.kind()
95+
{
9296
&ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _) => {
9397
if self.visit_trait(trait_ref) {
9498
return true;

src/librustc_trait_selection/opaque_types.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
11601160

11611161
for predicate in &bounds.predicates {
11621162
if let ty::PredicateKind::Projection(projection) =
1163-
predicate.ignore_qualifiers(tcx).skip_binder().kind()
1163+
predicate.ignore_qualifiers_with_unbound_vars(tcx).skip_binder().kind()
11641164
{
11651165
if projection.ty.references_error() {
11661166
// No point on adding these obligations since there's a type error involved.
@@ -1259,7 +1259,8 @@ crate fn required_region_bounds(
12591259
traits::elaborate_predicates(tcx, predicates)
12601260
.filter_map(|obligation| {
12611261
debug!("required_region_bounds(obligation={:?})", obligation);
1262-
match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
1262+
match obligation.predicate.ignore_qualifiers_with_unbound_vars(tcx).skip_binder().kind()
1263+
{
12631264
ty::PredicateKind::Projection(..)
12641265
| ty::PredicateKind::Trait(..)
12651266
| ty::PredicateKind::Subtype(..)

src/librustc_trait_selection/traits/auto_trait.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,8 @@ impl AutoTraitFinder<'tcx> {
418418
ty::PredicateKind::Trait(new_trait, _),
419419
ty::PredicateKind::Trait(old_trait, _),
420420
) = (
421-
new_pred.ignore_qualifiers(self.tcx).skip_binder().kind(),
422-
old_pred.ignore_qualifiers(self.tcx).skip_binder().kind(),
421+
new_pred.ignore_qualifiers_with_unbound_vars(self.tcx).skip_binder().kind(),
422+
old_pred.ignore_qualifiers_with_unbound_vars(self.tcx).skip_binder().kind(),
423423
) {
424424
if new_trait.def_id() == old_trait.def_id() {
425425
let new_substs = new_trait.trait_ref.substs;
@@ -639,7 +639,7 @@ impl AutoTraitFinder<'tcx> {
639639
// We check this by calling is_of_param on the relevant types
640640
// from the various possible predicates
641641

642-
match predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
642+
match predicate.ignore_qualifiers_with_unbound_vars(self.tcx).skip_binder().kind() {
643643
&ty::PredicateKind::Trait(p, _) => {
644644
if self.is_param_no_infer(p.trait_ref.substs)
645645
&& !only_projections

src/librustc_trait_selection/traits/error_reporting/mod.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
255255
return;
256256
}
257257

258-
match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
258+
match obligation
259+
.predicate
260+
.ignore_qualifiers_with_unbound_vars(tcx)
261+
.skip_binder()
262+
.kind()
263+
{
259264
ty::PredicateKind::ForAll(_) => {
260265
bug!("unexpected predicate: {:?}", obligation.predicate)
261266
}
@@ -1065,8 +1070,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
10651070

10661071
// FIXME: It should be possible to deal with `ForAll` in a cleaner way.
10671072
let (cond, error) = match (
1068-
cond.ignore_qualifiers(self.tcx).skip_binder().kind(),
1069-
error.ignore_qualifiers(self.tcx).skip_binder().kind(),
1073+
cond.ignore_qualifiers_with_unbound_vars(self.tcx).skip_binder().kind(),
1074+
error.ignore_qualifiers_with_unbound_vars(self.tcx).skip_binder().kind(),
10701075
) {
10711076
(ty::PredicateKind::Trait(..), &ty::PredicateKind::Trait(error, _)) => {
10721077
(cond, ty::Binder::bind(error))
@@ -1078,8 +1083,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
10781083
};
10791084

10801085
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
1081-
if let &ty::PredicateKind::Trait(implication, _) =
1082-
obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
1086+
if let &ty::PredicateKind::Trait(implication, _) = obligation
1087+
.predicate
1088+
.ignore_qualifiers_with_unbound_vars(self.tcx)
1089+
.skip_binder()
1090+
.kind()
10831091
{
10841092
let error = error.to_poly_trait_ref();
10851093
let implication = ty::Binder::bind(implication).to_poly_trait_ref();
@@ -1161,7 +1169,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
11611169
// this can fail if the problem was higher-ranked, in which
11621170
// cause I have no idea for a good error message.
11631171
if let &ty::PredicateKind::Projection(data) =
1164-
predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
1172+
predicate.ignore_qualifiers_with_unbound_vars(self.tcx).skip_binder().kind()
11651173
{
11661174
let mut selcx = SelectionContext::new(self);
11671175
let (data, _) = self.replace_bound_vars_with_fresh_vars(
@@ -1454,7 +1462,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
14541462
return;
14551463
}
14561464

1457-
let mut err = match predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
1465+
let mut err = match predicate
1466+
.ignore_qualifiers_with_unbound_vars(self.tcx)
1467+
.skip_binder()
1468+
.kind()
1469+
{
14581470
&ty::PredicateKind::Trait(data, _) => {
14591471
let trait_ref = ty::Binder::bind(data.trait_ref);
14601472
let self_ty = trait_ref.skip_binder().self_ty();
@@ -1708,7 +1720,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
17081720
obligation: &PredicateObligation<'tcx>,
17091721
) {
17101722
let (pred, item_def_id, span) = match (
1711-
obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind(),
1723+
obligation.predicate.ignore_qualifiers_with_unbound_vars(self.tcx).skip_binder().kind(),
17121724
obligation.cause.code.peel_derives(),
17131725
) {
17141726
(

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -1331,11 +1331,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
13311331
// the type. The last generator (`outer_generator` below) has information about where the
13321332
// bound was introduced. At least one generator should be present for this diagnostic to be
13331333
// modified.
1334-
let (mut trait_ref, mut target_ty) =
1335-
match obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
1336-
ty::PredicateKind::Trait(p, _) => (Some(p.trait_ref), Some(p.self_ty())),
1337-
_ => (None, None),
1338-
};
1334+
let (mut trait_ref, mut target_ty) = match obligation
1335+
.predicate
1336+
.ignore_qualifiers_with_unbound_vars(self.tcx)
1337+
.skip_binder()
1338+
.kind()
1339+
{
1340+
ty::PredicateKind::Trait(p, _) => (Some(p.trait_ref), Some(p.self_ty())),
1341+
_ => (None, None),
1342+
};
13391343
let mut generator = None;
13401344
let mut outer_generator = None;
13411345
let mut next_code = Some(&obligation.cause.code);

src/librustc_trait_selection/traits/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,11 @@ pub fn normalize_param_env_or_error<'tcx>(
328328
// This works fairly well because trait matching does not actually care about param-env
329329
// TypeOutlives predicates - these are normally used by regionck.
330330
let outlives_predicates: Vec<_> = predicates
331-
.drain_filter(|predicate| match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
332-
ty::PredicateKind::TypeOutlives(..) => true,
333-
_ => false,
331+
.drain_filter(|predicate| {
332+
match predicate.ignore_qualifiers_with_unbound_vars(tcx).skip_binder().kind() {
333+
ty::PredicateKind::TypeOutlives(..) => true,
334+
_ => false,
335+
}
334336
})
335337
.collect();
336338

0 commit comments

Comments
 (0)