Skip to content

Commit c313ab8

Browse files
bors[bot]Marwes
andauthored
Merge #874
874: fix: Prevent zero-argument functions from being created in Rust r=Marwes a=Marwes These cannot be called from the gluon side, instead a one argument function that takes `()` should be used. bors r+ Fixes #873 Co-authored-by: Markus Westerlind <[email protected]>
2 parents 0c26cee + 7ef0eb2 commit c313ab8

File tree

5 files changed

+86
-50
lines changed

5 files changed

+86
-50
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ branches:
1818

1919
matrix:
2020
include:
21-
- rust: nightly-2020-07-26
21+
- rust: nightly-2020-09-12
2222
# - rust: beta
2323
- rust: stable
2424
env: ARCH=i686
@@ -29,7 +29,7 @@ matrix:
2929
- PUBLISH=1
3030
- TARGET=x86_64-unknown-linux-gnu
3131

32-
- rust: nightly-2020-03-12
32+
- rust: nightly-2020-09-12
3333
env: WASM=1
3434

3535
# Only for deployment

base/src/types/mod.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3230,7 +3230,7 @@ where
32303230
type Context = NullInterner;
32313231

32323232
fn context(&mut self) -> &mut Self::Context {
3233-
&mut NullInterner
3233+
NullInterner::new()
32343234
}
32353235

32363236
fn visit(&mut self, typ: &T) -> Option<T>
@@ -3818,13 +3818,15 @@ where
38183818

38193819
pub type SharedInterner<Id, T> = TypeCache<Id, T>;
38203820

3821-
pub struct NullInternerInner;
3822-
// Workaround since &mut NullInterner does not get promoted to a `&'static mut NullInterner` but
3823-
// `&mut []` does
3824-
pub type NullInterner = [NullInternerInner; 0];
3821+
#[derive(Default)]
3822+
pub struct NullInterner;
38253823

3826-
#[allow(non_upper_case_globals)]
3827-
pub const NullInterner: NullInterner = [];
3824+
impl NullInterner {
3825+
pub fn new() -> &'static mut NullInterner {
3826+
// SAFETY NullInterner is zero-sized
3827+
unsafe { &mut *(&mut NullInterner as *mut _) }
3828+
}
3829+
}
38283830

38293831
impl<Id, T> TypeContext<Id, T> for NullInterner
38303832
where
@@ -4269,7 +4271,7 @@ where
42694271
type Context = NullInterner;
42704272

42714273
fn context(&mut self) -> &mut Self::Context {
4272-
&mut NullInterner
4274+
NullInterner::new()
42734275
}
42744276

42754277
fn visit(&mut self, typ: &T) -> Option<T>
@@ -4306,7 +4308,7 @@ where
43064308
type Context = NullInterner;
43074309

43084310
fn context(&mut self) -> &mut Self::Context {
4309-
&mut NullInterner
4311+
NullInterner::new()
43104312
}
43114313

43124314
fn visit(&mut self, typ: &T) -> Option<T>

completion/src/lib.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ where
152152
self.stack.insert(id.name.clone(), id.typ.clone());
153153
}
154154
Pattern::Record { typ, fields, .. } => {
155-
let unaliased = resolve::remove_aliases(&self.env, &mut NullInterner, typ.clone());
155+
let unaliased =
156+
resolve::remove_aliases(&self.env, NullInterner::new(), typ.clone());
156157
for field in &**fields {
157158
match field {
158159
PatternField::Type { name } => {
@@ -359,7 +360,7 @@ where
359360
if ident.span.containment(self.pos) == Ordering::Equal {
360361
let record_type = resolve::remove_aliases(
361362
&crate::base::ast::EmptyEnv::default(),
362-
&mut NullInterner,
363+
NullInterner::new(),
363364
record_type.clone(),
364365
);
365366
let either = record_type
@@ -1303,7 +1304,7 @@ impl SuggestionQuery {
13031304
Pattern::Constructor(ref id, _) | Pattern::Ident(ref id) => id.as_ref(),
13041305
Pattern::Record { ref fields, .. } => {
13051306
if let Ok(typ) = expr.try_type_of(&env) {
1306-
let typ = resolve::remove_aliases(env, &mut NullInterner, typ);
1307+
let typ = resolve::remove_aliases(env, NullInterner::new(), typ);
13071308
self.suggest_fields_of_type(&mut result, fields, "", &typ);
13081309
}
13091310
""
@@ -1325,7 +1326,7 @@ impl SuggestionQuery {
13251326
Match::Expr(context) => match context.value {
13261327
Expr::Projection(ref expr, _, _) => {
13271328
if let Ok(typ) = expr.try_type_of(&env) {
1328-
let typ = resolve::remove_aliases(&env, &mut NullInterner, typ);
1329+
let typ = resolve::remove_aliases(&env, NullInterner::new(), typ);
13291330
let id = ident.as_ref();
13301331

13311332
let iter = typ
@@ -1368,7 +1369,7 @@ impl SuggestionQuery {
13681369
},
13691370
..
13701371
}) => {
1371-
let typ = resolve::remove_aliases_cow(env, &mut NullInterner, typ);
1372+
let typ = resolve::remove_aliases_cow(env, NullInterner::new(), typ);
13721373
self.suggest_fields_of_type(
13731374
&mut result,
13741375
fields,
@@ -1409,7 +1410,7 @@ impl SuggestionQuery {
14091410
Match::Pattern(pattern) => match pattern.value {
14101411
Pattern::Record { ref fields, .. } => {
14111412
if let Ok(typ) = pattern.try_type_of(env) {
1412-
let typ = resolve::remove_aliases(env, &mut NullInterner, typ);
1413+
let typ = resolve::remove_aliases(env, NullInterner::new(), typ);
14131414
self.suggest_fields_of_type(&mut result, fields, "", &typ);
14141415
}
14151416
}

tests/compile-fail/run_expr_str_ref.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ fn main() {
66
let vm = new_vm();
77

88
let _ = vm.run_expr::<&str>("", r#" "test" "#);
9-
//~^ the trait bound `for<'value> &str: gluon::gluon_vm::api::Getable<'_, 'value>` is not satisfied [E0277]
9+
//~^ the trait bound `for<'value> &str: Getable<'_, 'value>` is not satisfied [E0277]
1010
}

vm/src/api/function.rs

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,14 @@ where
270270
}
271271

272272
macro_rules! vm_function_impl {
273-
([$($f:tt)*] $($args:ident),*) => {
273+
([$($f:tt)*] $($args:ident),* -> $ret: ident, $ret_ty: ty) => {
274274

275-
impl <'vm, $($args,)* R> VmFunction<'vm> for $($f)* ($($args),*) -> R
275+
impl <'vm, $($args,)* $ret> VmFunction<'vm> for $($f)* ($($args),*) -> $ret_ty
276276
where $($args: Getable<'vm, 'vm> + 'vm,)*
277-
R: AsyncPushable<'vm> + VmType + 'vm
277+
$ret: AsyncPushable<'vm> + VmType + 'vm,
278+
$ret_ty: AsyncPushable<'vm> + VmType + 'vm,
279+
$ret::Type: Sized,
280+
<$ret_ty as VmType>::Type: Sized,
278281
{
279282
#[allow(non_snake_case, unused_mut, unused_assignments, unused_variables, unused_unsafe)]
280283
fn unpack_and_call(&self, vm: &'vm Thread) -> Status {
@@ -341,49 +344,76 @@ where
341344
}
342345

343346
macro_rules! make_vm_function {
344-
($($args:ident),*) => (
345-
impl <$($args: VmType,)* R: VmType> VmType for fn ($($args),*) -> R {
347+
($($args:ident),*) => {
348+
make_vm_function_inner!($($args),* -> R, R);
349+
}
350+
}
351+
macro_rules! make_vm_function_inner {
352+
($($args:ident),* -> $ret: ident, $ret_ty: ty) => (
353+
impl <$($args: VmType,)* $ret: VmType> VmType for fn ($($args),*) -> $ret_ty
354+
where
355+
<$ret_ty as VmType>::Type: Sized,
356+
<$ret as VmType>::Type: Sized,
357+
{
346358
#[allow(non_snake_case)]
347-
type Type = fn ($($args::Type),*) -> R::Type;
359+
type Type = fn ($($args::Type),*) -> <$ret_ty as VmType>::Type;
348360

349361
#[allow(non_snake_case)]
350362
fn make_type(vm: &Thread) -> ArcType {
351363
let args = vec![$(make_type::<$args>(vm)),*];
352-
vm.global_env().type_cache().function(args, make_type::<R>(vm))
364+
vm.global_env().type_cache().function(args, make_type::<$ret_ty>(vm))
353365
}
354366
}
355367

356-
vm_function_impl!([fn] $($args),*);
357-
vm_function_impl!([dyn Fn] $($args),*);
368+
vm_function_impl!([fn] $($args),* -> $ret, $ret_ty);
369+
vm_function_impl!([dyn Fn] $($args),* -> $ret, $ret_ty);
358370

359-
impl <'vm, $($args,)* R: VmType> FunctionType for fn ($($args),*) -> R {
371+
impl <'vm, $($args,)* $ret: VmType> FunctionType for fn ($($args),*) -> $ret_ty
372+
where
373+
$ret_ty: VmType,
374+
<$ret_ty as VmType>::Type: Sized,
375+
$ret::Type: Sized,
376+
{
360377
fn arguments() -> VmIndex {
361-
count!($($args),*) + R::EXTRA_ARGS
378+
count!($($args),*) + <$ret_ty as VmType>::EXTRA_ARGS
362379
}
363380
}
364381

365-
impl <'s, $($args,)* R: VmType> FunctionType for dyn Fn($($args),*) -> R + 's {
382+
impl <'s, $($args,)* $ret: VmType> FunctionType for dyn Fn($($args),*) -> $ret_ty + 's
383+
where
384+
$ret_ty: VmType,
385+
<$ret_ty as VmType>::Type: Sized,
386+
$ret::Type: Sized,
387+
{
366388
fn arguments() -> VmIndex {
367-
count!($($args),*) + R::EXTRA_ARGS
389+
count!($($args),*) + <$ret_ty as VmType>::EXTRA_ARGS
368390
}
369391
}
370392

371-
impl <'s, $($args: VmType,)* R: VmType> VmType for dyn Fn($($args),*) -> R + 's {
372-
type Type = fn ($($args::Type),*) -> R::Type;
393+
impl <'s, $($args: VmType,)* $ret: VmType> VmType for dyn Fn($($args),*) -> $ret_ty + 's
394+
where
395+
$ret_ty: VmType,
396+
<$ret_ty as VmType>::Type: Sized,
397+
$ret::Type: Sized,
398+
{
399+
type Type = fn ($($args::Type),*) -> <$ret_ty as VmType>::Type;
373400

374401
#[allow(non_snake_case)]
375402
fn make_type(vm: &Thread) -> ArcType {
376-
<fn ($($args),*) -> R>::make_type(vm)
403+
<fn ($($args),*) -> $ret_ty>::make_type(vm)
377404
}
378405
}
379406

380-
impl<T, $($args,)* R> Function<T, fn($($args),*) -> R>
381-
where $($args: for<'vm> Pushable<'vm>,)*
382-
T: VmRootInternal,
383-
R: VmType + for<'x, 'value> Getable<'x, 'value>,
407+
impl<T, $($args,)* $ret> Function<T, fn($($args),*) -> $ret_ty>
408+
where
409+
$($args: for<'vm> Pushable<'vm>,)*
410+
T: VmRootInternal,
411+
$ret: VmType + for<'x, 'value> Getable<'x, 'value>,
412+
<$ret_ty as VmType>::Type: Sized,
413+
$ret::Type: Sized,
384414
{
385415
#[allow(non_snake_case)]
386-
pub fn call(&mut self $(, $args: $args)*) -> Result<R> {
416+
pub fn call(&mut self $(, $args: $args)*) -> Result<$ret_ty> {
387417
block_on_sync(future::lazy(|cx| {
388418
match self.call_first(cx, $($args),*) {
389419
Poll::Ready(r) => r,
@@ -393,17 +423,17 @@ impl<T, $($args,)* R> Function<T, fn($($args),*) -> R>
393423
}
394424

395425
#[allow(non_snake_case)]
396-
fn call_first(&self, cx: &mut task::Context<'_> $(, $args: $args)*) -> Poll<Result<R>> {
426+
fn call_first(&self, cx: &mut task::Context<'_> $(, $args: $args)*) -> Poll<Result<$ret_ty>> {
397427
let vm = self.value.vm();
398428
let mut context = vm.current_context();
399429
context.push(self.value.get_variant());
400430
$(
401431
$args.vm_push(&mut context)?;
402432
)*
403-
for _ in 0..R::EXTRA_ARGS {
433+
for _ in 0..<$ret_ty as VmType>::EXTRA_ARGS {
404434
0.vm_push(&mut context).unwrap();
405435
}
406-
let args = count!($($args),*) + R::EXTRA_ARGS;
436+
let args = count!($($args),*) + <$ret_ty as VmType>::EXTRA_ARGS;
407437
let context = ready!(vm.call_function(cx, context.into_owned(), args))?;
408438
let mut context = context.unwrap();
409439
let result = {
@@ -414,21 +444,24 @@ impl<T, $($args,)* R> Function<T, fn($($args),*) -> R>
414444
Poll::Ready(result)
415445
}
416446

417-
fn return_value(vm: &Thread, value: Variants) -> Result<R> {
418-
Ok(R::from_value(vm, value))
447+
fn return_value(vm: &Thread, value: Variants) -> Result<$ret_ty> {
448+
Ok(<$ret_ty>::from_value(vm, value))
419449
}
420450
}
421451

422-
impl<T, $($args,)* R> Function<T, fn($($args),*) -> R>
423-
where $($args: for<'vm> Pushable<'vm>,)*
424-
T: VmRootInternal + Clone + Send,
425-
R: VmType + for<'x, 'value> Getable<'x, 'value> + Send + Sync + 'static,
452+
impl<T, $($args,)* $ret> Function<T, fn($($args),*) -> $ret_ty>
453+
where
454+
$($args: for<'vm> Pushable<'vm>,)*
455+
T: VmRootInternal + Clone + Send,
456+
$ret: VmType + for<'x, 'value> Getable<'x, 'value> + Send + Sync + 'static,
457+
<$ret_ty as VmType>::Type: Sized,
458+
$ret::Type: Sized,
426459
{
427460
#[allow(non_snake_case)]
428461
pub async fn call_async(
429462
&mut self
430463
$(, $args: $args)*
431-
) -> Result<R>
464+
) -> Result<$ret_ty>
432465
{
433466
use crate::thread::Execute;
434467
match future::lazy(|cx| self.call_first(cx, $($args),*)).await {
@@ -444,7 +477,7 @@ impl<T, $($args,)* R> Function<T, fn($($args),*) -> R>
444477
)
445478
}
446479

447-
make_vm_function!();
480+
make_vm_function_inner!( -> R, crate::api::IO<R>);
448481
make_vm_function!(A);
449482
make_vm_function!(A, B);
450483
make_vm_function!(A, B, C);

0 commit comments

Comments
 (0)