+ ILGenerator ig = ec.ig;
+ Label is_null_label = ig.DefineLabel ();
+ Label end_label = ig.DefineLabel ();
+
+ unwrap.EmitCheck (ec);
+ ig.Emit (OpCodes.Brfalse, is_null_label);
+
+ NullableInfo ni = new NullableInfo (type);
+
+ if (user_operator != null) {
+ user_operator.Emit (ec);
+ } else {
+ EmitOperator (ec, ni.UnderlyingType);
+ }
+
+ ig.Emit (OpCodes.Newobj, ni.Constructor);
+ ig.Emit (OpCodes.Br_S, end_label);
+
+ ig.MarkLabel (is_null_label);
+ LiftedNull.Create (type, loc).Emit (ec);
+
+ ig.MarkLabel (end_label);
+ }
+
+ Expression LiftExpression (EmitContext ec, Expression expr)
+ {
+ TypeExpr lifted_type = new NullableType (expr.Type, expr.Location);
+ lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
+ if (lifted_type == null)
+ return null;
+
+ expr.Type = lifted_type.Type;
+ return expr;
+ }
+
+ protected override Expression ResolveEnumOperator (EmitContext ec, Expression expr)
+ {
+ expr = base.ResolveEnumOperator (ec, expr);
+ if (expr == null)
+ return null;
+
+ Expr = LiftExpression (ec, Expr);
+ return LiftExpression (ec, expr);
+ }
+
+ protected override Expression ResolveUserOperator (EmitContext ec, Expression expr)
+ {
+ expr = base.ResolveUserOperator (ec, expr);
+ if (expr == null)
+ return null;
+
+ //
+ // When a user operator is of non-nullable type
+ //
+ if (Expr is Unwrap) {
+ user_operator = LiftExpression (ec, expr);
+ return user_operator;
+ }
+
+ return expr;