diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-12-31 13:49:49 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-12-31 14:41:39 -0500 |
| commit | 67dab2af81ba64023c526dc96315863a9f7e9e40 (patch) | |
| tree | 1bce99583f93b23643c13a6f84f5010ef3708619 | |
| parent | 9675488ef9480365c2d26e23bfd649128037880f (diff) | |
| download | rust-67dab2af81ba64023c526dc96315863a9f7e9e40.tar.gz rust-67dab2af81ba64023c526dc96315863a9f7e9e40.zip | |
Include projection bounds in superpredicates.
Fixes #19451. Fixes #20345.
| -rw-r--r-- | src/librustc/middle/ty.rs | 17 | ||||
| -rw-r--r-- | src/test/run-pass/associated-types-projection-bound-in-supertraits.rs | 33 |
2 files changed, 43 insertions, 7 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 351485d74e8..dab24f6a163 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -5449,8 +5449,15 @@ pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>, .map(|poly_trait_ref| ty::Binder(poly_trait_ref.0.subst(tcx, trait_ref.substs()))) .collect(); - debug!("bounds_for_trait_ref: trait_bounds={}", - trait_bounds.repr(tcx)); + let projection_bounds: Vec<_> = + trait_def.bounds.projection_bounds + .iter() + .map(|poly_proj| ty::Binder(poly_proj.0.subst(tcx, trait_ref.substs()))) + .collect(); + + debug!("bounds_for_trait_ref: trait_bounds={} projection_bounds={}", + trait_bounds.repr(tcx), + projection_bounds.repr(tcx)); // The region bounds and builtin bounds do not currently introduce // binders so we can just substitute in a straightforward way here. @@ -5463,11 +5470,7 @@ pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>, trait_bounds: trait_bounds, region_bounds: region_bounds, builtin_bounds: builtin_bounds, - - // FIXME(#19451) -- if a trait has a bound like `trait Foo : - // Bar<T=X>`, we should probably be returning that, but this - // code here will just ignore it. - projection_bounds: Vec::new(), + projection_bounds: projection_bounds, }; predicates(tcx, trait_ref.self_ty(), &bounds) diff --git a/src/test/run-pass/associated-types-projection-bound-in-supertraits.rs b/src/test/run-pass/associated-types-projection-bound-in-supertraits.rs new file mode 100644 index 00000000000..c7ffb56cc83 --- /dev/null +++ b/src/test/run-pass/associated-types-projection-bound-in-supertraits.rs @@ -0,0 +1,33 @@ +// Copyright 2014 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. + +// Test that we correctly handle projection bounds appearing in the +// supertrait list (and in conjunction with overloaded operators). In +// this case, the `Result=Self` binding in the supertrait listing of +// `Int` was being ignored. + +#![feature(associated_types)] + +trait Not { + type Result; + + fn not(self) -> Self::Result; +} + +trait Int: Not<Result=Self> { + fn count_ones(self) -> uint; + fn count_zeros(self) -> uint { + // neither works + let x: Self = self.not(); + 0 + } +} + +fn main() { } |
