Skip to content

My program segfaults and/or aborts when I abuse generic_associated_types #71210

Closed
@jonaskoelker

Description

@jonaskoelker

I tried this code:

// segfaults when running on 1.44.0-nightly (94d346360 2020-04-09)
#![allow(incomplete_features)]
#![feature(generic_associated_types)]

use std::collections::hash_map::{HashMap, Iter};

pub enum Papadimoulian { True, FileNotFound } // any two will do

fn visit_directory<FS: FileSystem>(fs: &FS) -> () {
    let _unused = "----------------------------------------------------------------------------".to_string();
    let mut iterator = fs.directory_iterator();
    iterator.next();
}

pub trait FileSystem {
    type DirectoryIterator<'a>: Iterator<Item = Result<Box<u8>, Papadimoulian>>;
    fn directory_iterator<'a>(&'a self) -> Self::DirectoryIterator<'a>;
}

impl FileSystem for HashMap<(), ()> {
    type DirectoryIterator<'a> = Iter<'a, (), ()>;
    fn directory_iterator<'a>(&'a self) -> Iter<'a, (), ()> {
        self.iter()
    }
}

/*****/ fn main() { visit_directory(&HashMap::new()) }
#[test] fn segv() { visit_directory(&HashMap::new()) }

(See also https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=05e8a880961163a517c92515c4edff7d)

When I feed this main.rs into rustc it happily gives me a main program. When I run said main program, I get [1] 32118 segmentation fault (core dumped) RUST_BACKTRACE=1 ./main from zsh. (The main program also segfaults without RUST_BACKTRACE=1.)

Instead, I expected the compiler to reject my program with a type error: The HashMap iterator has Self::Item = (&'a K, &'a V) which is not a Result<Box<u8>, Papadimoulian>—yet if my program is to mean what I think it should mean, it's claiming that to be the case.

If I compile without --release and remove a dash from the unused string, I instead get munmap_chunk(): invalid pointer. If I remove all the dashes, or I remove the unused variable alltogether (and still compile without --release), I get free(): invalid pointer.

If I change Box<u8> to Box<()> I get a test success.

If I keep Box<u8> and replace Papadimoulian with Option<()> I get a segfault. I also get segfaults if I replace Papadimoulian with bool or u8, but not if I replace it with () (in all cases keeping Box<u8>.)

These two issues seem to be exploring the same feature, but with different results: #69184 and #67089.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)C-bugCategory: This is a bug.F-generic_associated_types`#![feature(generic_associated_types)]` a.k.a. GATsI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions