From a7bdcceadb2c8b455939a6c55aa070e428d54cbe Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas Chirananthavat)" Date: Mon, 8 Jun 2026 20:46:55 +0700 Subject: [PATCH] Add a test where subtyping inhibits coercion. --- .../subtyping-inhibits-deref-coercion.rs | 35 +++++++++++++++++++ .../subtyping-inhibits-deref-coercion.stderr | 12 +++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/ui/coercion/subtyping-inhibits-deref-coercion.rs create mode 100644 tests/ui/coercion/subtyping-inhibits-deref-coercion.stderr diff --git a/tests/ui/coercion/subtyping-inhibits-deref-coercion.rs b/tests/ui/coercion/subtyping-inhibits-deref-coercion.rs new file mode 100644 index 0000000000000..8232dcc6b1f18 --- /dev/null +++ b/tests/ui/coercion/subtyping-inhibits-deref-coercion.rs @@ -0,0 +1,35 @@ +// For some reason, subtyping due to higher ranked function pointers, +// even in an invariant position, causes deref coercion to not happen. +// This might be a compiler bug. However, as of this writing, +// the `pin!()` macro's soundness relies on code like this not compiling. +// See https://github.com/rust-lang/rust/issues/153438#issuecomment-4517609119 + +use std::marker::PhantomData; +use std::ops::{Deref, DerefMut}; + +// `Sub` is a subtype of `Sup` +type Sup = fn(&'static ()); +type Sub = for<'a> fn(&'a ()); + +struct Thing(PhantomData); + +impl Deref for Thing { + type Target = Thing; + fn deref(&self) -> &Thing { + unimplemented!() + } +} + +impl DerefMut for Thing { + fn deref_mut(&mut self) -> &mut Thing { + unimplemented!() + } +} + +// This could, in theory, compile due to a deref coercion. However, it does not. +fn foo(x: &mut Thing) -> &mut Thing { + x + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/coercion/subtyping-inhibits-deref-coercion.stderr b/tests/ui/coercion/subtyping-inhibits-deref-coercion.stderr new file mode 100644 index 0000000000000..c2a105e75fe82 --- /dev/null +++ b/tests/ui/coercion/subtyping-inhibits-deref-coercion.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/subtyping-inhibits-deref-coercion.rs:31:5 + | +LL | x + | ^ one type is more general than the other + | + = note: expected mutable reference `&mut Thing` + found mutable reference `&mut Thing fn(&'a ())>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.