Allow coercing functions whose signature differs in opaque types in their defining scope into a shared function pointer type by oli-obk · Pull Request #124297 · rust-lang/rust (original) (raw)

r? @compiler-errors

This accepts more code on stable. It is now possible to have match arms return a function item foo and a different function item bar in another, and that will constrain OpaqueTypeInDefiningScope to have the hidden type ConcreteType and make the type of the match arms a function pointer that matches the signature. So the following function will now compile, but on master it errors with a type mismatch on the second match arm

fn foo(t: T) -> T { t }

fn bar(t: T) -> T { t }

fn k() -> impl Sized { fn bind<T, F: FnOnce(T) -> T>(_: T, f: F) -> F { f } let x = match true { true => { let f = foo; bind(k(), f) } false => bar::<()>, }; todo!() }

cc #116652

This is very similar to #123794, and with the same rationale:

this is for consistency with -Znext-solver. the new solver does not have the concept of "non-defining use of opaque" right now and we would like to ideally keep it that way. Moving to DefineOpaqueTypes::Yes in more cases removes subtlety from the type system. Right now we have to be careful when relating Opaque with another type as the behavior changes depending on whether we later use the Opaque or its hidden type directly (even though they are equal), if that later use is with DefineOpaqueTypes::No*