Higher-ranked trait bounds in function signature incorrectly require bounds on the impl
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Description:
When using higher-ranked trait bounds (HRTBs) in a method signature, the compiler throws an error suggesting that the bounds should be moved to the impl block, even though the function-specific bound should be sufficient.
Expected behavior:
The function-specific bound should be enough, and the implementation should compile without moving the bound to the impl block.
Actual behavior:
The compiler throws an error, requiring the bound to be placed on the impl block instead of just the method, even though the method-specific bound should work.
Example code
impl <T:Base>Base for Wrapper<T>{
type E=T::E;
}
impl <T:Trait<U>,U:Base>Trait<U>for Wrapper<T>{
fn requires_ref_add_and_assign(&self,u:&U) where for<'a>U::E:AddAssign<<&'a T::E as Add<&'a U::E>>::Output>,for<'a>&'a T::E:Add<&'a U::E>{
}
}
struct Wrapper<T:Base>(T);
trait Base{
type E;
}
trait Trait<U:Base>:Base{
fn requires_ref_add_and_assign(&self,u:&U) where for<'a>U::E:AddAssign<<&'a Self::E as Add<&'a U::E>>::Output>,for<'a>&'a Self::E:Add<&'a U::E>;
}
use std::ops::{Add,AddAssign};
Compiler output
error[E0277]: cannot add `&'a <U as Base>::E` to `&'a <T as Base>::E`
--> src/main.rs:12:2
|
12 | fn requires_add(&self,u:&U) where for<'a>U::E:AddAssign<<&'a T::E as Add<&'a U::E>>::Output>,for<'a>&'a T::E:Add<&'a U::E>{
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `&'a <T as Base>::E + &'a <U as Base>::E`
|
= help: the trait `for<'a> Add<&'a <U as Base>::E>` is not implemented for `&'a <T as Base>::E`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
11 | impl <T:Trait<U>,U:Base>Trait<U>for Wrapper<T> where for<'a> &'a <T as Base>::E: Add<&'a <U as Base>::E>{
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Workaround:
Moving the bounds to the impl block works, but function-specific bounds should work without requiring this. Since I can't do that in my actual use case, I've made alternative operation traits.
Meta
rustc --version --verbose:
rustc 1.80.1 (3f5fd8dd4 2024-08-06) (Arch Linux rust 1:1.80.1-1)
binary: rustc
commit-hash: 3f5fd8dd41153bc5fdca9427e9e05be2c767ba23
commit-date: 2024-08-06
host: x86_64-unknown-linux-gnu
release: 1.80.1
LLVM version: 18.1.8
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
Start by reproducing the higher-ranked trait bounds example in src/main.rs with the reported rustc version. Compare the method-specific bounds with the impl-level workaround and trace the compiler diagnostic that rejects the method signature. Done means the example compiles with the bounds kept on the method, without requiring them on the impl block.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100