diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-02-05 11:48:20 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-02-05 11:48:44 -0500 |
| commit | be8d9bb98a140d4a4df762e2ea44109c2f05ce6c (patch) | |
| tree | 70be870211e0508b8b418a5b571c64d7968f444a /src | |
| parent | 2bd8ec2d197809fc0f0efccf1de14419ffb17b2b (diff) | |
| download | rust-be8d9bb98a140d4a4df762e2ea44109c2f05ce6c.tar.gz rust-be8d9bb98a140d4a4df762e2ea44109c2f05ce6c.zip | |
When elaborating predicates, purge duplicates from the initial vector.
Fixes #21965.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/traits/util.rs | 13 | ||||
| -rw-r--r-- | src/test/run-pass/associated-types-duplicate-binding-in-env.rs | 27 |
2 files changed, 32 insertions, 8 deletions
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 45ce692bb07..6cbac7d01e7 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -11,12 +11,12 @@ use middle::subst::{Substs, VecPerParamSpace}; use middle::infer::InferCtxt; use middle::ty::{self, Ty, AsPredicate, ToPolyTraitRef}; -use std::collections::HashSet; use std::fmt; use std::rc::Rc; use syntax::ast; use syntax::codemap::Span; use util::common::ErrorReported; +use util::nodemap::FnvHashSet; use util::ppaux::Repr; use super::{Obligation, ObligationCause, PredicateObligation, @@ -36,7 +36,7 @@ use super::{Obligation, ObligationCause, PredicateObligation, pub struct Elaborator<'cx, 'tcx:'cx> { tcx: &'cx ty::ctxt<'tcx>, stack: Vec<StackEntry<'tcx>>, - visited: HashSet<ty::Predicate<'tcx>>, + visited: FnvHashSet<ty::Predicate<'tcx>>, } struct StackEntry<'tcx> { @@ -65,14 +65,11 @@ pub fn elaborate_trait_refs<'cx, 'tcx>( pub fn elaborate_predicates<'cx, 'tcx>( tcx: &'cx ty::ctxt<'tcx>, - predicates: Vec<ty::Predicate<'tcx>>) + mut predicates: Vec<ty::Predicate<'tcx>>) -> Elaborator<'cx, 'tcx> { - let visited: HashSet<ty::Predicate<'tcx>> = - predicates.iter() - .map(|b| (*b).clone()) - .collect(); - + let mut visited = FnvHashSet(); + predicates.retain(|pred| visited.insert(pred.clone())); let entry = StackEntry { position: 0, predicates: predicates }; Elaborator { tcx: tcx, stack: vec![entry], visited: visited } } diff --git a/src/test/run-pass/associated-types-duplicate-binding-in-env.rs b/src/test/run-pass/associated-types-duplicate-binding-in-env.rs new file mode 100644 index 00000000000..62ac2187952 --- /dev/null +++ b/src/test/run-pass/associated-types-duplicate-binding-in-env.rs @@ -0,0 +1,27 @@ +// 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. + +// Check that we do not report ambiguities when the same predicate +// appears in the environment twice. Issue #21965. + +trait Foo { + type B; + + fn get() -> Self::B; +} + +fn foo<T>() -> () + where T : Foo<B=()>, T : Foo<B=()> +{ + <T as Foo>::get() +} + +fn main() { +} |
