diff options
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/basic-types/floats-boxed-cast.vala | 7 | ||||
-rw-r--r-- | tests/generics/floating-type-cast.vala | 9 | ||||
-rw-r--r-- | vala/valacastexpression.vala | 22 |
4 files changed, 40 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 7a99b0af2..160d77169 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -24,6 +24,7 @@ TESTS = \ basic-types/integers.vala \ basic-types/escape-chars.vala \ basic-types/floats.vala \ + basic-types/floats-boxed-cast.vala \ basic-types/boolean.vala \ basic-types/custom-types.vala \ basic-types/default-gtype.vala \ @@ -570,6 +571,7 @@ TESTS = \ asynchronous/yield.vala \ generics/arrays-not-supported.test \ generics/constructor-chain-up.vala \ + generics/floating-type-cast.vala \ generics/inference-argument-may-fail.vala \ generics/inference-static-function.vala \ generics/parameter-sizeof-initializer.vala \ diff --git a/tests/basic-types/floats-boxed-cast.vala b/tests/basic-types/floats-boxed-cast.vala new file mode 100644 index 000000000..86e9f52cf --- /dev/null +++ b/tests/basic-types/floats-boxed-cast.vala @@ -0,0 +1,7 @@ +void main () { + var f = (float?) 23.0f; + assert (f == 23.0f); + + var d = (double?) 42.0; + assert (d == 42.0); +} diff --git a/tests/generics/floating-type-cast.vala b/tests/generics/floating-type-cast.vala new file mode 100644 index 000000000..9475a4219 --- /dev/null +++ b/tests/generics/floating-type-cast.vala @@ -0,0 +1,9 @@ +void foo<G,T> (G g, T t) { + assert ((float?) g == 23.0f); + assert ((double?) t == 42.0); +} + +void main () { + foo ((float?) 23.0f, (double?) 42.0); + foo<float?,double?> ((float?) 23.0f, (double?) 42.0); +} diff --git a/vala/valacastexpression.vala b/vala/valacastexpression.vala index d51b4e205..5dc60c726 100644 --- a/vala/valacastexpression.vala +++ b/vala/valacastexpression.vala @@ -172,6 +172,28 @@ public class Vala.CastExpression : Expression { } } + // Implicit transformation of stack-allocated value to heap-allocated boxed-type + if (!(is_silent_cast || is_non_null_cast) + && (type_reference is ValueType && type_reference.nullable) + && !inner.value_type.nullable + && inner.value_type is FloatingType) { + var local = new LocalVariable (type_reference, get_temp_name (), null, inner.source_reference); + var decl = new DeclarationStatement (local, source_reference); + + insert_statement (context.analyzer.insert_block, decl); + + var temp_access = SemanticAnalyzer.create_temp_access (local, target_type); + temp_access.formal_target_type = formal_target_type; + + // don't set initializer earlier as this changes parent_node and parent_statement + local.initializer = inner; + decl.check (context); + + context.analyzer.replaced_nodes.add (this); + parent_node.replace_expression (this, temp_access); + return temp_access.check (context); + } + value_type = type_reference; value_type.value_owned = inner.value_type.value_owned; value_type.floating_reference = inner.value_type.floating_reference; |