A simple example of HRBT

A simple example of HRBT

(Jin Qing’s Column, April., 2025)

Higher-ranked trait bounds (HRTBs) specify a bound that is true for all lifetimes.

Here is an example of how HRTB is used.

fn bar() -> impl for<'a> Fn(&'a str, &'a str) -> &'a str {
    move |text1, text2| {
        println!("{text1}, {text2}");
        text1
    }
}

bar() returns a Fn which must specify the lifetimes of parameters and return type.

The main() function:

fn main() {
    let func = bar();
    let text1: String = "Hello".into();
    let text2: String = "world".into();
    let text = func(&text1, &text2);
    println!("text: {text}");
}

If we don’t use HRBT:

fn bar<'a>() -> impl Fn(&'a str, &'a str) -> &'a str {
	todo!()
}

There will be errors:

error[E0597]: `text1` does not live long enough
 --> src\main.rs:5:21
  |
3 |     let text1: String = "Hello".into();
  |         ----- binding `text1` declared here
4 |     let text2: String = "world".into();
5 |     let text = func(&text1, &text2);
  |                     ^^^^^^ borrowed value does not live long enough
6 |     println!("text: {text}");
7 | }
  | -
  | |
  | `text1` dropped here while still borrowed
  | borrow might be used here, when `func` is dropped and runs the destructor for type `impl Fn(&str, &str) -> &str`
  |
  = note: values in a scope are dropped in the opposite order they are defined

error[E0597]: `text2` does not live long enough
 --> src\main.rs:5:29
  |
4 |     let text2: String = "world".into();
  |         ----- binding `text2` declared here
5 |     let text = func(&text1, &text2);
  |                             ^^^^^^ borrowed value does not live long enough
6 |     println!("text: {text}");
7 | }
  | -
  | |
  | `text2` dropped here while still borrowed
  | borrow might be used here, when `func` is dropped and runs the destructor for type `impl Fn(&str, &str) -> &str`
  |
  = note: values in a scope are dropped in the opposite order they are defined

If we delete the lifetimes:

fn bar() -> impl Fn(&str, &str) -> &str {
	todo!()
}

The compiler sugguests using HRBT:

error[E0106]: missing lifetime specifier
 --> src\main.rs:9:36
  |
9 | fn bar() -> impl Fn(&str, &str) -> &str {
  |                     ----  ----     ^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does 
not say whether it is borrowed from argument 1 or argument 2
  = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider making the bound lifetime-generic with a new `'a` lifetime
  |
9 | fn bar() -> impl for<'a> Fn(&'a str, &'a str) -> &'a str {
  |                  +++++++     ++       ++          ++
help: consider introducing a named lifetime parameter
  |
9 | fn bar<'a>() -> impl Fn(&'a str, &'a str) -> &'a str {
  |       ++++               ++       ++          ++

Reference: https://www.zhihu.com/question/504670139

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值