1 // Copyright 2015 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.
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.
11 use middle::ty::{self};
13 use std::collections::HashSet;
16 pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>,
17 predicates: &[ty::Predicate<'tcx>],
18 impl_trait_ref: Option<Rc<ty::TraitRef<'tcx>>>,
19 input_parameters: &mut HashSet<ty::ParamTy>)
22 let num_inputs = input_parameters.len();
24 let projection_predicates =
26 .filter_map(|predicate| {
28 // Ignore higher-ranked binders. For the purposes
29 // of this check, they don't matter because they
30 // only affect named regions, and we're just
31 // concerned about type parameters here.
32 ty::Predicate::Projection(ref data) => Some(data.0.clone()),
37 for projection in projection_predicates {
38 // Special case: watch out for some kind of sneaky attempt
39 // to project out an associated type defined by this very trait.
40 if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
44 let relies_only_on_inputs =
45 projection.projection_ty.trait_ref.input_types()
47 .flat_map(|t| t.walk())
48 .filter_map(|t| t.as_opt_param_ty())
49 .all(|t| input_parameters.contains(&t));
51 if relies_only_on_inputs {
52 input_parameters.extend(
53 projection.ty.walk().filter_map(|t| t.as_opt_param_ty()));
57 if input_parameters.len() == num_inputs {