diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-01-13 14:49:10 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-01-14 16:35:14 -0500 |
| commit | ff6085f401844bc5cb07b804f0d2258bb5c2b9a8 (patch) | |
| tree | 0c54a885929a34ca75f9b44bab6dfa1c2b3e9249 | |
| parent | b92ec6a78a980b567ec8e6c034e3b37caea81aaa (diff) | |
| download | rust-ff6085f401844bc5cb07b804f0d2258bb5c2b9a8.tar.gz rust-ff6085f401844bc5cb07b804f0d2258bb5c2b9a8.zip | |
Fix propagation of the HAS_PROJECTION flag in object types. Fixes #20831 some more.
| -rw-r--r-- | src/librustc/middle/ty.rs | 16 | ||||
| -rw-r--r-- | src/test/run-pass/associated-types-projection-in-object-type.rs | 43 |
2 files changed, 58 insertions, 1 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index cf30969ebef..fb216a5e99d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2604,12 +2604,17 @@ impl FlagComputation { &ty_projection(ref data) => { self.add_flags(HAS_PROJECTION); - self.add_substs(data.trait_ref.substs); + self.add_projection_ty(data); } &ty_trait(box TyTrait { ref principal, ref bounds }) => { let mut computation = FlagComputation::new(); computation.add_substs(principal.0.substs); + for projection_bound in bounds.projection_bounds.iter() { + let mut proj_computation = FlagComputation::new(); + proj_computation.add_projection_predicate(&projection_bound.0); + computation.add_bound_computation(&proj_computation); + } self.add_bound_computation(&computation); self.add_bounds(bounds); @@ -2673,6 +2678,15 @@ impl FlagComputation { } } + fn add_projection_predicate(&mut self, projection_predicate: &ProjectionPredicate) { + self.add_projection_ty(&projection_predicate.projection_ty); + self.add_ty(projection_predicate.ty); + } + + fn add_projection_ty(&mut self, projection_ty: &ProjectionTy) { + self.add_substs(projection_ty.trait_ref.substs); + } + fn add_substs(&mut self, substs: &Substs) { self.add_tys(substs.types.as_slice()); match substs.regions { diff --git a/src/test/run-pass/associated-types-projection-in-object-type.rs b/src/test/run-pass/associated-types-projection-in-object-type.rs new file mode 100644 index 00000000000..44dd49b7297 --- /dev/null +++ b/src/test/run-pass/associated-types-projection-in-object-type.rs @@ -0,0 +1,43 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Corrected regression test for #20831. The original did not compile. +// When fixed, it revealed another problem concerning projections that +// appear in associated type bindings in object types, which were not +// being properly flagged. + +use std::ops::{Shl, Shr}; +use std::cell::RefCell; + +pub trait Subscriber { + type Input; +} + +pub trait Publisher<'a> { + type Output; + fn subscribe(&mut self, Box<Subscriber<Input=Self::Output> + 'a>); +} + +pub trait Processor<'a> : Subscriber + Publisher<'a> { } + +impl<'a, P> Processor<'a> for P where P : Subscriber + Publisher<'a> { } + +struct MyStruct<'a> { + sub: Box<Subscriber<Input=u64> + 'a> +} + +impl<'a> Publisher<'a> for MyStruct<'a> { + type Output = u64; + fn subscribe(&mut self, t : Box<Subscriber<Input=u64> + 'a>) { + self.sub = t; + } +} + +fn main() {} |
