require reimplementations of all items when a defaulted associated type is overriden
This is a [breaking-change] but it follows the RFC (not sure whether it will be accepted).
This commit is contained in:
parent
ace86701a9
commit
6b27005f2f
3 changed files with 68 additions and 12 deletions
|
|
@ -846,6 +846,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
// Locate trait methods
|
||||
let tcx = ccx.tcx;
|
||||
let trait_items = tcx.trait_items(impl_trait_ref.def_id);
|
||||
let mut overridden_associated_type = None;
|
||||
|
||||
// Check existing impl methods to see if they are both present in trait
|
||||
// and compatible with trait signature
|
||||
|
|
@ -911,8 +912,10 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
_ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
|
||||
};
|
||||
|
||||
if let &ty::TypeTraitItem(..) = ty_trait_item {
|
||||
// ...
|
||||
if let &ty::TypeTraitItem(ref at) = ty_trait_item {
|
||||
if let Some(_) = at.ty {
|
||||
overridden_associated_type = Some(impl_item);
|
||||
}
|
||||
} else {
|
||||
span_err!(tcx.sess, impl_item.span, E0325,
|
||||
"item `{}` is an associated type, \
|
||||
|
|
@ -930,6 +933,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
|
||||
let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
|
||||
let mut missing_items = Vec::new();
|
||||
let mut invalidated_items = Vec::new();
|
||||
let associated_type_overridden = overridden_associated_type.is_some();
|
||||
for trait_item in trait_items.iter() {
|
||||
match *trait_item {
|
||||
ty::ConstTraitItem(ref associated_const) => {
|
||||
|
|
@ -944,9 +949,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
let is_provided =
|
||||
associated_consts.iter().any(|ac| ac.default.is_some() &&
|
||||
ac.name == associated_const.name);
|
||||
if !is_implemented && !is_provided {
|
||||
missing_items.push(format!("`{}`",
|
||||
token::get_name(associated_const.name)));
|
||||
if !is_implemented {
|
||||
if !is_provided {
|
||||
missing_items.push(associated_const.name);
|
||||
} else if associated_type_overridden {
|
||||
invalidated_items.push(associated_const.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::MethodTraitItem(ref trait_method) => {
|
||||
|
|
@ -961,8 +969,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
});
|
||||
let is_provided =
|
||||
provided_methods.iter().any(|m| m.name == trait_method.name);
|
||||
if !is_implemented && !is_provided {
|
||||
missing_items.push(format!("`{}`", token::get_name(trait_method.name)));
|
||||
if !is_implemented {
|
||||
if !is_provided {
|
||||
missing_items.push(trait_method.name);
|
||||
} else if associated_type_overridden {
|
||||
invalidated_items.push(trait_method.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::TypeTraitItem(ref associated_type) => {
|
||||
|
|
@ -975,8 +987,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
}
|
||||
});
|
||||
let is_provided = associated_type.ty.is_some();
|
||||
if !is_implemented && !is_provided {
|
||||
missing_items.push(format!("`{}`", token::get_name(associated_type.name)));
|
||||
if !is_implemented {
|
||||
if !is_provided {
|
||||
missing_items.push(associated_type.name);
|
||||
} else if associated_type_overridden {
|
||||
invalidated_items.push(associated_type.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -984,8 +1000,21 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
if !missing_items.is_empty() {
|
||||
span_err!(tcx.sess, impl_span, E0046,
|
||||
"not all trait items implemented, missing: {}",
|
||||
missing_items.connect(", "));
|
||||
"not all trait items implemented, missing: `{}`",
|
||||
missing_items.iter()
|
||||
.map(<ast::Name>::as_str)
|
||||
.collect::<Vec<_>>().connect("`, `"))
|
||||
}
|
||||
|
||||
if !invalidated_items.is_empty() {
|
||||
let invalidator = overridden_associated_type.unwrap();
|
||||
span_err!(tcx.sess, invalidator.span, E0399,
|
||||
"the following trait items need to be reimplemented \
|
||||
as `{}` was overridden: `{}`",
|
||||
invalidator.ident.as_str(),
|
||||
invalidated_items.iter()
|
||||
.map(<ast::Name>::as_str)
|
||||
.collect::<Vec<_>>().connect("`, `"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2066,6 +2066,8 @@ register_diagnostics! {
|
|||
// `#[lang = \"{}\"]` is allowed for the `{}` primitive
|
||||
E0391, // unsupported cyclic reference between types/traits detected
|
||||
E0392, // parameter `{}` is never used
|
||||
E0393 // the type parameter `{}` must be explicitly specified in an object
|
||||
E0393, // the type parameter `{}` must be explicitly specified in an object
|
||||
// type because its default value `{}` references the type `Self`"
|
||||
E0399 // trait items need to be implemented because the associated
|
||||
// type `{}` was overridden
|
||||
}
|
||||
|
|
|
|||
25
src/test/compile-fail/associated-types-overridden-default.rs
Normal file
25
src/test/compile-fail/associated-types-overridden-default.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
#![feature(associated_consts)]
|
||||
|
||||
pub trait Tr {
|
||||
type Assoc = u8;
|
||||
type Assoc2 = Self::Assoc;
|
||||
const C: u8 = 11;
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
impl Tr for () {
|
||||
type Assoc = ();
|
||||
//~^ ERROR need to be reimplemented as `Assoc` was overridden: `Assoc2`, `C`, `foo`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue