Refining generic bounds in trait method
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
This issue documents an aspect of #100706 (refined trait implementations) that to my knowledge has not been previously discussed or documented: refining generic bounds on trait methods.
It also documents the current rustc behavior, which seems to be quite surprising based on conversations I've had with a half dozen very experienced Rustaceans.
Code example
Consider the following setup in a fictional upstream crate:
pub trait Super {}
mod private {
pub trait Marker: super::Super {}
}
pub trait Subject {
fn method<IM: private::Marker>(&self);
}
In this case, rustc allows both of the following generic type refinements with no errors or warnings:
struct First;
impl upstream::Subject for First {
fn method<IM: upstream::Super>(&self) {}
}
struct Second;
impl upstream::Subject for Second {
fn method<IM>(&self) {}
}
Surprising current behavior
In the above code, First refines the generic bound from IM: upstream::private::Marker to IM: upstream::Super, a supertype of Marker. Second refines the bound away completely, allowing any type.
It's quite surprising that a bare <IM> generic is accepted! It's completely unused and trivially satisfied, and unbounded generics are usually not accepted elsewhere in Rust. Consider for example that PhantomData marker fields must be added if a type declares, but does not use, a generic type.
Relying on the refinement fails at point of use, not declaration
Attempting to rely on either refinement when calling the refined function fail with the trait bound '<type>: Marker' is not satisfied errors:
fn use_first() {
<First as upstream::Subject>::method::<()>(&First);
}
impl upstream::Super for () {}
fn use_second() {
<Second as upstream::Subject>::method::<()>(&Second);
}
A warning similar to the one for refined return types (impl trait in impl method signature does not match trait method signature) would be good. An example of that warning can be seen in this playground link.
Related to #121718, #100706
@rustbot label +F-refine +T-lang
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the two generic-bound refinement examples using the linked Rust Playground cases and compare their behavior with the refined return-type warning example. Read related issues #121718 and #100706 to understand the intended refinement rules. Done means reaching agreement on whether these refinements should produce a diagnostic and documenting or testing that behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100