Higher-ranked trait bounds in function signature incorrectly require bounds on the impl #132089
Open
Description
opened on Oct 24, 2024
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
Metadata
Assignees
Labels
Area: Associated items (types, constants & functions)Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)Area: Trait systemCategory: This is a bug.Relevant to the types team, which will review and decide on the PR/issue.Fixed by the next-generation trait solver, `-Znext-solver`.
Activity