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 or the MIT license +// , 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 + '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 + 'a> +} + +impl<'a> Publisher<'a> for MyStruct<'a> { + type Output = u64; + fn subscribe(&mut self, t : Box + 'a>) { + self.sub = t; + } +} + +fn main() {}