Skip to content

Higher-ranked trait bounds in function signature incorrectly require bounds on the impl #132089

Open
@8000thCube

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-trait-systemArea: Trait systemC-bugCategory: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions