diff --git a/spec/Candid.md b/spec/Candid.md index 72f0c4d3..29859d7e 100644 --- a/spec/Candid.md +++ b/spec/Candid.md @@ -791,7 +791,7 @@ not ( <: opt ) --------------------------------- opt <: opt -not (null <: ) +not (null <: ) not ( <: ) --------------------------------- opt <: opt @@ -915,7 +915,7 @@ C[vec <: vec ]( vec { ;* } ) = vec { C[ <: ]();* } #### Options -The null type coerces into any option type: +The null type and the reserved type coerce into any option type: ``` C[null <: opt ](null) = null ``` @@ -927,15 +927,20 @@ C[opt <: opt ](opt ) = opt C[ <: ](v) if <: C[opt <: opt ](opt ) = null if not( <: ) ``` -NOTE: These rules above imply that a Candid decoder has to be able to decide the subtyping relation at runtime. +Coercing a non-null, non-optional and non-reserved type at an option type treats it as an optional value, if it has a suitable type: +``` +C[ <: opt ]() = opt C[ <: ](v) if not (null <: ) and <: +``` -Coercing a non-null, non-optional and non-reserved value at an option type treats it as an optional value: +Any other type goes to `null`: ``` -C[ <: opt ]() = opt C[ <: ](v) if not (null <: ) and <: -C[ <: opt ](_) = null if not (null <: ) and not ( <: ) -C[reserved <: opt ](_) = null +C[reserved <: opt ](_) = null +C[ <: opt ](_) = null if not (null <: ) and not ( <: ) +C[ <: opt ](_) = null if null <: and not (null <: ) ``` +NOTE: These rules above imply that a Candid decoder has to be able to decide the subtyping relation at runtime. + #### Records In the following rule: