rust-lang / rust-lang/rust

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

Open
#132,089 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-associated-items A-higher-ranked A-trait-system C-bug fixed-by-next-solver T-types
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.