@@ -69,7 +69,8 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
69
69
ast:: ItemImpl ( _, _, _, Some ( _) , _, _) => {
70
70
// "Trait" impl
71
71
debug ! ( "coherence2::orphan check: trait impl {}" , item. repr( self . tcx) ) ;
72
- let trait_def_id = ty:: impl_trait_ref ( self . tcx , def_id) . unwrap ( ) . def_id ;
72
+ let trait_ref = ty:: impl_trait_ref ( self . tcx , def_id) . unwrap ( ) ;
73
+ let trait_def_id = trait_ref. def_id ;
73
74
match traits:: orphan_check ( self . tcx , def_id) {
74
75
Ok ( ( ) ) => { }
75
76
Err ( traits:: OrphanCheckErr :: NoLocalInputType ) => {
@@ -92,6 +93,40 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
92
93
}
93
94
}
94
95
}
96
+
97
+ // Impls of a defaulted trait face additional rules.
98
+ debug ! ( "trait_ref={} trait_def_id={} trait_has_default_impl={}" ,
99
+ trait_ref. repr( self . tcx) ,
100
+ trait_def_id. repr( self . tcx) ,
101
+ ty:: trait_has_default_impl( self . tcx, trait_def_id) ) ;
102
+ if
103
+ ty:: trait_has_default_impl ( self . tcx , trait_def_id) &&
104
+ trait_def_id. krate != ast:: LOCAL_CRATE
105
+ {
106
+ let self_ty = trait_ref. self_ty ( ) ;
107
+ match self_ty. sty {
108
+ ty:: ty_struct( self_def_id, _) | ty:: ty_enum( self_def_id, _) => {
109
+ // The orphan check often rules this out,
110
+ // but not always. For example, the orphan
111
+ // check would accept `impl Send for
112
+ // Box<SomethingLocal>`, but we want to
113
+ // forbid that.
114
+ if self_def_id. krate != ast:: LOCAL_CRATE {
115
+ self . tcx . sess . span_err (
116
+ item. span ,
117
+ "cross-crate traits with a default impl \
118
+ can only be implemented for a struct/enum type \
119
+ defined in the current crate") ;
120
+ }
121
+ }
122
+ _ => {
123
+ self . tcx . sess . span_err (
124
+ item. span ,
125
+ "cross-crate traits with a default impl \
126
+ can only be implemented for a struct or enum type") ;
127
+ }
128
+ }
129
+ }
95
130
}
96
131
ast:: ItemDefaultImpl ( ..) => {
97
132
// "Trait" impl
0 commit comments