Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE when trying to parameterize on ebml::writer::Encoder #11881

Closed
olsonjeffery opened this issue Jan 28, 2014 · 4 comments
Closed

ICE when trying to parameterize on ebml::writer::Encoder #11881

olsonjeffery opened this issue Jan 28, 2014 · 4 comments
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@olsonjeffery
Copy link
Contributor

(pnkfelix: Here is a modern example that ICE's (feel free to replace as necessary as rustc changes):)

extern crate ser = "serialize";

use serialize = self::ser; // necessary for deriving(Encodable)
use ser::{Encodable, Encoder};
use ser::json;
use ser::ebml::writer;
use std::io::MemWriter;
use std::str::from_utf8_owned;

#[deriving(Encodable)]
struct Foo {
    baz: bool,
}

#[deriving(Encodable)]
struct Bar {
    froboz: uint
}

enum WireProtocol {
    JSON,
    EBML,
    // ...
}

fn encode_json<'a, T: Encodable<json::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
    let mut encoder = json::Encoder::new(wr);
    val.encode(&mut encoder);
}
fn encode_ebml<'a, T: Encodable<writer::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
    let mut encoder = writer::Encoder(wr);
    val.encode(&mut encoder);
}

pub fn main() {
    let target = Foo { baz: false };
    let mut wr = MemWriter::new();
    let proto = JSON;
    match proto {
        JSON => encode_json(&target, &mut wr),
        EBML => encode_ebml(&target, &mut wr)
    }
}

Original bug description follows

Consider the following:

extern mod extra = "extra#0.10-pre";

use extra::serialize::{Encodable, Encoder};
use extra::json;
use extra::ebml::writer;
use std::io::MemWriter;
use std::str::from_utf8_owned;

#[deriving(Encodable)]
struct Foo {
    baz: bool,
}

#[deriving(Encodable)]
struct Bar {
    froboz: uint
}

enum WireProtocol {
    JSON,
    EBML,
    // ...
}

fn encode_json<'a, T: Encodable<json::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
    let mut encoder = json::Encoder::new(wr);
    val.encode(&mut encoder);
}
fn encode_ebml<'a, T: Encodable<writer::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
    let mut encoder = writer::Encoder(wr);
    val.encode(&mut encoder);
}

fn main() {
    let target = Foo { baz: false };
    let mut wr = MemWriter::new();
    let proto = JSON;
    match proto {
        JSON => encode_json(&target, &mut wr),
        EBML => encode_ebml(&target, &mut wr)
    }
}

This fails with the following ICE:

serialization-branch.rs:31:16: 31:28 error: internal compiler error: Cannot relate bound region: ReLateBound(167, BrNamed(syntax::ast::DefId{crate: 0u32, node: 185u32}, a)) <= ReInfer(0)
This message reflects a bug in the Rust compiler.
We would appreciate a bug report: http://static.rust-lang.org/doc/master/complement-bugreport.html
serialization-branch.rs:31     val.encode(&mut encoder);

But if you comment out the EBML code, like so:

extern mod extra = "extra#0.10-pre";

use extra::serialize::{Encodable, Encoder};
use extra::json;
use extra::ebml::writer;
use std::io::MemWriter;
use std::str::from_utf8_owned;

#[deriving(Encodable)]
struct Foo {
    baz: bool,
}

#[deriving(Encodable)]
struct Bar {
    froboz: uint
}

enum WireProtocol {
    JSON,
    EBML,
    // ...
}

fn encode_json<'a, T: Encodable<json::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
    let mut encoder = json::Encoder::new(wr);
    val.encode(&mut encoder);
}
/*
fn encode_ebml<'a, T: Encodable<writer::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
    let mut encoder = writer::Encoder(wr);
    val.encode(&mut encoder);
}
*/

fn main() {
    let target = Foo { baz: false };
    let mut wr = MemWriter::new();
    let proto = JSON;
    match proto {
        JSON => encode_json(&target, &mut wr),
        _ => {}
        //EBML => encode_ebml(&target, &mut wr)
    }
}

it compiles.

The JSON and EBML serialization code is identifical, but their Encoder impls and how they're exposed are slightly different (I assume because of their respective histories). Something about that difference is triggering this ICE, it seems.

@olsonjeffery
Copy link
Contributor Author

As observed by @huonw , probably related to #5121

@pnkfelix
Copy link
Member

still reproduces.

updated description to put in something that builds against rustc 0.10-pre (caf17fe 2014-03-21)

@JustAPerson
Copy link
Contributor

This no longer produces an ICE likely due to #13157 and related work towards resolving the outstanding #5121.

The updated version in the description no longer builds against master due to changes in the libserialize API, so I have updated it again here: https://gist.github.com/JustAPerson/a96dddcde35633ec9d27
A small diff is provided:

--- old.rs 2014-03-30 20:40:18.290040065 -0500
+++ new.rs     2014-03-30 20:47:11.096850380 -0500
@@ -26 +26 @@
-fn encode_json<'a, T: Encodable<json::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
+fn encode_json<'a, T: Encodable<json::Encoder<'a>, std::io::IoError>>(val: &T, wr: &'a mut MemWriter) {
@@ -30 +30 @@
-fn encode_ebml<'a, T: Encodable<writer::Encoder<'a>>>(val: &T, wr: &'a mut MemWriter) {
+fn encode_ebml<'a, T: Encodable<writer::Encoder<'a, MemWriter>, std::io::IoError>>(val: &T, wr: &'a mut MemWriter) {

Tested with

rustc 0.10-pre (ec7d0c7 2014-03-30 11:26:44 -0700)
host: x86_64-unknown-linux-gnu

@sfackler
Copy link
Member

Flagging as needstest

alexcrichton added a commit to alexcrichton/rust that referenced this issue Apr 8, 2014
Closes rust-lang#13394 (sync: remove unsafe and add Send+Share to Deref (enabled by autoderef vtables))
Closes rust-lang#13389 (Made libflate functions return Options instead of outright failing)
Closes rust-lang#13388 (doc: Document flavorful variations of paths)
Closes rust-lang#13387 (Register new snapshots)
Closes rust-lang#13386 (std: Add more docs for ptr mod)
Closes rust-lang#13384 (Tweak crate loading to load less metadata)
Closes rust-lang#13382 (fix ~ZeroSizeType rvalues)
Closes rust-lang#13378 (Update tidy script, replace XXX with FIXME)
Closes rust-lang#13377 (std: User a smaller stdin buffer on windows)
Closes rust-lang#13369 (Fix spelling errors in comments.)
Closes rust-lang#13314 (Made 'make install' include libs for additional targets)
Closes rust-lang#13278 (std: make vec!() macro handle a trailing comma)
Closes rust-lang#13276 (Add test for rust-lang#11881)
flip1995 pushed a commit to flip1995/rust that referenced this issue Feb 26, 2024
[`implied_bounds_in_impls`]: avoid linting on overlapping associated tys

Fixes rust-lang#11880

Before this change, we were simply ignoring associated types (except for suggestion purposes), because of an incorrect assumption (see the comment that I also removed).

For something like
```rs
trait X { type T; }
trait Y: X { type T; }

// Can't constrain `X::T` through `Y`
fn f() -> impl X<T = i32> + Y<T = u32> { ... }
```
We now avoid linting if the implied bound (`X<T = i32>`) "names" associated types that also exists in the implying trait (`trait Y`). Here that would be the case.
But if we only wrote `impl X + Y<T = u32>` then that's ok because `X::T` was never constrained in the first place.

I haven't really thought about how this interacts with GATs, but I think it's fine. Fine as in, it might create false negatives, but hopefully no false positives.

(The diff is slightly annoying because of formatting things. Really the only thing that changed in the if chain is extracting the `implied_by_def_id` which is needed for getting associated types from the trait, and of course actually checking for overlap)

cc `@Jarcho` ? idk if you want to review this or not. I assume you looked into this code a bit to find this bug.

changelog: [`implied_bounds_in_impls`]: avoid linting when associated type from supertrait can't be constrained through the implying trait bound
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

No branches or pull requests

4 participants