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

Copying Primitive Types #8

Open
phase opened this issue Mar 22, 2017 · 4 comments
Open

Copying Primitive Types #8

phase opened this issue Mar 22, 2017 · 4 comments
Assignees
Labels

Comments

@phase
Copy link
Owner

phase commented Mar 22, 2017

With 0b6cf37, I introduced a very primitive ownership implementation into the Semantic Analysis pass. The biggest caveat of this is that it will error when moving primitive types, such as ints.

In Rust, you can't use a struct once you've moved it.

struct P {
    x: i32,
}

fn main() {
    let a = P { x: 7 };
    let b = a;
    let c = a.x + b.x;
    println!("{}", c);
}

This code will result in the following error:

rustc 1.16.0 (30cf806ef 2017-03-10)
error[E0382]: use of moved value: `a.x`
 --> <anon>:8:13
  |
7 |     let b = a;
  |         - value moved here
8 |     let c = a.x + b.x;
  |             ^^^ value used here after move
  |
  = note: move occurs because `a` has type `P`, which does not implement the `Copy` trait

error: aborting due to previous error

This behavior has been implemented:

class P
    let x : Int

    init (v : Int)
        x = v
;

main () : Int
    let a = new P(7),
    let b = a,
    let c = a.x + b.x,
    0
11             let b = a,
12             let c = a.x + b.x,
   ~~~~~~~~~~~~^
13             0
Reference to 'a' has already been used.

However, Rust handles primitives differently...

fn main() {
    let a = 7;
    let b = a;
    let c = a + b;
    println!("{}", c);
}

This code is perfectly allowed in Rust, since a is being copied to b when it is moved.

main ()
  let a = 7,
  let b = a,
  let c = a + b,
  0

This will currently error with the following:

4             let b = a,
5             let c = a + b,
  ~~~~~~~~~~~~^
6             0
Reference to 'a' has already been used.

If we look at the above Rust error, we can see that our struct didn't implement the Copy trait. Integers in Rust implement this trait, and thus can be copied. It would be easy to create a special case for our defined primitive types, but having something like "traits" would be beneficial to users who want their classes to be copyable. Maybe an annotation?

@phase phase added the desgin label Mar 22, 2017
@phase phase self-assigned this Mar 22, 2017
@phase
Copy link
Owner Author

phase commented Mar 22, 2017

@copy
class P
    let x : Int
;

I think this could be a good idea. I've always liked the idea of annotations, but making the language annotation heavy might not make it super intuative.

@Techcable
Copy link

I think classes should be value-based by default and should have to explicitly request reference schematics (forcing heap-allocation). If this is done, the compiler is free to stack-allocate and copy immutable objects, allowing boxing to be deferred indefinitely.

@phase
Copy link
Owner Author

phase commented Mar 22, 2017

If we're moving large objects, copying would be quite slow.

Think about this:

LargeObject largeObj = new LargeObject();
largeObj.a = 7;
largeObj.b = true;
// etc.

LargeObjectContainer box = new LargeObjectContainer(largeObj);

If we have to copy largeObj, then it'll be slower than just passing the reference.

Objects will be stack allocated once there's a pass implemented to detect that they can be.

@Techcable
Copy link

You only need to do the optimization for small immutable objects, which are the most common.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants