Skip to content

Commit 70cf33f

Browse files
committed
remove snapshot calls from "match" operations during select
Motivation: - we want to use leak-check sparingly, first off - these calls were essentially the same as doing the check during subtyping
1 parent 1e00e1b commit 70cf33f

16 files changed

+138
-188
lines changed

src/librustc_trait_selection/traits/select/candidate_assembly.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
163163
_ => return,
164164
}
165165

166-
let result = self.infcx.probe(|snapshot| {
167-
self.match_projection_obligation_against_definition_bounds(obligation, snapshot)
168-
});
166+
let result = self
167+
.infcx
168+
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
169169

170170
if result {
171171
candidates.vec.push(ProjectionCandidate);
@@ -345,8 +345,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
345345
obligation.predicate.def_id(),
346346
obligation.predicate.skip_binder().trait_ref.self_ty(),
347347
|impl_def_id| {
348-
self.infcx.probe(|snapshot| {
349-
if let Ok(_substs) = self.match_impl(impl_def_id, obligation, snapshot) {
348+
self.infcx.probe(|_| {
349+
if let Ok(_substs) = self.match_impl(impl_def_id, obligation) {
350350
candidates.vec.push(ImplCandidate(impl_def_id));
351351
}
352352
});

src/librustc_trait_selection/traits/select/confirmation.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
121121
}
122122

123123
fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) {
124-
self.infcx.commit_unconditionally(|snapshot| {
125-
let result =
126-
self.match_projection_obligation_against_definition_bounds(obligation, snapshot);
124+
self.infcx.commit_unconditionally(|_| {
125+
let result = self.match_projection_obligation_against_definition_bounds(obligation);
127126
assert!(result);
128127
})
129128
}
@@ -265,8 +264,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
265264

266265
// First, create the substitutions by matching the impl again,
267266
// this time not in a probe.
268-
self.infcx.commit_unconditionally(|snapshot| {
269-
let substs = self.rematch_impl(impl_def_id, obligation, snapshot);
267+
self.infcx.commit_unconditionally(|_| {
268+
let substs = self.rematch_impl(impl_def_id, obligation);
270269
debug!("confirm_impl_candidate: substs={:?}", substs);
271270
let cause = obligation.derived_cause(ImplDerivedObligation);
272271
ensure_sufficient_stack(|| {

src/librustc_trait_selection/traits/select/mod.rs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use super::{Normalized, ProjectionCacheKey};
2121
use super::{ObligationCause, PredicateObligation, TraitObligation};
2222
use super::{Overflow, SelectionError, Unimplemented};
2323

24-
use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, TypeFreshener};
24+
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
2525
use crate::traits::error_reporting::InferCtxtExt;
2626
use crate::traits::project::ProjectionCacheKeyExt;
2727
use rustc_ast::attr;
@@ -1268,7 +1268,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12681268
fn match_projection_obligation_against_definition_bounds(
12691269
&mut self,
12701270
obligation: &TraitObligation<'tcx>,
1271-
snapshot: &CombinedSnapshot<'_, 'tcx>,
12721271
) -> bool {
12731272
let poly_trait_predicate = self.infcx().resolve_vars_if_possible(&obligation.predicate);
12741273
let (placeholder_trait_predicate, _) =
@@ -1299,12 +1298,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12991298
if let ty::PredicateKind::Trait(bound, _) = bound.kind() {
13001299
let bound = bound.to_poly_trait_ref();
13011300
if self.infcx.probe(|_| {
1302-
self.match_projection(
1303-
obligation,
1304-
bound,
1305-
placeholder_trait_predicate.trait_ref,
1306-
snapshot,
1307-
)
1301+
self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref)
13081302
}) {
13091303
return Some(bound);
13101304
}
@@ -1321,12 +1315,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13211315
None => false,
13221316
Some(bound) => {
13231317
// Repeat the successful match, if any, this time outside of a probe.
1324-
let result = self.match_projection(
1325-
obligation,
1326-
bound,
1327-
placeholder_trait_predicate.trait_ref,
1328-
snapshot,
1329-
);
1318+
let result =
1319+
self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref);
13301320

13311321
assert!(result);
13321322
true
@@ -1339,14 +1329,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13391329
obligation: &TraitObligation<'tcx>,
13401330
trait_bound: ty::PolyTraitRef<'tcx>,
13411331
placeholder_trait_ref: ty::TraitRef<'tcx>,
1342-
snapshot: &CombinedSnapshot<'_, 'tcx>,
13431332
) -> bool {
13441333
debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars());
13451334
self.infcx
13461335
.at(&obligation.cause, obligation.param_env)
13471336
.sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound)
13481337
.is_ok()
1349-
&& self.infcx.leak_check(false, snapshot).is_ok()
13501338
}
13511339

13521340
fn evaluate_where_clause<'o>(
@@ -1811,9 +1799,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18111799
&mut self,
18121800
impl_def_id: DefId,
18131801
obligation: &TraitObligation<'tcx>,
1814-
snapshot: &CombinedSnapshot<'_, 'tcx>,
18151802
) -> Normalized<'tcx, SubstsRef<'tcx>> {
1816-
match self.match_impl(impl_def_id, obligation, snapshot) {
1803+
match self.match_impl(impl_def_id, obligation) {
18171804
Ok(substs) => substs,
18181805
Err(()) => {
18191806
bug!(
@@ -1829,7 +1816,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18291816
&mut self,
18301817
impl_def_id: DefId,
18311818
obligation: &TraitObligation<'tcx>,
1832-
snapshot: &CombinedSnapshot<'_, 'tcx>,
18331819
) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
18341820
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
18351821

@@ -1872,11 +1858,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18721858
.map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
18731859
nested_obligations.extend(obligations);
18741860

1875-
if let Err(e) = self.infcx.leak_check(false, snapshot) {
1876-
debug!("match_impl: failed leak check due to `{}`", e);
1877-
return Err(());
1878-
}
1879-
18801861
if !self.intercrate
18811862
&& self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
18821863
{

src/test/ui/associated-types/associated-types-eq-hr.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub trait TheTrait<T> {
77
}
88

99
struct IntStruct {
10-
x: isize
10+
x: isize,
1111
}
1212

1313
impl<'a> TheTrait<&'a isize> for IntStruct {
@@ -19,7 +19,7 @@ impl<'a> TheTrait<&'a isize> for IntStruct {
1919
}
2020

2121
struct UintStruct {
22-
x: isize
22+
x: isize,
2323
}
2424

2525
impl<'a> TheTrait<&'a isize> for UintStruct {
@@ -30,8 +30,7 @@ impl<'a> TheTrait<&'a isize> for UintStruct {
3030
}
3131
}
3232

33-
struct Tuple {
34-
}
33+
struct Tuple {}
3534

3635
impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple {
3736
type A = &'a isize;
@@ -42,37 +41,43 @@ impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple {
4241
}
4342

4443
fn foo<T>()
45-
where T : for<'x> TheTrait<&'x isize, A = &'x isize>
44+
where
45+
T: for<'x> TheTrait<&'x isize, A = &'x isize>,
4646
{
4747
// ok for IntStruct, but not UintStruct
4848
}
4949

5050
fn bar<T>()
51-
where T : for<'x> TheTrait<&'x isize, A = &'x usize>
51+
where
52+
T: for<'x> TheTrait<&'x isize, A = &'x usize>,
5253
{
5354
// ok for UintStruct, but not IntStruct
5455
}
5556

5657
fn tuple_one<T>()
57-
where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
58+
where
59+
T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>,
5860
{
5961
// not ok for tuple, two lifetimes and we pick first
6062
}
6163

6264
fn tuple_two<T>()
63-
where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
65+
where
66+
T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
6467
{
6568
// not ok for tuple, two lifetimes and we pick second
6669
}
6770

6871
fn tuple_three<T>()
69-
where T : for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize>
72+
where
73+
T: for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize>,
7074
{
7175
// ok for tuple
7276
}
7377

7478
fn tuple_four<T>()
75-
where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
79+
where
80+
T: for<'x, 'y> TheTrait<(&'x isize, &'y isize)>,
7681
{
7782
// not ok for tuple, two lifetimes, and lifetime matching is invariant
7883
}
@@ -89,14 +94,12 @@ pub fn call_bar() {
8994

9095
pub fn call_tuple_one() {
9196
tuple_one::<Tuple>();
92-
//~^ ERROR not satisfied
93-
//~| ERROR type mismatch
97+
//~^ ERROR type mismatch
9498
}
9599

96100
pub fn call_tuple_two() {
97101
tuple_two::<Tuple>();
98-
//~^ ERROR not satisfied
99-
//~| ERROR type mismatch
102+
//~^ ERROR type mismatch
100103
}
101104

102105
pub fn call_tuple_three() {
@@ -105,7 +108,7 @@ pub fn call_tuple_three() {
105108

106109
pub fn call_tuple_four() {
107110
tuple_four::<Tuple>();
108-
//~^ ERROR not satisfied
111+
//~^ ERROR implementation of `TheTrait` is not general enough
109112
}
110113

111-
fn main() { }
114+
fn main() {}
Lines changed: 32 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
2-
--> $DIR/associated-types-eq-hr.rs:82:5
2+
--> $DIR/associated-types-eq-hr.rs:87:5
33
|
44
LL | fn foo<T>()
55
| --- required by a bound in this
6-
LL | where T : for<'x> TheTrait<&'x isize, A = &'x isize>
7-
| ------------- required by this bound in `foo`
6+
LL | where
7+
LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
8+
| ------------- required by this bound in `foo`
89
...
910
LL | foo::<UintStruct>();
1011
| ^^^^^^^^^^^^^^^^^ expected `isize`, found `usize`
@@ -13,84 +14,60 @@ LL | foo::<UintStruct>();
1314
found reference `&usize`
1415

1516
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
16-
--> $DIR/associated-types-eq-hr.rs:86:5
17+
--> $DIR/associated-types-eq-hr.rs:91:5
1718
|
1819
LL | fn bar<T>()
1920
| --- required by a bound in this
20-
LL | where T : for<'x> TheTrait<&'x isize, A = &'x usize>
21-
| ------------- required by this bound in `bar`
21+
LL | where
22+
LL | T: for<'x> TheTrait<&'x isize, A = &'x usize>,
23+
| ------------- required by this bound in `bar`
2224
...
2325
LL | bar::<IntStruct>();
2426
| ^^^^^^^^^^^^^^^^ expected `usize`, found `isize`
2527
|
2628
= note: expected reference `&usize`
2729
found reference `&isize`
2830

29-
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
30-
--> $DIR/associated-types-eq-hr.rs:91:17
31-
|
32-
LL | fn tuple_one<T>()
33-
| --------- required by a bound in this
34-
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
35-
| ---------------------------------------------------------- required by this bound in `tuple_one`
36-
...
37-
LL | tuple_one::<Tuple>();
38-
| ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
39-
|
40-
= help: the following implementations were found:
41-
<Tuple as TheTrait<(&'a isize, &'a isize)>>
42-
4331
error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'x isize`
44-
--> $DIR/associated-types-eq-hr.rs:91:5
32+
--> $DIR/associated-types-eq-hr.rs:96:5
4533
|
4634
LL | fn tuple_one<T>()
4735
| --------- required by a bound in this
48-
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
49-
| ------------- required by this bound in `tuple_one`
36+
LL | where
37+
LL | T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>,
38+
| ------------- required by this bound in `tuple_one`
5039
...
5140
LL | tuple_one::<Tuple>();
52-
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
53-
54-
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
55-
--> $DIR/associated-types-eq-hr.rs:97:17
56-
|
57-
LL | fn tuple_two<T>()
58-
| --------- required by a bound in this
59-
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
60-
| ---------------------------------------------------------- required by this bound in `tuple_two`
61-
...
62-
LL | tuple_two::<Tuple>();
63-
| ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
64-
|
65-
= help: the following implementations were found:
66-
<Tuple as TheTrait<(&'a isize, &'a isize)>>
41+
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
6742

6843
error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'y isize`
69-
--> $DIR/associated-types-eq-hr.rs:97:5
44+
--> $DIR/associated-types-eq-hr.rs:101:5
7045
|
7146
LL | fn tuple_two<T>()
7247
| --------- required by a bound in this
73-
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
74-
| ------------- required by this bound in `tuple_two`
48+
LL | where
49+
LL | T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
50+
| ------------- required by this bound in `tuple_two`
7551
...
7652
LL | tuple_two::<Tuple>();
77-
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
53+
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
7854

79-
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
80-
--> $DIR/associated-types-eq-hr.rs:107:18
55+
error: implementation of `TheTrait` is not general enough
56+
--> $DIR/associated-types-eq-hr.rs:110:5
8157
|
82-
LL | fn tuple_four<T>()
83-
| ---------- required by a bound in this
84-
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
85-
| ------------------------------------------- required by this bound in `tuple_four`
58+
LL | / pub trait TheTrait<T> {
59+
LL | | type A;
60+
LL | |
61+
LL | | fn get(&self, t: T) -> Self::A;
62+
LL | | }
63+
| |_- trait `TheTrait` defined here
8664
...
87-
LL | tuple_four::<Tuple>();
88-
| ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
65+
LL | tuple_four::<Tuple>();
66+
| ^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
8967
|
90-
= help: the following implementations were found:
91-
<Tuple as TheTrait<(&'a isize, &'a isize)>>
68+
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
69+
= note: ...but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
9270

93-
error: aborting due to 7 previous errors
71+
error: aborting due to 5 previous errors
9472

95-
Some errors have detailed explanations: E0271, E0277.
96-
For more information about an error, try `rustc --explain E0271`.
73+
For more information about this error, try `rustc --explain E0271`.
Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied
2-
--> $DIR/hrtb-conflate-regions.rs:27:22
1+
error: implementation of `Foo` is not general enough
2+
--> $DIR/hrtb-conflate-regions.rs:27:10
33
|
4-
LL | fn want_foo2<T>()
5-
| --------- required by a bound in this
6-
LL | where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
7-
| -------------------------------------- required by this bound in `want_foo2`
4+
LL | / trait Foo<X> {
5+
LL | | fn foo(&self, x: X) { }
6+
LL | | }
7+
| |_- trait `Foo` defined here
88
...
9-
LL | fn b() { want_foo2::<SomeStruct>(); }
10-
| ^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
9+
LL | fn b() { want_foo2::<SomeStruct>(); }
10+
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
1111
|
12-
= help: the following implementations were found:
13-
<SomeStruct as Foo<(&'a isize, &'a isize)>>
12+
= note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
13+
= note: ...but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
1414

1515
error: aborting due to previous error
1616

17-
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)