Skip to content

Segfault when returning deep function compositions #93237

Open
@fredlahde

Description

@fredlahde

This issue is tightly bound to this PR (93082), which aims to add the ability to return impl Fn() -> impl Trait from a function.

I played around with it, and got the idea to test out if there is a limit to how deep we can nest those functions (since the PR also enables impl Fn() -> impl Fn() -> impl Trait). It quickly noticed a segfault from rustc and was able to determine the exact depth that causes the crash.

Code

For generating test files quickly, I wrote a small code generator:

const FILE_NAME: &str = "test.rs";

use std::io::Write;
use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let n_depth: usize = args[1].parse().unwrap();
    let mut fd = std::fs::OpenOptions::new()
        .create(true)
        .truncate(true)
        .write(true)
        .open(FILE_NAME)
        .unwrap();
    fd.write(b"use std::fmt::Debug;\n").unwrap();
    fd.write(b"fn foo()").unwrap();
    (0..n_depth).for_each(|_| {
        let _w = fd.write(b"-> impl Fn() ").unwrap();
    });
    fd.write(b"-> impl Debug {\n").unwrap();
    (0..n_depth).for_each(|_| {
        let _w = fd.write(b"|| ").unwrap();
    });
    fd.write(br#""hi""#).unwrap();
    fd.write(b"}\n").unwrap();

    fd.write(br#"
        fn main() {
            let x = foo()"#).unwrap();
    (0..n_depth).for_each(|_| {
        let _w = fd.write(b"()").unwrap();
    });
    fd.write(br#";
        println!("{:?}", x);
        }"#).unwrap();
}

Once compiled, one can call it like this: ./gen <depth>. The depth argument controls the count of -> impl Fn() that is emitted. The following listing is an example with depth set to 5:

use std::fmt::Debug;
fn foo()-> impl Fn() -> impl Fn() -> impl Fn() -> impl Fn() -> impl Fn() -> impl Debug {
|| || || || || "hi"}

        fn main() {
            let x = foo()()()()()();
        println!("{:?}", x);
        }

If one then tries to compile this with the rustc from the PR at commit 3ed486b37477dde94c87539, the test program compiles successfully.

However, when I set depth to 560, I get a segfault.

Meta

rustc --version --verbose:

rustc 1.60.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.60.0-dev
LLVM version: 13.0.0

Error output

I got a backtrace from gdb:

#0  0x00007ffff5a28670 in core::iter::adapters::process_results::<core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::zip::Zip<core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>, core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>>>, rustc_middle::ty::relate::relate_substs<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#0}>, rustc_middle::ty::subst::GenericArg, rustc_middle::ty::error::TypeError, <core::result::Result<smallvec::SmallVec<[rustc_middle::ty::subst::GenericArg; 8]>, rustc_middle::ty::error::TypeError> as core::iter::traits::collect::FromIterator<core::result::Result<rustc_middle::ty::subst::GenericArg, rustc_middle::ty::error::TypeError>>>::from_iter<core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::zip::Zip<core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>, core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>>>, rustc_middle::ty::relate::relate_substs<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#0}>>::{closure#0}, smallvec::SmallVec<[rustc_middle::ty::subst::GenericArg; 8]>> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#1  0x00007ffff5ab8cb0 in <core::result::Result<rustc_middle::ty::subst::GenericArg, rustc_middle::ty::error::TypeError> as rustc_middle::ty::context::InternIteratorElement<rustc_middle::ty::subst::GenericArg, &rustc_middle::ty::list::List<rustc_middle::ty::subst::GenericArg>>>::intern_with::<core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::zip::Zip<core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>, core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>>>, rustc_middle::ty::relate::relate_substs<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#0}>, <rustc_middle::ty::context::TyCtxt>::mk_substs<core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::zip::Zip<core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>, core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>>>, rustc_middle::ty::relate::relate_substs<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#0}>>::{closure#0}> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#2  0x00007ffff598b20d in <rustc_middle::ty::context::TyCtxt>::mk_substs::<core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::zip::Zip<core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>, core::iter::adapters::copied::Copied<core::slice::iter::Iter<rustc_middle::ty::subst::GenericArg>>>>, rustc_middle::ty::relate::relate_substs<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#0}>> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#3  0x00007ffff5af7b0a in rustc_middle::ty::relate::relate_substs::<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#4  0x00007ffff5ae1780 in <&rustc_middle::ty::list::List<rustc_middle::ty::subst::GenericArg> as rustc_middle::ty::relate::Relate>::relate::<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#5  0x00007ffff5af8f11 in rustc_middle::ty::relate::super_relate_tys::<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#6  0x00007ffff59cb2e6 in <rustc_infer::infer::InferCtxt>::super_combine_tys::<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#7  0x00007ffff5a99bd7 in <rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate> as rustc_middle::ty::relate::TypeRelation>::relate::<&rustc_middle::ty::TyS> ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#8  0x00007ffff5b011c3 in <&mut <rustc_middle::ty::sty::FnSig as rustc_middle::ty::relate::Relate>::relate<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#1} as core::ops::function::FnOnce<(((&rustc_middle::ty::TyS, &rustc_middle::ty::TyS), bool),)>>::call_once ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so
#9  0x00007ffff5abe042 in <core::iter::adapters::map::Map<core::iter::adapters::enumerate::Enumerate<core::iter::adapters::map::Map<core::iter::adapters::chain::Chain<core::iter::adapters::map::Map<core::iter::adapters::zip::Zip<core::slice::iter::Iter<&rustc_middle::ty::TyS>, core::slice::iter::Iter<&rustc_middle::ty::TyS>>, <rustc_middle::ty::sty::FnSig as rustc_middle::ty::relate::Relate>::relate<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#0}>, core::iter::sources::once::Once<((&rustc_middle::ty::TyS, &rustc_middle::ty::TyS), bool)>>, <rustc_middle::ty::sty::FnSig as rustc_middle::ty::relate::Relate>::relate<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#1}>>, <rustc_middle::ty::sty::FnSig as rustc_middle::ty::relate::Relate>::relate<rustc_infer::infer::nll_relate::TypeRelating<rustc_borrowck::type_check::relate_tys::NllTypeRelatingDelegate>>::{closure#2}> as core::iter::traits::iterator::Iterator>::next ()
   from /mnt/work/home/fredlahde/research/rust-impl-fn-depth-test/rust-fork/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-135a9886b846246a.so

I am not entirely sure, if this is important enough for having it's own issue, since it's so tightly bound to the PR. Feel free to close / move accordingly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.I-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.S-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions