Skip to content

Commit 3892dd1

Browse files
committed
rollup merge of #20593: nikomatsakis/unused-tps-in-impl
Conflicts: src/libcollections/lib.rs src/librustc/lib.rs src/libserialize/lib.rs src/libstd/lib.rs
2 parents e3f047c + d31105e commit 3892dd1

File tree

22 files changed

+283
-24
lines changed

22 files changed

+283
-24
lines changed

src/libcollections/btree/node.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ pub type MutTraversal<'a, K, V> = AbsTraversal<ElemsAndEdges<Zip<slice::Iter<'a,
14171417
/// An owning traversal over a node's entries and edges
14181418
pub type MoveTraversal<K, V> = AbsTraversal<MoveTraversalImpl<K, V>>;
14191419

1420-
1420+
#[old_impl_check]
14211421
impl<K, V, E, Impl: TraversalImpl<K, V, E>> Iterator for AbsTraversal<Impl> {
14221422
type Item = TraversalItem<K, V, E>;
14231423

@@ -1433,6 +1433,7 @@ impl<K, V, E, Impl: TraversalImpl<K, V, E>> Iterator for AbsTraversal<Impl> {
14331433
}
14341434
}
14351435

1436+
#[old_impl_check]
14361437
impl<K, V, E, Impl: TraversalImpl<K, V, E>> DoubleEndedIterator for AbsTraversal<Impl> {
14371438
fn next_back(&mut self) -> Option<TraversalItem<K, V, E>> {
14381439
let tail_is_edge = self.tail_is_edge;

src/libcollections/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
html_playground_url = "http://play.rust-lang.org/")]
2323

2424
#![feature(unsafe_destructor, slicing_syntax)]
25+
#![feature(old_impl_check)]
2526
#![no_std]
2627

2728
#[macro_use]

src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(quote)]
2626
#![feature(slicing_syntax, unsafe_destructor)]
2727
#![feature(rustc_diagnostic_macros)]
28+
#![feature(old_impl_check)]
2829

2930
extern crate arena;
3031
extern crate flate;

src/librustc/lint/builtin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ impl LintPass for UnusedAttributes {
669669

670670
// FIXME: #19470 this shouldn't be needed forever
671671
"old_orphan_check",
672+
"old_impl_check",
672673
];
673674

674675
static CRATE_ATTRS: &'static [&'static str] = &[

src/librustc/util/ppaux.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,7 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
13501350
}
13511351
}
13521352

1353+
#[old_impl_check]
13531354
impl<'tcx, S, H, K, V> Repr<'tcx> for HashMap<K,V,H>
13541355
where K : Hash<S> + Eq + Repr<'tcx>,
13551356
V : Repr<'tcx>,

src/librustc_typeck/collect.rs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use middle::lang_items::SizedTraitLangItem;
3535
use middle::region;
3636
use middle::resolve_lifetime;
3737
use middle::subst;
38-
use middle::subst::{Substs};
38+
use middle::subst::{Substs, TypeSpace};
3939
use middle::ty::{AsPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
4040
use middle::ty::{self, RegionEscape, Ty, TypeScheme};
4141
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
@@ -47,6 +47,7 @@ use util::ppaux;
4747
use util::ppaux::{Repr,UserString};
4848
use write_ty_to_tcx;
4949

50+
use std::collections::HashSet;
5051
use std::rc::Rc;
5152

5253
use syntax::abi;
@@ -644,6 +645,10 @@ fn convert(ccx: &CollectCtxt, it: &ast::Item) {
644645
Some(selfty),
645646
None);
646647
}
648+
649+
enforce_impl_ty_params_are_constrained(ccx.tcx,
650+
generics,
651+
local_def(it.id));
647652
},
648653
ast::ItemTrait(_, _, _, ref trait_methods) => {
649654
let trait_def = trait_def_of_item(ccx, it);
@@ -1605,3 +1610,96 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
16051610
})
16061611
}
16071612
}
1613+
1614+
/// Checks that all the type parameters on an impl
1615+
fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
1616+
ast_generics: &ast::Generics,
1617+
impl_def_id: ast::DefId)
1618+
{
1619+
let impl_scheme = ty::lookup_item_type(tcx, impl_def_id);
1620+
let impl_trait_ref = ty::impl_trait_ref(tcx, impl_def_id);
1621+
1622+
// The trait reference is an input, so find all type parameters
1623+
// reachable from there, to start (if this is an inherent impl,
1624+
// then just examine the self type).
1625+
let mut input_parameters: HashSet<_> =
1626+
impl_trait_ref.iter()
1627+
.flat_map(|t| t.input_types().iter()) // Types in trait ref, if any
1628+
.chain(Some(impl_scheme.ty).iter()) // Self type, always
1629+
.flat_map(|t| t.walk())
1630+
.filter_map(to_opt_param_ty)
1631+
.collect();
1632+
1633+
loop {
1634+
let num_inputs = input_parameters.len();
1635+
1636+
let mut projection_predicates =
1637+
impl_scheme.generics.predicates
1638+
.iter()
1639+
.filter_map(|predicate| {
1640+
match *predicate {
1641+
// Ignore higher-ranked binders. For the purposes
1642+
// of this check, they don't matter because they
1643+
// only affect named regions, and we're just
1644+
// concerned about type parameters here.
1645+
ty::Predicate::Projection(ref data) => Some(data.0.clone()),
1646+
_ => None,
1647+
}
1648+
});
1649+
1650+
for projection in projection_predicates {
1651+
// Special case: watch out for some kind of sneaky attempt
1652+
// to project out an associated type defined by this very trait.
1653+
if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
1654+
continue;
1655+
}
1656+
1657+
let relies_only_on_inputs =
1658+
projection.projection_ty.trait_ref.input_types().iter()
1659+
.flat_map(|t| t.walk())
1660+
.filter_map(to_opt_param_ty)
1661+
.all(|t| input_parameters.contains(&t));
1662+
1663+
if relies_only_on_inputs {
1664+
input_parameters.extend(
1665+
projection.ty.walk().filter_map(to_opt_param_ty));
1666+
}
1667+
}
1668+
1669+
if input_parameters.len() == num_inputs {
1670+
break;
1671+
}
1672+
}
1673+
1674+
for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
1675+
let param_ty = ty::ParamTy { space: TypeSpace,
1676+
idx: index as u32,
1677+
name: ty_param.ident.name };
1678+
if !input_parameters.contains(&param_ty) {
1679+
if ty::has_attr(tcx, impl_def_id, "old_impl_check") {
1680+
tcx.sess.span_warn(
1681+
ty_param.span,
1682+
format!("the type parameter `{}` is not constrained by the \
1683+
impl trait, self type, or predicates",
1684+
param_ty.user_string(tcx)).as_slice());
1685+
} else {
1686+
tcx.sess.span_err(
1687+
ty_param.span,
1688+
format!("the type parameter `{}` is not constrained by the \
1689+
impl trait, self type, or predicates",
1690+
param_ty.user_string(tcx)).as_slice());
1691+
tcx.sess.span_help(
1692+
ty_param.span,
1693+
format!("you can temporarily opt out of this rule by placing \
1694+
the `#[old_impl_check]` attribute on the impl").as_slice());
1695+
}
1696+
}
1697+
}
1698+
1699+
fn to_opt_param_ty<'tcx>(ty: Ty<'tcx>) -> Option<ty::ParamTy> {
1700+
match ty.sty {
1701+
ty::ty_param(ref d) => Some(d.clone()),
1702+
_ => None,
1703+
}
1704+
}
1705+
}

src/libserialize/collection_impls.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ impl<
156156
}
157157
}
158158

159+
#[old_impl_check]
159160
impl<
160161
K: Encodable + Hash<X> + Eq,
161162
V: Encodable,
@@ -175,6 +176,7 @@ impl<
175176
}
176177
}
177178

179+
#[old_impl_check]
178180
impl<
179181
K: Decodable + Hash<S> + Eq,
180182
V: Decodable,
@@ -195,6 +197,7 @@ impl<
195197
}
196198
}
197199

200+
#[old_impl_check]
198201
impl<
199202
T: Encodable + Hash<X> + Eq,
200203
X,
@@ -212,6 +215,7 @@ impl<
212215
}
213216
}
214217

218+
#[old_impl_check]
215219
impl<
216220
T: Decodable + Hash<S> + Eq,
217221
S,

src/libserialize/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Core encoding and decoding interfaces.
2424
html_playground_url = "http://play.rust-lang.org/")]
2525
#![allow(unknown_features)]
2626
#![feature(slicing_syntax)]
27+
#![feature(old_impl_check)]
2728

2829
// test harness access
2930
#[cfg(test)] extern crate test;

src/libstd/collections/hash/map.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ impl<K, V, M> SearchResult<K, V, M> {
439439
}
440440
}
441441

442+
#[old_impl_check]
442443
impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
443444
fn make_hash<X: ?Sized + Hash<S>>(&self, x: &X) -> SafeHash {
444445
table::make_hash(&self.hasher, x)
@@ -517,6 +518,7 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> {
517518
}
518519
}
519520

521+
#[old_impl_check]
520522
impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
521523
/// Creates an empty hashmap which will use the given hasher to hash keys.
522524
///
@@ -1188,6 +1190,7 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHas
11881190
}
11891191

11901192
#[stable]
1193+
#[old_impl_check]
11911194
impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
11921195
fn eq(&self, other: &HashMap<K, V, H>) -> bool {
11931196
if self.len() != other.len() { return false; }
@@ -1199,9 +1202,11 @@ impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V,
11991202
}
12001203

12011204
#[stable]
1205+
#[old_impl_check]
12021206
impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {}
12031207

12041208
#[stable]
1209+
#[old_impl_check]
12051210
impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
12061211
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
12071212
try!(write!(f, "HashMap {{"));
@@ -1216,6 +1221,7 @@ impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H>
12161221
}
12171222

12181223
#[stable]
1224+
#[old_impl_check]
12191225
impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
12201226
#[stable]
12211227
fn default() -> HashMap<K, V, H> {
@@ -1224,6 +1230,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H>
12241230
}
12251231

12261232
#[stable]
1233+
#[old_impl_check]
12271234
impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V, H>
12281235
where Q: BorrowFrom<K> + Hash<S> + Eq
12291236
{
@@ -1236,6 +1243,7 @@ impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V,
12361243
}
12371244

12381245
#[stable]
1246+
#[old_impl_check]
12391247
impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> IndexMut<Q> for HashMap<K, V, H>
12401248
where Q: BorrowFrom<K> + Hash<S> + Eq
12411249
{
@@ -1465,6 +1473,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
14651473
}
14661474

14671475
#[stable]
1476+
#[old_impl_check]
14681477
impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
14691478
fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, H> {
14701479
let lower = iter.size_hint().0;
@@ -1475,6 +1484,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for Has
14751484
}
14761485

14771486
#[stable]
1487+
#[old_impl_check]
14781488
impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Extend<(K, V)> for HashMap<K, V, H> {
14791489
fn extend<T: Iterator<Item=(K, V)>>(&mut self, mut iter: T) {
14801490
for (k, v) in iter {

0 commit comments

Comments
 (0)