about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-09-07 00:45:12 +0000
committerMichael Goulet <michael@errs.io>2023-09-07 01:31:32 +0000
commit4d05da46e7154a6fc31bed3b217892d9a98cc0e3 (patch)
tree8b8d89c33d5a822d96a38e76b6c2c498fde936de
parent4745d34bc3ac377f8444d5dac94e0f206b7cded7 (diff)
downloadrust-4d05da46e7154a6fc31bed3b217892d9a98cc0e3.tar.gz
rust-4d05da46e7154a6fc31bed3b217892d9a98cc0e3.zip
Don't emit refining_impl_trait for private items
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs28
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs2
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-extra.rs6
-rw-r--r--tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs4
-rw-r--r--tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match-works.rs8
-rw-r--r--tests/ui/impl-trait/in-trait/foreign.rs15
-rw-r--r--tests/ui/impl-trait/in-trait/nested-rpitit.rs12
-rw-r--r--tests/ui/impl-trait/in-trait/refine.rs24
-rw-r--r--tests/ui/impl-trait/in-trait/refine.stderr2
-rw-r--r--tests/ui/impl-trait/in-trait/reveal.rs6
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs4
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.rs14
-rw-r--r--tests/ui/impl-trait/in-trait/specialization-substs-remap.rs6
-rw-r--r--tests/ui/impl-trait/in-trait/success.rs12
15 files changed, 98 insertions, 47 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index b013f292e52..a8149b634ef 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -23,8 +23,22 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
     if !tcx.impl_method_has_trait_impl_trait_tys(impl_m.def_id) {
         return;
     }
+    // crate-private traits don't have any library guarantees, there's no need to do this check.
+    if !tcx.visibility(trait_m.container_id(tcx)).is_public() {
+        return;
+    }
 
+    // If a type in the trait ref is private, then there's also no reason to to do this check.
     let impl_def_id = impl_m.container_id(tcx);
+    for arg in impl_trait_ref.args {
+        if let Some(ty) = arg.as_type()
+            && let Some(self_visibility) = type_visibility(tcx, ty)
+            && !self_visibility.is_public()
+        {
+            return;
+        }
+    }
+
     let impl_m_args = ty::GenericArgs::identity_for_item(tcx, impl_m.def_id);
     let trait_m_to_impl_m_args = impl_m_args.rebase_onto(tcx, impl_def_id, impl_trait_ref.args);
     let bound_trait_m_sig = tcx.fn_sig(trait_m.def_id).instantiate(tcx, trait_m_to_impl_m_args);
@@ -281,3 +295,17 @@ fn report_mismatched_rpitit_signature<'tcx>(
         },
     );
 }
+
+fn type_visibility<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<ty::Visibility<DefId>> {
+    match *ty.kind() {
+        ty::Ref(_, ty, _) => type_visibility(tcx, ty),
+        ty::Adt(def, args) => {
+            if def.is_fundamental() {
+                type_visibility(tcx, args.type_at(0))
+            } else {
+                Some(tcx.visibility(def.did()))
+            }
+        }
+        _ => None,
+    }
+}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index df0151dc499..2567e273e11 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4496,7 +4496,7 @@ declare_lint! {
     ///
     /// use std::fmt::Display;
     ///
-    /// trait AsDisplay {
+    /// pub trait AsDisplay {
     ///     fn as_display(&self) -> impl Display;
     /// }
     ///
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs
index 1bbf4836a2a..3505690f1ec 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-extra.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-extra.rs
@@ -2,14 +2,14 @@
 // edition: 2021
 
 #![feature(async_fn_in_trait)]
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 #![allow(incomplete_features)]
 
 use std::future::Future;
 use std::pin::Pin;
 use std::task::Poll;
 
-trait MyTrait {
+pub trait MyTrait {
     async fn foo(&self) -> i32;
 }
 
@@ -27,7 +27,7 @@ impl Future for MyFuture {
 }
 
 impl MyTrait for i32 {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn foo(&self) -> impl Future<Output = i32> + Clone {
         MyFuture(*self)
     }
diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
index 5bd5c48ca69..6e99402113a 100644
--- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
@@ -1,4 +1,4 @@
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 
 use std::ops::Deref;
 
@@ -8,7 +8,7 @@ pub trait Foo {
 
 pub struct Foreign;
 impl Foo for Foreign {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar(self) -> &'static () {
         &()
     }
diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
index 063adb7c378..fbbbb8585d1 100644
--- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
@@ -2,7 +2,7 @@
 
 #![feature(return_position_impl_trait_in_trait)]
 
-trait Iterable {
+pub trait Iterable {
     type Item<'a>
     where
         Self: 'a;
diff --git a/tests/ui/impl-trait/in-trait/deep-match-works.rs b/tests/ui/impl-trait/in-trait/deep-match-works.rs
index ffd10d9b1ff..fc290f11f9d 100644
--- a/tests/ui/impl-trait/in-trait/deep-match-works.rs
+++ b/tests/ui/impl-trait/in-trait/deep-match-works.rs
@@ -1,16 +1,16 @@
 // check-pass
 
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 #![allow(incomplete_features)]
 
-struct Wrapper<T>(T);
+pub struct Wrapper<T>(T);
 
-trait Foo {
+pub trait Foo {
     fn bar() -> Wrapper<impl Sized>;
 }
 
 impl Foo for () {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar() -> Wrapper<i32> {
         Wrapper(0)
     }
diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs
index 035d91c1876..6285d7786d5 100644
--- a/tests/ui/impl-trait/in-trait/foreign.rs
+++ b/tests/ui/impl-trait/in-trait/foreign.rs
@@ -1,15 +1,25 @@
 // check-pass
 // aux-build: rpitit.rs
 
+#![feature(lint_reasons)]
+
 extern crate rpitit;
 
 use rpitit::{Foo, Foreign};
 use std::sync::Arc;
 
 // Implement an RPITIT from another crate.
-struct Local;
+pub struct Local;
 impl Foo for Local {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
+    fn bar(self) -> Arc<String> {
+        Arc::new(String::new())
+    }
+}
+
+struct LocalIgnoreRefining;
+impl Foo for LocalIgnoreRefining {
+    #[deny(refining_impl_trait)]
     fn bar(self) -> Arc<String> {
         Arc::new(String::new())
     }
@@ -24,4 +34,5 @@ fn main() {
     let &() = Foreign.bar();
 
     let x: Arc<String> = Local.bar();
+    let x: Arc<String> = LocalIgnoreRefining.bar();
 }
diff --git a/tests/ui/impl-trait/in-trait/nested-rpitit.rs b/tests/ui/impl-trait/in-trait/nested-rpitit.rs
index cb943eb5af9..58ba1acaf14 100644
--- a/tests/ui/impl-trait/in-trait/nested-rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/nested-rpitit.rs
@@ -1,28 +1,28 @@
 // check-pass
 
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 #![allow(incomplete_features)]
 
 use std::fmt::Display;
 use std::ops::Deref;
 
-trait Foo {
+pub trait Foo {
     fn bar(self) -> impl Deref<Target = impl Display + ?Sized>;
 }
 
-struct A;
+pub struct A;
 
 impl Foo for A {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar(self) -> &'static str {
         "Hello, world"
     }
 }
 
-struct B;
+pub struct B;
 
 impl Foo for B {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar(self) -> Box<i32> {
         Box::new(42)
     }
diff --git a/tests/ui/impl-trait/in-trait/refine.rs b/tests/ui/impl-trait/in-trait/refine.rs
index e9b5e669fde..a91f9b3e722 100644
--- a/tests/ui/impl-trait/in-trait/refine.rs
+++ b/tests/ui/impl-trait/in-trait/refine.rs
@@ -1,33 +1,45 @@
 #![feature(return_position_impl_trait_in_trait, async_fn_in_trait)]
 #![deny(refining_impl_trait)]
 
-trait Foo {
+pub trait Foo {
     fn bar() -> impl Sized;
 }
 
-struct A;
+pub struct A;
 impl Foo for A {
     fn bar() -> impl Copy {}
     //~^ ERROR impl method signature does not match trait method signature
 }
 
-struct B;
+pub struct B;
 impl Foo for B {
     fn bar() {}
     //~^ ERROR impl method signature does not match trait method signature
 }
 
-struct C;
+pub struct C;
 impl Foo for C {
     fn bar() -> () {}
     //~^ ERROR impl method signature does not match trait method signature
 }
 
-trait Late {
+struct Private;
+impl Foo for Private {
+    fn bar() -> () {}
+}
+
+pub trait Arg<A> {
+    fn bar() -> impl Sized;
+}
+impl Arg<Private> for A {
+    fn bar() -> () {}
+}
+
+pub trait Late {
     fn bar<'a>(&'a self) -> impl Sized + 'a;
 }
 
-struct D;
+pub struct D;
 impl Late for D {
     fn bar(&self) -> impl Copy + '_ {}
     //~^ ERROR impl method signature does not match trait method signature
diff --git a/tests/ui/impl-trait/in-trait/refine.stderr b/tests/ui/impl-trait/in-trait/refine.stderr
index 28d53270da3..65dfdf869e4 100644
--- a/tests/ui/impl-trait/in-trait/refine.stderr
+++ b/tests/ui/impl-trait/in-trait/refine.stderr
@@ -46,7 +46,7 @@ LL |     fn bar() -> impl Sized {}
    |                 ~~~~~~~~~~
 
 error: impl trait in impl method signature does not match trait method signature
-  --> $DIR/refine.rs:32:27
+  --> $DIR/refine.rs:44:27
    |
 LL |     fn bar<'a>(&'a self) -> impl Sized + 'a;
    |                             --------------- return type from trait method defined here
diff --git a/tests/ui/impl-trait/in-trait/reveal.rs b/tests/ui/impl-trait/in-trait/reveal.rs
index 65425ba1a84..b1b46d75b8f 100644
--- a/tests/ui/impl-trait/in-trait/reveal.rs
+++ b/tests/ui/impl-trait/in-trait/reveal.rs
@@ -1,14 +1,14 @@
 // check-pass
 
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 #![allow(incomplete_features)]
 
-trait Foo {
+pub trait Foo {
     fn f() -> Box<impl Sized>;
 }
 
 impl Foo for () {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn f() -> Box<String> {
         Box::new(String::new())
     }
diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs
index 747f7ed9e72..44a2b430344 100644
--- a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs
+++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs
@@ -1,6 +1,6 @@
 // issue: 113903
 
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 
 use std::ops::Deref;
 
@@ -10,7 +10,7 @@ pub trait Tr {
 }
 
 impl Tr for () {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn w() -> &'static () {
         &()
     }
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
index 135467d57ee..685c0f06e88 100644
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
@@ -2,17 +2,17 @@
 // revisions: success failure
 //[success] check-pass
 
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 
 use std::future::Future;
 
-trait Captures<'a> {}
+pub trait Captures<'a> {}
 impl<T> Captures<'_> for T {}
 
-trait Captures2<'a, 'b> {}
+pub trait Captures2<'a, 'b> {}
 impl<T> Captures2<'_, '_> for T {}
 
-trait AsyncTrait {
+pub trait AsyncTrait {
     #[cfg(success)]
     fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
 
@@ -44,7 +44,7 @@ impl AsyncTrait for Struct {
     // Does not capture more lifetimes that trait def'n, since trait def'n
     // implicitly captures all in-scope lifetimes.
     #[cfg(success)]
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
         async move { buff.to_vec() }
     }
@@ -52,7 +52,7 @@ impl AsyncTrait for Struct {
     // Does not capture more lifetimes that trait def'n, since trait def'n
     // implicitly captures all in-scope lifetimes.
     #[cfg(success)]
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
         async move { buff.to_vec() }
     }
@@ -60,7 +60,7 @@ impl AsyncTrait for Struct {
     // Does not capture more lifetimes that trait def'n, since trait def'n
     // implicitly captures all in-scope lifetimes.
     #[cfg(success)]
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn async_fn_multiple<'a, 'b>(
         &'a self,
         buff: &'b [u8],
diff --git a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
index 83812d6cd8a..41fc285883a 100644
--- a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
+++ b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
@@ -1,10 +1,10 @@
 // check-pass
 
 #![feature(specialization)]
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 #![allow(incomplete_features)]
 
-trait Foo {
+pub trait Foo {
     fn bar(&self) -> impl Sized;
 }
 
@@ -12,7 +12,7 @@ impl<U> Foo for U
 where
     U: Copy,
 {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar(&self) -> U {
         *self
     }
diff --git a/tests/ui/impl-trait/in-trait/success.rs b/tests/ui/impl-trait/in-trait/success.rs
index f583604a021..7d415ea17a4 100644
--- a/tests/ui/impl-trait/in-trait/success.rs
+++ b/tests/ui/impl-trait/in-trait/success.rs
@@ -1,32 +1,32 @@
 // check-pass
 
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
 #![allow(incomplete_features)]
 
 use std::fmt::Display;
 
-trait Foo {
+pub trait Foo {
     fn bar(&self) -> impl Display;
 }
 
 impl Foo for i32 {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar(&self) -> i32 {
         *self
     }
 }
 
 impl Foo for &'static str {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar(&self) -> &'static str {
         *self
     }
 }
 
-struct Yay;
+pub struct Yay;
 
 impl Foo for Yay {
-    #[allow(refining_impl_trait)]
+    #[expect(refining_impl_trait)]
     fn bar(&self) -> String {
         String::from(":^)")
     }