Skip to content

Commit 12238b9

Browse files
committed
Auto merge of #33816 - nikomatsakis:projection-cache-2, r=arielb1
Projection cache and better warnings for #32330 This PR does three things: - it lays the groundwork for the more precise subtyping rules discussed in #32330, but does not enable them; - it issues warnings when the result of a leak-check or subtyping check relies on a late-bound region which will late become early-bound when #32330 is fixed; - it introduces a cache for projection in the inference context. I'm not 100% happy with the approach taken by the cache here, but it seems like a step in the right direction. It results in big wins on some test cases, but not as big as previous versions -- I think because it is caching the `Vec<Obligation>` (whereas before I just returned the normalized type with an empty vector). However, that change was needed to fix an ICE in @alexcrichton's future-rs module (I haven't fully tracked the cause of that ICE yet). Also, because trans/the collector use a fresh inference context for every call to `fulfill_obligation`, they don't profit nearly as much from this cache as they ought to. Still, here are the results from the future-rs `retry.rs`: ``` 06:26 <nmatsakis> time: 6.246; rss: 44MB item-bodies checking 06:26 <nmatsakis> time: 54.783; rss: 63MB translation item collection 06:26 <nmatsakis> time: 140.086; rss: 86MB translation 06:26 <nmatsakis> time: 0.361; rss: 46MB item-bodies checking 06:26 <nmatsakis> time: 5.299; rss: 63MB translation item collection 06:26 <nmatsakis> time: 12.140; rss: 86MB translation ``` ~~Another example is the example from #31849. For that, I get 34s to run item-bodies without any cache. The version of the cache included here takes 2s to run item-bodies type-checking. An alternative version which doesn't track nested obligations takes 0.2s, but that version ICEs on @alexcrichton's future-rs (and may well be incorrect, I've not fully convinced myself of that). So, a definite win, but I think there's definitely room for further progress.~~ Pushed a modified version which improves performance of the case from #31849: ``` lunch-box. time rustc --stage0 ~/tmp/issue-31849.rs -Z no-trans real 0m33.539s user 0m32.932s sys 0m0.570s lunch-box. time rustc --stage2 ~/tmp/issue-31849.rs -Z no-trans real 0m0.195s user 0m0.154s sys 0m0.042s ``` Some sort of cache is also needed for unblocking further work on lazy normalization, since that will lean even more heavily on the cache, and will also require cycle detection. r? @arielb1
2 parents 382ab92 + 480d18c commit 12238b9

Some content is hidden

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

49 files changed

+2149
-633
lines changed

src/librustc/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1647,5 +1647,5 @@ register_diagnostics! {
16471647
E0490, // a value of type `..` is borrowed for too long
16481648
E0491, // in type `..`, reference has a longer lifetime than the data it...
16491649
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
1650-
E0525, // expected a closure that implements `..` but this closure only implements `..`
1650+
E0525 // expected a closure that implements `..` but this closure only implements `..`
16511651
}

src/librustc/hir/intravisit.rs

+31-23
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ pub trait Visitor<'v> : Sized {
132132
fn visit_generics(&mut self, g: &'v Generics) {
133133
walk_generics(self, g)
134134
}
135+
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) {
136+
walk_where_predicate(self, predicate)
137+
}
135138
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
136139
walk_fn(self, fk, fd, b, s)
137140
}
@@ -529,29 +532,34 @@ pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics
529532
walk_list!(visitor, visit_ty, &param.default);
530533
}
531534
walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
532-
for predicate in &generics.where_clause.predicates {
533-
match predicate {
534-
&WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
535-
ref bounds,
536-
ref bound_lifetimes,
537-
..}) => {
538-
visitor.visit_ty(bounded_ty);
539-
walk_list!(visitor, visit_ty_param_bound, bounds);
540-
walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
541-
}
542-
&WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
543-
ref bounds,
544-
..}) => {
545-
visitor.visit_lifetime(lifetime);
546-
walk_list!(visitor, visit_lifetime, bounds);
547-
}
548-
&WherePredicate::EqPredicate(WhereEqPredicate{id,
549-
ref path,
550-
ref ty,
551-
..}) => {
552-
visitor.visit_path(path, id);
553-
visitor.visit_ty(ty);
554-
}
535+
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
536+
}
537+
538+
pub fn walk_where_predicate<'v, V: Visitor<'v>>(
539+
visitor: &mut V,
540+
predicate: &'v WherePredicate)
541+
{
542+
match predicate {
543+
&WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
544+
ref bounds,
545+
ref bound_lifetimes,
546+
..}) => {
547+
visitor.visit_ty(bounded_ty);
548+
walk_list!(visitor, visit_ty_param_bound, bounds);
549+
walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
550+
}
551+
&WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
552+
ref bounds,
553+
..}) => {
554+
visitor.visit_lifetime(lifetime);
555+
walk_list!(visitor, visit_lifetime, bounds);
556+
}
557+
&WherePredicate::EqPredicate(WhereEqPredicate{id,
558+
ref path,
559+
ref ty,
560+
..}) => {
561+
visitor.visit_path(path, id);
562+
visitor.visit_ty(ty);
555563
}
556564
}
557565
}

src/librustc/infer/error_reporting.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ use hir::map as ast_map;
7777
use hir;
7878
use hir::print as pprust;
7979

80+
use lint;
8081
use hir::def::Def;
8182
use hir::def_id::DefId;
8283
use infer::{self, TypeOrigin};
@@ -1017,6 +1018,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10171018
let (fn_decl, generics) = rebuilder.rebuild();
10181019
self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name, &generics, span);
10191020
}
1021+
1022+
pub fn issue_32330_warnings(&self, span: Span, issue32330s: &[ty::Issue32330]) {
1023+
for issue32330 in issue32330s {
1024+
match *issue32330 {
1025+
ty::Issue32330::WontChange => { }
1026+
ty::Issue32330::WillChange { fn_def_id, region_name } => {
1027+
self.tcx.sess.add_lint(
1028+
lint::builtin::HR_LIFETIME_IN_ASSOC_TYPE,
1029+
ast::CRATE_NODE_ID,
1030+
span,
1031+
format!("lifetime parameter `{0}` declared on fn `{1}` \
1032+
appears only in the return type, \
1033+
but here is required to be higher-ranked, \
1034+
which means that `{0}` must appear in both \
1035+
argument and return types",
1036+
region_name,
1037+
self.tcx.item_path_str(fn_def_id)));
1038+
}
1039+
}
1040+
}
1041+
}
10201042
}
10211043

10221044
struct RebuildPathInfo<'a> {
@@ -1129,7 +1151,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
11291151
ty::BrAnon(i) => {
11301152
anon_nums.insert(i);
11311153
}
1132-
ty::BrNamed(_, name) => {
1154+
ty::BrNamed(_, name, _) => {
11331155
region_names.insert(name);
11341156
}
11351157
_ => ()
@@ -1143,7 +1165,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
11431165
for sr in self.same_regions {
11441166
for br in &sr.regions {
11451167
match *br {
1146-
ty::BrNamed(_, name) => {
1168+
ty::BrNamed(_, name, _) => {
11471169
all_region_names.insert(name);
11481170
}
11491171
_ => ()
@@ -1923,3 +1945,4 @@ fn name_to_dummy_lifetime(name: ast::Name) -> hir::Lifetime {
19231945
span: codemap::DUMMY_SP,
19241946
name: name }
19251947
}
1948+

0 commit comments

Comments
 (0)