@@ -703,13 +703,42 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
703
703
}
704
704
}
705
705
ty:: Error ( _) => ControlFlow :: Break ( OrphanCheckEarlyExit :: LocalTy ( ty) ) ,
706
- ty:: Opaque ( .. ) | ty :: Closure ( ..) | ty:: Generator ( ..) | ty:: GeneratorWitness ( ..) => {
706
+ ty:: Closure ( ..) | ty:: Generator ( ..) | ty:: GeneratorWitness ( ..) => {
707
707
self . tcx . sess . delay_span_bug (
708
708
DUMMY_SP ,
709
709
format ! ( "ty_is_local invoked on closure or generator: {:?}" , ty) ,
710
710
) ;
711
711
ControlFlow :: Break ( OrphanCheckEarlyExit :: LocalTy ( ty) )
712
712
}
713
+ ty:: Opaque ( ..) => {
714
+ // This merits some explanation.
715
+ // Normally, opaque types are not involved when performing
716
+ // coherence checking, since it is illegal to directly
717
+ // implement a trait on an opaque type. However, we might
718
+ // end up looking at an opaque type during coherence checking
719
+ // if an opaque type gets used within another type (e.g. as
720
+ // the type of a field) when checking for auto trait or `Sized`
721
+ // impls. This requires us to decide whether or not an opaque
722
+ // type should be considered 'local' or not.
723
+ //
724
+ // We choose to treat all opaque types as non-local, even
725
+ // those that appear within the same crate. This seems
726
+ // somewhat surprising at first, but makes sense when
727
+ // you consider that opaque types are supposed to hide
728
+ // the underlying type *within the same crate*. When an
729
+ // opaque type is used from outside the module
730
+ // where it is declared, it should be impossible to observe
731
+ // anything about it other than the traits that it implements.
732
+ //
733
+ // The alternative would be to look at the underlying type
734
+ // to determine whether or not the opaque type itself should
735
+ // be considered local. However, this could make it a breaking change
736
+ // to switch the underlying ('defining') type from a local type
737
+ // to a remote type. This would violate the rule that opaque
738
+ // types should be completely opaque apart from the traits
739
+ // that they implement, so we don't use this behavior.
740
+ self . found_non_local_ty ( ty)
741
+ }
713
742
} ;
714
743
// A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so
715
744
// the first type we visit is always the self type.
0 commit comments