]> git.lizzy.rs Git - rust.git/commitdiff
orphan check: opaque types are an error
authorlcnr <rust@lcnr.de>
Thu, 21 Jul 2022 08:53:54 +0000 (10:53 +0200)
committerlcnr <rust@lcnr.de>
Thu, 21 Jul 2022 08:53:54 +0000 (10:53 +0200)
compiler/rustc_trait_selection/src/traits/coherence.rs
src/test/ui/impl-trait/negative-reasoning.stderr

index 52ca23c4b303ebd906a9b10eaf33fcabb7a64f48..67ae26b0b3ad1049a80c5c29363e890a9920b535 100644 (file)
@@ -739,34 +739,6 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
 
         ty::Adt(def, _) => def_id_is_local(def.did(), in_crate),
         ty::Foreign(did) => def_id_is_local(did, in_crate),
-        ty::Opaque(..) => {
-            // This merits some explanation.
-            // Normally, opaque types are not involved when performing
-            // coherence checking, since it is illegal to directly
-            // implement a trait on an opaque type. However, we might
-            // end up looking at an opaque type during coherence checking
-            // if an opaque type gets used within another type (e.g. as
-            // a type parameter). This requires us to decide whether or
-            // not an opaque type should be considered 'local' or not.
-            //
-            // We choose to treat all opaque types as non-local, even
-            // those that appear within the same crate. This seems
-            // somewhat surprising at first, but makes sense when
-            // you consider that opaque types are supposed to hide
-            // the underlying type *within the same crate*. When an
-            // opaque type is used from outside the module
-            // where it is declared, it should be impossible to observe
-            // anything about it other than the traits that it implements.
-            //
-            // The alternative would be to look at the underlying type
-            // to determine whether or not the opaque type itself should
-            // be considered local. However, this could make it a breaking change
-            // to switch the underlying ('defining') type from a local type
-            // to a remote type. This would violate the rule that opaque
-            // types should be completely opaque apart from the traits
-            // that they implement, so we don't use this behavior.
-            false
-        }
 
         ty::Dynamic(ref tt, ..) => {
             if let Some(principal) = tt.principal() {
@@ -786,7 +758,7 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo
         //
         // See `test/ui/coherence/coherence-with-closure.rs` for an example where this
         // could happens.
-        ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => {
+        ty::Opaque(..) | ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => {
             tcx.sess.delay_span_bug(
                 DUMMY_SP,
                 format!("ty_is_local invoked on closure or generator: {:?}", ty),
index 479b451855d5517fb2a7fe6edf8358d15130874c..2eea726a19c5aa6622a2365b1271ee2a11a00bb7 100644 (file)
@@ -7,7 +7,7 @@ LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
 LL | impl AnotherTrait for D<OpaqueType> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
    |
-   = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
+   = note: downstream crates may implement trait `std::fmt::Debug` for type `OpaqueType`
 
 error: cannot implement trait on type alias impl trait
   --> $DIR/negative-reasoning.rs:19:25