提交 9a4e5df1 编写于 作者: B bors

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
......@@ -279,6 +279,12 @@
"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 @@ fn get_lints(&self) -> LintArray {
BARE_TRAIT_OBJECT,
ABSOLUTE_PATH_NOT_STARTING_WITH_CRATE,
UNSTABLE_NAME_COLLISION,
DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
)
}
}
......
......@@ -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
......
......@@ -27,7 +27,7 @@
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 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self,
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 @@ fn ast_type_binding_to_poly_projection_predicate(
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 @@ fn ast_type_binding_to_poly_projection_predicate(
}
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(
......
// 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();
}
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>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册