ast::ItemImpl(_, _, _, Some(_), _, _) => {
// "Trait" impl
debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
+ 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) => {
- span_err!(self.tcx.sess, item.span, E0117,
- "cannot provide an extension implementation \
- where both trait and type are not defined in this crate");
+ 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::UncoveredTypeParameter(param_ty)) => {
- if !self.tcx.sess.features.borrow().old_orphan_check {
+ 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 `{}` must also appear as a type parameter \
- of some type defined within this crate",
- param_ty.user_string(self.tcx)).as_slice());
+ 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 \