Repository: gluon-lang/gluon (rust)

Issue:
pub unsupported for Rust tuple struct in Getable derive macro
The macro for Getable derive doesn't seem to support the pub keyword.  I've modified this example:
`https://github.com/gluon-lang/gluon/blob/master/codegen/tests/full.rs`
to highlight the issue.  Note the `struct Newtype(pub Struct);` line.

```
extern crate gluon;
#[macro_use]
extern crate gluon_codegen;
#[macro_use]
extern crate gluon_vm;

use gluon::{
    new_vm,
    Thread,
    Compiler,
    vm::{
        self,
        ExternModule,
    },
    import,
};

#[derive(Debug, PartialEq, Getable, Pushable, VmType)]
struct Struct {
    string: String,
    number: u32,
    vec: Vec<f64>,
}

fn load_struct_mod(vm: &Thread) -> vm::Result<ExternModule> {
    let module = record! {
        new_struct => primitive!(1, new_struct),
    };

    ExternModule::new(vm, module)
}

fn new_struct(_: ()) -> Struct {
    Struct {
        string: "hello".to_owned(),
        number: 1,
        vec: vec![1.0, 2.0, 3.0],
    }
}

#[test]
fn normal_struct() {
    let vm = new_vm();
    let mut compiler = Compiler::new();
    import::add_extern_module(&vm, "functions", load_struct_mod);

    let script = r#"
        let { new_struct } = import! functions

        new_struct ()
    "#;

    let (s, _) = compiler
        .run_expr::<Struct>(&vm, "test", script)
        .unwrap_or_else(|why| panic!("{}", why));

    assert_eq!(
        s,
        Struct {
            string: "hello".into(),
            number: 1,
            vec: vec![1.0, 2.0, 3.0],
        }
    );
}

#[derive(Debug, PartialEq, VmType, Pushable, Getable)]
struct Newtype(pub Struct);

fn load_newtype_mod(vm: &Thread) -> vm::Result<ExternModule> {
    let module = record! {
        newtype_id => primitive!(1, newtype_id),
    };

    ExternModule::new(vm, module)
}

fn newtype_id(val: Newtype) -> Newtype {
    val
}

#[test]
fn newtype() {
    let vm = new_vm();
    let mut compiler = Compiler::new();
    import::add_extern_module(&vm, "functions", load_newtype_mod);

    // newtypes should map to the inner type
    let script = r#"
        let { newtype_id } = import! functions
        newtype_id { string = "test", number = 42, vec = [1.0, 1.0, 2.0, 3.0, 5.0] }
    "#;

    let (s, _) = compiler
        .run_expr::<Newtype>(&vm, "test", script)
        .unwrap_or_else(|why| panic!("{}", why));

    assert_eq!(
        s,
        Newtype(Struct {
            string: "test".into(),
            number: 42,
            vec: vec![1.0, 1.0, 2.0, 3.0, 5.0],
        })
    );
}
```
This is the error I get:
```
error: expected type, found keyword `pub`
  --> src/main.rs:68:16
   |
68 | struct Newtype(pub Struct);
   |                ^^^

error: proc-macro derive produced unparseable tokens
  --> src/main.rs:67:46
   |
67 | #[derive(Debug, PartialEq, VmType, Pushable, Getable)]
   |                                              ^^^^^^^

error: aborting due to 2 previous errors
```

Pull request:
fix: Handle newtypes with a public field
Fixes #713

Patch:
diff --git a/base/src/types/mod.rs b/base/src/types/mod.rs
index 4ee2d3ee..a55340af 100644
--- a/base/src/types/mod.rs
+++ b/base/src/types/mod.rs
@@ -6,7 +6,7 @@ use std::{
     iter,
     marker::PhantomData,
     mem,
-    ops::{self, Deref, DerefMut},
+    ops::{Deref, DerefMut},
     rc::Rc,
     sync::Arc,
 };
diff --git a/codegen/src/getable.rs b/codegen/src/getable.rs
index 19ceb120..4044a48c 100644
--- a/codegen/src/getable.rs
+++ b/codegen/src/getable.rs
@@ -85,12 +85,13 @@ where
     // Treat newtype structs as just their inner type
     let (first, second) = (fields.next(), fields.next());
     match (&first, &second) {
-        (Some(field_ty), None) => {
+        (Some(field), None) => {
+            let field_ty = &field.ty;
             return quote! {
                 #ident (
                 <#field_ty as _gluon_api::Getable<'__vm, '__value>>::from_value(vm, variants)
                 )
-            }
+            };
         }
         _ => (),
     }


Test patch:
diff --git a/codegen/tests/full.rs b/codegen/tests/full.rs
index c24a31dc..bf08bc1a 100644
--- a/codegen/tests/full.rs
+++ b/codegen/tests/full.rs
@@ -60,7 +60,7 @@ fn normal_struct() {
 }
 
 #[derive(Debug, PartialEq, VmType, Pushable, Getable)]
-struct Newtype(Struct);
+struct Newtype(pub Struct);
 
 fn load_newtype_mod(vm: &Thread) -> vm::Result<ExternModule> {
     let module = record! {