move duplicate checking into TypeCheck
This completes the effort to not touch the impl-items during `Collect(Impl)`.
This commit is contained in:
parent
29a39ab834
commit
4df5288971
3 changed files with 54 additions and 31 deletions
46
src/librustc_typeck/check/impl_item_duplicate.rs
Normal file
46
src/librustc_typeck/check/impl_item_duplicate.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2012-2014 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.
|
||||
|
||||
use rustc::hir;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
|
||||
use CrateCtxt;
|
||||
|
||||
/// Enforce that we do not have two items in an impl with the same name.
|
||||
pub fn enforce_impl_items_are_distinct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
impl_item_ids: &[hir::ImplItemId])
|
||||
{
|
||||
let tcx = ccx.tcx;
|
||||
let mut seen_type_items = FxHashMap();
|
||||
let mut seen_value_items = FxHashMap();
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = tcx.map.impl_item(impl_item_id);
|
||||
let seen_items = match impl_item.node {
|
||||
hir::ImplItemKind::Type(_) => &mut seen_type_items,
|
||||
_ => &mut seen_value_items,
|
||||
};
|
||||
match seen_items.entry(impl_item.name) {
|
||||
Occupied(entry) => {
|
||||
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
|
||||
"duplicate definitions with name `{}`:",
|
||||
impl_item.name);
|
||||
err.span_label(*entry.get(),
|
||||
&format!("previous definition of `{}` here",
|
||||
impl_item.name));
|
||||
err.span_label(impl_item.span, &format!("duplicate definition"));
|
||||
err.emit();
|
||||
}
|
||||
Vacant(entry) => {
|
||||
entry.insert(impl_item.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -143,6 +143,7 @@ mod closure;
|
|||
mod callee;
|
||||
mod compare_method;
|
||||
mod intrinsic;
|
||||
mod impl_item_duplicate;
|
||||
mod impl_parameters_used;
|
||||
mod op;
|
||||
|
||||
|
|
@ -834,6 +835,8 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
|
|||
impl_def_id,
|
||||
impl_item_ids);
|
||||
|
||||
impl_item_duplicate::enforce_impl_items_are_distinct(ccx,
|
||||
impl_item_ids);
|
||||
}
|
||||
hir::ItemTrait(..) => {
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ use CrateCtxt;
|
|||
use rustc_const_math::ConstInt;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
|
||||
use syntax::{abi, ast, attr};
|
||||
use syntax::parse::token::{self, keywords};
|
||||
|
|
@ -732,7 +731,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
ref generics,
|
||||
ref opt_trait_ref,
|
||||
ref selfty,
|
||||
ref impl_item_ids) => {
|
||||
ref _impl_item_ids /* [1] */) => {
|
||||
// [1]: We really don't want to be inspecting the details
|
||||
// of impl-items here; it creates bad edges in the
|
||||
// incr. comp. graph.
|
||||
|
||||
// Create generics from the generics specified in the impl head.
|
||||
debug!("convert: ast_generics={:?}", generics);
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
|
|
@ -763,35 +766,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
&mut ctp::parameters_for_impl(selfty, trait_ref));
|
||||
|
||||
tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
|
||||
|
||||
|
||||
// Convert all the associated consts.
|
||||
// Also, check if there are any duplicate associated items
|
||||
let mut seen_type_items = FxHashMap();
|
||||
let mut seen_value_items = FxHashMap();
|
||||
|
||||
for &impl_item_id in impl_item_ids {
|
||||
let impl_item = tcx.map.impl_item(impl_item_id);
|
||||
let seen_items = match impl_item.node {
|
||||
hir::ImplItemKind::Type(_) => &mut seen_type_items,
|
||||
_ => &mut seen_value_items,
|
||||
};
|
||||
match seen_items.entry(impl_item.name) {
|
||||
Occupied(entry) => {
|
||||
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
|
||||
"duplicate definitions with name `{}`:",
|
||||
impl_item.name);
|
||||
err.span_label(*entry.get(),
|
||||
&format!("previous definition of `{}` here",
|
||||
impl_item.name));
|
||||
err.span_label(impl_item.span, &format!("duplicate definition"));
|
||||
err.emit();
|
||||
}
|
||||
Vacant(entry) => {
|
||||
entry.insert(impl_item.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hir::ItemTrait(.., ref trait_items) => {
|
||||
let trait_def = trait_def_of_item(ccx, it);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue