Skip to content

Commit 17598a4

Browse files
committed
---
yaml --- r: 227559 b: refs/heads/try c: f0f13f8 h: refs/heads/master i: 227557: 8abc57e 227555: 53e6b83 227551: 1475152 v: v3
1 parent a130e91 commit 17598a4

File tree

6 files changed

+80
-24
lines changed

6 files changed

+80
-24
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: ff89fcf83b41c2759d69c01d5e41b9043f5acff8
4+
refs/heads/try: f0f13f86ef434809282bc5eca1bd04a23fdf88d2
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc/middle/traits/mod.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,27 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
414414
debug!("normalize_param_env_or_error(unnormalized_env={})",
415415
unnormalized_env.repr(tcx));
416416

417+
let predicates: Vec<_> =
418+
util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.clone())
419+
.filter(|p| !p.is_global()) // (*)
420+
.collect();
421+
422+
// (*) Any predicate like `i32: Trait<u32>` or whatever doesn't
423+
// need to be in the *environment* to be proven, so screen those
424+
// out. This is important for the soundness of inter-fn
425+
// caching. Note though that we should probably check that these
426+
// predicates hold at the point where the environment is
427+
// constructed, but I am not currently doing so out of laziness.
428+
// -nmatsakis
429+
430+
debug!("normalize_param_env_or_error: elaborated-predicates={}",
431+
predicates.repr(tcx));
432+
433+
let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
434+
417435
let infcx = infer::new_infer_ctxt(tcx);
418-
let predicates = match fully_normalize(&infcx, &unnormalized_env, cause,
419-
&unnormalized_env.caller_bounds) {
436+
let predicates = match fully_normalize(&infcx, &elaborated_env, cause,
437+
&elaborated_env.caller_bounds) {
420438
Ok(predicates) => predicates,
421439
Err(errors) => {
422440
report_fulfillment_errors(&infcx, &errors);
@@ -438,14 +456,11 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
438456
// all things considered.
439457
let err_msg = fixup_err_to_string(fixup_err);
440458
tcx.sess.span_err(span, &err_msg);
441-
return unnormalized_env; // an unnormalized env is better than nothing
459+
return elaborated_env; // an unnormalized env is better than nothing
442460
}
443461
};
444462

445-
debug!("normalize_param_env_or_error: predicates={}",
446-
predicates.repr(tcx));
447-
448-
unnormalized_env.with_caller_bounds(predicates)
463+
elaborated_env.with_caller_bounds(predicates)
449464
}
450465

451466
pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,

branches/try/src/librustc/middle/traits/project.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ fn assemble_candidates_from_param_env<'cx,'tcx>(
531531
obligation_trait_ref: &ty::TraitRef<'tcx>,
532532
candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
533533
{
534-
let env_predicates = selcx.param_env().caller_bounds.clone();
534+
let env_predicates = selcx.param_env().caller_bounds.iter().cloned();
535535
assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
536536
candidate_set, env_predicates);
537537
}
@@ -567,22 +567,25 @@ fn assemble_candidates_from_trait_def<'cx,'tcx>(
567567
// If so, extract what we know from the trait and try to come up with a good answer.
568568
let trait_predicates = ty::lookup_predicates(selcx.tcx(), trait_ref.def_id);
569569
let bounds = trait_predicates.instantiate(selcx.tcx(), trait_ref.substs);
570+
let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates.into_vec());
570571
assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
571-
candidate_set, bounds.predicates.into_vec());
572+
candidate_set, bounds)
572573
}
573574

574-
fn assemble_candidates_from_predicates<'cx,'tcx>(
575+
fn assemble_candidates_from_predicates<'cx,'tcx,I>(
575576
selcx: &mut SelectionContext<'cx,'tcx>,
576577
obligation: &ProjectionTyObligation<'tcx>,
577578
obligation_trait_ref: &ty::TraitRef<'tcx>,
578579
candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
579-
env_predicates: Vec<ty::Predicate<'tcx>>)
580+
env_predicates: I)
581+
where I: Iterator<Item=ty::Predicate<'tcx>>
580582
{
581-
debug!("assemble_candidates_from_predicates(obligation={}, env_predicates={})",
582-
obligation.repr(selcx.tcx()),
583-
env_predicates.repr(selcx.tcx()));
583+
debug!("assemble_candidates_from_predicates(obligation={})",
584+
obligation.repr(selcx.tcx()));
584585
let infcx = selcx.infcx();
585-
for predicate in elaborate_predicates(selcx.tcx(), env_predicates) {
586+
for predicate in env_predicates {
587+
debug!("assemble_candidates_from_predicates: predicate={}",
588+
predicate.repr(selcx.tcx()));
586589
match predicate {
587590
ty::Predicate::Projection(ref data) => {
588591
let same_name = data.item_name() == obligation.predicate.item_name;
@@ -637,6 +640,7 @@ fn assemble_candidates_from_object_type<'cx,'tcx>(
637640
let env_predicates = projection_bounds.iter()
638641
.map(|p| p.as_predicate())
639642
.collect();
643+
let env_predicates = elaborate_predicates(selcx.tcx(), env_predicates);
640644
assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
641645
candidate_set, env_predicates)
642646
}

branches/try/src/librustc/middle/traits/select.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,14 +1083,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10831083
debug!("assemble_candidates_from_caller_bounds({})",
10841084
stack.obligation.repr(self.tcx()));
10851085

1086-
let caller_trait_refs: Vec<_> =
1087-
self.param_env().caller_bounds.iter()
1088-
.filter_map(|o| o.to_opt_poly_trait_ref())
1089-
.collect();
1090-
10911086
let all_bounds =
1092-
util::transitive_bounds(
1093-
self.tcx(), &caller_trait_refs[..]);
1087+
self.param_env().caller_bounds
1088+
.iter()
1089+
.filter_map(|o| o.to_opt_poly_trait_ref());
10941090

10951091
let matching_bounds =
10961092
all_bounds.filter(

branches/try/src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2371,7 +2371,7 @@ pub struct ParameterEnvironment<'a, 'tcx:'a> {
23712371

23722372
/// Obligations that the caller must satisfy. This is basically
23732373
/// the set of bounds on the in-scope type parameters, translated
2374-
/// into Obligations.
2374+
/// into Obligations, and elaborated and normalized.
23752375
pub caller_bounds: Vec<ty::Predicate<'tcx>>,
23762376

23772377
/// Caches the results of trait selection. This cache is used
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Check that when there are vacuous predicates in the environment
12+
// (which make a fn uncallable) we don't erroneously cache those and
13+
// then consider them satisfied elsewhere. The current technique for
14+
// doing this is just to filter "global" predicates out of the
15+
// environment, which means that we wind up with an error in the
16+
// function `vacuous`, because even though `i32: Bar<u32>` is implied
17+
// by its where clause, that where clause never holds.
18+
19+
trait Foo<X,Y>: Bar<X> {
20+
}
21+
22+
trait Bar<X> { }
23+
24+
fn vacuous<A>()
25+
where i32: Foo<u32, A>
26+
{
27+
// vacuous could never be called, because it requires that i32:
28+
// Bar<u32>. But the code doesn't check that this could never be
29+
// satisfied.
30+
require::<i32, u32>();
31+
//~^ ERROR the trait `Bar<u32>` is not implemented for the type `i32`
32+
}
33+
34+
fn require<A,B>()
35+
where A: Bar<B>
36+
{
37+
}
38+
39+
fn main() {
40+
require::<i32, u32>();
41+
}

0 commit comments

Comments
 (0)