< 返回版块

Neutron3529 发表于 2021-03-16 00:20

fn main() {
    func(&mut(0u8..1))
}

fn func<T: Iterator<Item = u8>>(iter: &mut T) {
    func(&mut iter.map(|x| x + 1))
}

据传,Rustc会在试图打印出错信息的时候卡死……

果然泛型什么的……对小白来说就是一个新世界


update:

原始出错的程序是这个:

fn main(){
  let mut iter=0u8..1;
  println!("begin");
  func(&mut iter)
}
fn func<T:Iterator<Item=u8>>(iter:&mut T){
    if let Some(x)=iter.next(){
        println!("{}",x);
        func(&mut iter.map(|x|x+1))
    }
}

肉身执行的结果很简单,程序打印一行begin,然后调用func(&mut iter),然后打印0,然后调用func(&mut iter.map(|x|x+1)),由于此时iter里面没有元素,调用结束(x2),然后程序正常退出

问题是,这段程序在编译时候卡死。

原文提供的是一个最小化的程序卡死的版本。


事实上,我在github里面标注了最新进展:

#![type_length_limit="393"]
fn main() {
    func(&mut(0u8..1))
}

fn func<T: Iterator<Item = u8>>(iter: &mut T) {
    func(&mut iter.map(|x| x + 1))
}

卡死(rustc 1.52),但

#![type_length_limit="392"]
fn main() {
    func(&mut(0u8..1))
}

fn func<T: Iterator<Item = u8>>(iter: &mut T) {
    func(&mut iter.map(|x| x + 1))
}

正常报错


评论区

写评论
作者 Neutron3529 2021-03-30 19:46

最新进展(差点忘了关注这个issue的进展了……)

 @b-naber b-naber linked a pull request that will close this issue 7 days ago
Introduce recursion limit in LateBoundRegionNameCollector #83406 
作者 Neutron3529 2021-03-17 23:53

解决方案并不是给rustc加上默认的递归层数限制。

递归本来是有限制的

type length也是有限制的(事实上我给出了限制失效的数字:393)

问题应该是为什么程序失效。

有人通过backtrace说这是试图打印错误时候卡死的原因

但我反正是没看懂backtrace……

--
👇
ruby: 我放上Rust相关issue的链接方便大家查看或反馈官方,issue#83150

官方已将该issue设成高优先级了,解决方案好像是给rustc加上默认的递归层数限制?

eweca-d 2021-03-17 16:09

GJ

--
👇
ruby: 我放上Rust相关issue的链接方便大家查看或反馈官方,issue#83150

官方已将该issue设成高优先级了,解决方案好像是给rustc加上默认的递归层数限制?

ruby 2021-03-17 14:23

我放上Rust相关issue的链接方便大家查看或反馈官方,issue#83150

官方已将该issue设成高优先级了,解决方案好像是给rustc加上默认的递归层数限制?

eweca-d 2021-03-16 22:19

还真是。挺神奇的。

--
👇
Neutron3529: 有关的

你可以试试把&mut T改成T

会直接撞recursion limit的

--
👇
eweca-d: 跟泛型无关,你这连编译都无限递归了,但是硬是没有啥错误,所以一直无限正确的递归编译下去了,自然也没有什么错误打印出来了。

作者 Neutron3529 2021-03-16 20:09

有关的

你可以试试把&mut T改成T

会直接撞recursion limit的

--
👇
eweca-d: 跟泛型无关,你这连编译都无限递归了,但是硬是没有啥错误,所以一直无限正确的递归编译下去了,自然也没有什么错误打印出来了。

eweca-d 2021-03-16 15:17

跟泛型无关,你这连编译都无限递归了,但是硬是没有啥错误,所以一直无限正确的递归编译下去了,自然也没有什么错误打印出来了。

azone 2021-03-16 12:34

   Compiling playground v0.0.1 (/playground)
/playground/tools/entrypoint.sh: line 11:     8 Killed                  timeout --signal=KILL ${timeout} "$@"

timeout 怎么能算没有错呢,这个和是不是泛型没关系吧?递归调用没有结束出口。。。

--
👇
ruby: 这段代码在play.rust-lang.org上运行正常啊,没有任何报错

ruby 2021-03-16 11:00

这段代码在play.rust-lang.org上运行正常啊,没有任何报错

1 共 9 条评论, 1 页