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

Associated constants should not be object safe #26847

Closed
P1start opened this Issue Jul 7, 2015 · 12 comments

Comments

Projects
None yet
7 participants
@P1start
Copy link
Contributor

P1start commented Jul 7, 2015

The following code compiles:

#![feature(associated_consts)]

trait Foo {
    const FOO: u32;
}

impl Foo for () {
    const FOO: u32 = 1;
}

fn main() {
    let _: &Foo = &();
}

Furthermore, adding the line <Foo>::FOO; to main causes an ICE:

error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'assertion failed: match trait_items[method_offset_in_trait] {
    ty::MethodTraitItem(_) => true,
    _ => false,
}', ../src/librustc/middle/traits/util.rs:439
@oli-obk

This comment has been minimized.

Copy link
Contributor

oli-obk commented Jul 10, 2015

I think the code should be legal to compile. It's impossible to get the value of FOO from a variable (there's no such thing as a::FOO where a is a binding of type &Foo).

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Aug 5, 2015

@oli-obk
Well it shouldn't compile

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jan 26, 2017

I don't know if this can lead to unsoundness or not. Correct me.

@brson brson removed the I-unsound 💥 label Jan 26, 2017

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jan 26, 2017

@eddyb says no

@brson brson referenced this issue Jan 26, 2017

Closed

Tracking issue for `associated_consts` feature #29646

4 of 6 tasks complete
@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Mar 27, 2017

Update on this, the example in the original post compiles today.

But this ICEs:

#![feature(associated_consts)]

trait Foo {
    const FOO: u32;
}

impl Foo for () {
    const FOO: u32 = 1;
}

fn main() {
    let _ = <Foo as Foo>::FOO;
}

AFAICT there are two options here:

  1. Associated consts are not object safe, just like associated (static) functions.
  2. Associated consts must all be specified, just like associated types.

I think its sensible to start with the first. The second makes more sense in the context of a world with const params, but the first can be extended to the second.

It might also make sense some day to allow where clauses on associated consts just like methods (and on associated types, for that matter, which connects in some degree with the ATC RFC).

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented Apr 24, 2017

bors added a commit that referenced this issue Apr 24, 2017

Auto merge of #41494 - withoutboats:associated-consts-are-not-object-…
…safe, r=eddyb

Associated consts are not object safe.

fixes #26847

r? @eddyb

@bors bors closed this in #41494 Apr 24, 2017

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented May 3, 2017

Can't associated consts be part of the vtable/fat pointers?

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented May 3, 2017

Associated consts are inlined at compiletime, they can't have a value which is determined at runtime. This is a hard requirement for making things like const fn and const generics work.

Associated statics could be object safe if they existed.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented May 3, 2017

I think that having to write:

trait Foo {
    fn get_x(&self) -> u32;
}

trait FooC {
    const X: u32;
}

impl FooC for () {
    const X: u32 = 3;
}

impl Foo for () {
    fn get_x(&self) -> u32 { <() as FooC>::X } ; // or just 3
}

instead of just:

trait Foo {
  const X: u32;
}

or

trait Foo {
  const X: u32;
  fn get_x(&self) -> u32 { Self::X } 
}

is a pain.

they can't have a value which is determined at runtime.

The value is determined at compile-time, but I am talking about being able to access that value at run-time via dynamic dispatch.

@withoutboats

This comment has been minimized.

Copy link
Contributor

withoutboats commented May 3, 2017

The value is not determined at compile time for the virtually dispatched type Foo (the trait object type). What you want is the fields in traits RFC.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented May 3, 2017

The value is not determined at compile time for the virtually dispatched type Foo (the trait object type).

I did not say otherwise (the value is only determined at compile-time for the types that implement Foo, not for Foo itself or trait objects). What I did say is that currently there is no way to access this value at run-time without in my opinion unnecessary boilerplate but there should be one.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented May 3, 2017

Maybe the problem is that traits support associated consts, and associated consts are values, but traits do not support associated values (yet).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.