diff options
| author | bors <bors@rust-lang.org> | 2018-05-23 05:09:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-05-23 05:09:13 +0000 |
| commit | 9a4e5df12685e58ad42ce0152cdbe266373c6bf3 (patch) | |
| tree | 9a444841d99befe893ba2801037b11d949f0497e /src | |
| parent | 5ec4ab9b6820c5f0937bf29c09637648fcb547a3 (diff) | |
| parent | 88f810f52e628795875260a31d479af4f28a5edb (diff) | |
| download | rust-9a4e5df12685e58ad42ce0152cdbe266373c6bf3.tar.gz rust-9a4e5df12685e58ad42ce0152cdbe266373c6bf3.zip | |
Auto merge of #50682 - F001:issue-50589, r=petrochenkov
Add lint for multiple associated types Fix https://github.com/rust-lang/rust/issues/50589. cc @abonander
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/lint/builtin.rs | 7 | ||||
| -rw-r--r-- | src/librustc_lint/lib.rs | 5 | ||||
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 27 | ||||
| -rw-r--r-- | src/test/ui/lint/issue-50589-multiple-associated-types.rs | 23 | ||||
| -rw-r--r-- | src/test/ui/lint/issue-50589-multiple-associated-types.stderr | 23 |
5 files changed, 81 insertions, 4 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index ac2fa8515bc..5d7d2f0f9e6 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -279,6 +279,12 @@ declare_lint! { "detects labels that are never used" } +declare_lint! { + pub DUPLICATE_ASSOCIATED_TYPE_BINDINGS, + Warn, + "warns about duplicate associated type bindings in generics" +} + /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -330,6 +336,7 @@ impl LintPass for HardwiredLints { BARE_TRAIT_OBJECT, ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE, UNSTABLE_NAME_COLLISION, + DUPLICATE_ASSOCIATED_TYPE_BINDINGS, ) } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index cfd5cf5a0f9..e35537459b7 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -283,6 +283,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue TBD", edition: Some(Edition::Edition2018), }, + FutureIncompatibleInfo { + id: LintId::of(DUPLICATE_ASSOCIATED_TYPE_BINDINGS), + reference: "issue #50589 <https://github.com/rust-lang/rust/issues/50589>", + edition: None, + }, ]); // Register renamed and removed lints diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f2fe8b1d891..68587fb8b3c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -27,7 +27,7 @@ use rustc_target::spec::abi; use std::slice; use require_c_abi_if_variadic; use util::common::ErrorReported; -use util::nodemap::FxHashSet; +use util::nodemap::{FxHashSet, FxHashMap}; use errors::FatalError; use std::iter; @@ -398,11 +398,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { trait_ref.path.segments.last().unwrap()); let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); + let mut dup_bindings = FxHashMap::default(); poly_projections.extend(assoc_bindings.iter().filter_map(|binding| { // specify type to assert that error was already reported in Err case: let predicate: Result<_, ErrorReported> = - self.ast_type_binding_to_poly_projection_predicate(trait_ref.ref_id, poly_trait_ref, - binding, speculative); + self.ast_type_binding_to_poly_projection_predicate( + trait_ref.ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings); predicate.ok() // ok to ignore Err() because ErrorReported (see above) })); @@ -487,7 +488,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { ref_id: ast::NodeId, trait_ref: ty::PolyTraitRef<'tcx>, binding: &ConvertedBinding<'tcx>, - speculative: bool) + speculative: bool, + dup_bindings: &mut FxHashMap<DefId, Span>) -> Result<ty::PolyProjectionPredicate<'tcx>, ErrorReported> { let tcx = self.tcx(); @@ -566,6 +568,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } tcx.check_stability(assoc_ty.def_id, Some(ref_id), binding.span); + if !speculative { + dup_bindings.entry(assoc_ty.def_id) + .and_modify(|prev_span| { + let mut err = self.tcx().struct_span_lint_node( + ::rustc::lint::builtin::DUPLICATE_ASSOCIATED_TYPE_BINDINGS, + ref_id, + binding.span, + &format!("associated type binding `{}` specified more than once", + binding.item_name) + ); + err.span_label(binding.span, "used more than once"); + err.span_label(*prev_span, format!("first use of `{}`", binding.item_name)); + err.emit(); + }) + .or_insert(binding.span); + } + Ok(candidate.map_bound(|trait_ref| { ty::ProjectionPredicate { projection_ty: ty::ProjectionTy::from_ref_and_name( diff --git a/src/test/ui/lint/issue-50589-multiple-associated-types.rs b/src/test/ui/lint/issue-50589-multiple-associated-types.rs new file mode 100644 index 00000000000..2c789a139cd --- /dev/null +++ b/src/test/ui/lint/issue-50589-multiple-associated-types.rs @@ -0,0 +1,23 @@ +// Copyright 2018 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. + +// compile-pass + +use std::iter::Iterator; + +type Unit = (); + +fn test() -> Box<Iterator<Item = (), Item = Unit>> { + Box::new(None.into_iter()) +} + +fn main() { + test(); +} diff --git a/src/test/ui/lint/issue-50589-multiple-associated-types.stderr b/src/test/ui/lint/issue-50589-multiple-associated-types.stderr new file mode 100644 index 00000000000..7f0a1ee1f33 --- /dev/null +++ b/src/test/ui/lint/issue-50589-multiple-associated-types.stderr @@ -0,0 +1,23 @@ +warning: associated type binding `Item` specified more than once + --> $DIR/issue-50589-multiple-associated-types.rs:17:39 + | +LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> { + | --------- ^^^^^^^^^^^ used more than once + | | + | first use of `Item` + | + = note: #[warn(duplicate_associated_type_bindings)] on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589> + +warning: associated type binding `Item` specified more than once + --> $DIR/issue-50589-multiple-associated-types.rs:17:39 + | +LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> { + | --------- ^^^^^^^^^^^ used more than once + | | + | first use of `Item` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589> + |
