Add stricter orphan rules for cross-crate impls of default traits.
This commit is contained in:
parent
dbec033e29
commit
2e216896e4
3 changed files with 87 additions and 1 deletions
|
@ -69,7 +69,8 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
|
|||
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;
|
||||
let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap();
|
||||
let trait_def_id = trait_ref.def_id;
|
||||
match traits::orphan_check(self.tcx, def_id) {
|
||||
Ok(()) => { }
|
||||
Err(traits::OrphanCheckErr::NoLocalInputType) => {
|
||||
|
@ -92,6 +93,40 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Impls of a defaulted trait face additional rules.
|
||||
debug!("trait_ref={} trait_def_id={} trait_has_default_impl={}",
|
||||
trait_ref.repr(self.tcx),
|
||||
trait_def_id.repr(self.tcx),
|
||||
ty::trait_has_default_impl(self.tcx, trait_def_id));
|
||||
if
|
||||
ty::trait_has_default_impl(self.tcx, trait_def_id) &&
|
||||
trait_def_id.krate != ast::LOCAL_CRATE
|
||||
{
|
||||
let self_ty = trait_ref.self_ty();
|
||||
match self_ty.sty {
|
||||
ty::ty_struct(self_def_id, _) | ty::ty_enum(self_def_id, _) => {
|
||||
// The orphan check often rules this out,
|
||||
// but not always. For example, the orphan
|
||||
// check would accept `impl Send for
|
||||
// Box<SomethingLocal>`, but we want to
|
||||
// forbid that.
|
||||
if self_def_id.krate != ast::LOCAL_CRATE {
|
||||
self.tcx.sess.span_err(
|
||||
item.span,
|
||||
"cross-crate traits with a default impl \
|
||||
can only be implemented for a struct/enum type \
|
||||
defined in the current crate");
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.tcx.sess.span_err(
|
||||
item.span,
|
||||
"cross-crate traits with a default impl \
|
||||
can only be implemented for a struct or enum type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ItemDefaultImpl(..) => {
|
||||
// "Trait" impl
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// 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(optin_builtin_traits)]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
use std::marker::MarkerTrait;
|
||||
|
||||
pub trait DefaultedTrait : MarkerTrait { }
|
||||
impl DefaultedTrait for .. { }
|
|
@ -0,0 +1,34 @@
|
|||
// 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.
|
||||
|
||||
// aux-build:typeck-default-trait-impl-cross-crate-coherence-lib.rs
|
||||
|
||||
// Test that we do not consider associated types to be sendable without
|
||||
// some applicable trait bound (and we don't ICE).
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
extern crate "typeck-default-trait-impl-cross-crate-coherence-lib" as lib;
|
||||
|
||||
use lib::DefaultedTrait;
|
||||
|
||||
struct A;
|
||||
impl DefaultedTrait for (A,) { }
|
||||
//~^ ERROR can only be implemented for a struct or enum type
|
||||
|
||||
struct B;
|
||||
impl !DefaultedTrait for (B,) { }
|
||||
//~^ ERROR can only be implemented for a struct or enum type
|
||||
|
||||
struct C;
|
||||
impl DefaultedTrait for Box<C> { }
|
||||
//~^ ERROR can only be implemented for a struct or enum type
|
||||
|
||||
fn main() { }
|
Loading…
Reference in a new issue