use syntax::ast_util;
use syntax::codemap::Span;
use syntax::visit;
-use util::ppaux::Repr;
+use util::ppaux::{Repr, UserString};
pub fn check(tcx: &ty::ctxt) {
let mut orphan = OrphanChecker { tcx: tcx };
fn visit_item(&mut self, item: &'v ast::Item) {
let def_id = ast_util::local_def(item.id);
match item.node {
- ast::ItemImpl(_, _, None, _, _) => {
+ ast::ItemImpl(_, _, _, None, _, _) => {
// For inherent impls, self type must be a nominal type
// defined in this crate.
debug!("coherence2::orphan check: inherent impl {}", item.repr(self.tcx));
ty::ty_struct(def_id, _) => {
self.check_def_id(item.span, def_id);
}
- ty::ty_trait(box ty::TyTrait{ ref principal, ..}) => {
- self.check_def_id(item.span, principal.def_id());
+ ty::ty_trait(ref data) => {
+ self.check_def_id(item.span, data.principal_def_id());
+ }
+ ty::ty_uniq(..) => {
+ self.check_def_id(item.span,
+ self.tcx.lang_items.owned_box()
+ .unwrap());
}
_ => {
span_err!(self.tcx.sess, item.span, E0118,
}
}
}
- ast::ItemImpl(_, _, Some(_), _, _) => {
+ ast::ItemImpl(_, _, _, Some(_), _, _) => {
// "Trait" impl
debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
- if traits::is_orphan_impl(self.tcx, def_id) {
- span_err!(self.tcx.sess, item.span, E0117,
- "cannot provide an extension implementation \
- where both trait and type are not defined in this crate");
+ let trait_def_id = ty::impl_trait_ref(self.tcx, def_id).unwrap().def_id;
+ match traits::orphan_check(self.tcx, def_id) {
+ Ok(()) => { }
+ Err(traits::OrphanCheckErr::NoLocalInputType) => {
+ if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
+ let self_ty = ty::lookup_item_type(self.tcx, def_id).ty;
+ span_err!(
+ self.tcx.sess, item.span, E0117,
+ "the type `{}` does not reference any \
+ types defined in this crate; \
+ only traits defined in the current crate can be \
+ implemented for arbitrary types",
+ self_ty.user_string(self.tcx));
+ }
+ }
+ Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
+ if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
+ self.tcx.sess.span_err(
+ item.span,
+ format!(
+ "type parameter `{}` is not constrained by any local type; \
+ only traits defined in the current crate can be implemented \
+ for a type parameter",
+ param_ty.user_string(self.tcx)).as_slice());
+ self.tcx.sess.span_note(
+ item.span,
+ format!("for a limited time, you can add \
+ `#![feature(old_orphan_check)]` to your crate \
+ to disable this rule").as_slice());
+ }
+ }
}
}
_ => {