@@ -122,34 +122,38 @@ func runCfg(n *node, f *frame) {
122122}
123123
124124func typeAssertStatus (n * node ) {
125- c0 , c1 := n .child [0 ], n .child [1 ]
125+ c0 , c1 := n .child [0 ], n .child [1 ] // cO contains the input value, c1 the type to assert
126126 value := genValue (c0 ) // input value
127127 value1 := genValue (n .anc .child [1 ]) // returned status
128- typ := c1 .typ .rtype // type to assert
129128 next := getExec (n .tnext )
130129
131130 switch {
132- case c0 .typ .cat == valueT :
131+ case isInterfaceSrc (c1 .typ ):
132+ typ := c1 .typ
133+ n .exec = func (f * frame ) bltn {
134+ v , ok := value (f ).Interface ().(valueInterface )
135+ value1 (f ).SetBool (ok && v .node .typ .implements (typ ))
136+ return next
137+ }
138+ case isInterface (c1 .typ ):
139+ rtype := c1 .typ .rtype
133140 n .exec = func (f * frame ) bltn {
134141 v := value (f )
135- if ! v .IsValid () || v .IsNil () {
136- value1 (f ).SetBool (false )
137- }
138- value1 (f ).SetBool (v .Type ().Implements (typ ))
142+ value1 (f ).SetBool (v .IsValid () && v .Type ().Implements (rtype ))
139143 return next
140144 }
141- case c1 .typ .cat == interfaceT :
145+ case c0 .typ .cat == valueT :
146+ rtype := c1 .typ .rtype
142147 n .exec = func (f * frame ) bltn {
143- _ , ok := value (f ).Interface ().(valueInterface )
144- // TODO: verify that value(f) implements asserted type.
145- value1 (f ).SetBool (ok )
148+ v := value (f )
149+ value1 (f ).SetBool (v .IsValid () && v .Type () == rtype )
146150 return next
147151 }
148152 default :
153+ typID := c1 .typ .id ()
149154 n .exec = func (f * frame ) bltn {
150- _ , ok := value (f ).Interface ().(valueInterface )
151- // TODO: verify that value(f) implements asserted type.
152- value1 (f ).SetBool (ok )
155+ v , ok := value (f ).Interface ().(valueInterface )
156+ value1 (f ).SetBool (ok && v .node .typ .id () == typID )
153157 return next
154158 }
155159 }
@@ -162,24 +166,35 @@ func typeAssert(n *node) {
162166 next := getExec (n .tnext )
163167
164168 switch {
165- case c0 .typ .cat == valueT :
169+ case isInterfaceSrc (c1 .typ ):
170+ typ := n .child [1 ].typ
171+ typID := n .child [1 ].typ .id ()
166172 n .exec = func (f * frame ) bltn {
167173 v := value (f )
168- dest (f ).Set (v .Elem ())
174+ vi , ok := v .Interface ().(valueInterface )
175+ if ! ok {
176+ panic (n .cfgErrorf ("interface conversion: nil is not %v" , typID ))
177+ }
178+ if ! vi .node .typ .implements (typ ) {
179+ panic (n .cfgErrorf ("interface conversion: %v is not %v" , vi .node .typ .id (), typID ))
180+ }
181+ dest (f ).Set (v )
169182 return next
170183 }
171- case c1 .typ .cat == interfaceT :
184+ case isInterface (c1 .typ ):
185+ rtype := n .child [1 ].typ .rtype
186+ n .exec = func (f * frame ) bltn {
187+ dest (f ).Set (value (f ).Convert (rtype ))
188+ return next
189+ }
190+ case c0 .typ .cat == valueT :
172191 n .exec = func (f * frame ) bltn {
173- v := value (f ).Interface ().(valueInterface )
174- // TODO: verify that value(f) implements asserted type.
175- dest (f ).Set (reflect .ValueOf (valueInterface {v .node , v .value }))
192+ dest (f ).Set (value (f ).Elem ())
176193 return next
177194 }
178195 default :
179196 n .exec = func (f * frame ) bltn {
180- v := value (f ).Interface ().(valueInterface )
181- // TODO: verify that value(f) implements asserted type.
182- dest (f ).Set (v .value )
197+ dest (f ).Set (value (f ).Interface ().(valueInterface ).value )
183198 return next
184199 }
185200 }
@@ -189,30 +204,58 @@ func typeAssert2(n *node) {
189204 value := genValue (n .child [0 ]) // input value
190205 value0 := genValue (n .anc .child [0 ]) // returned result
191206 value1 := genValue (n .anc .child [1 ]) // returned status
207+ typ := n .child [1 ].typ // type to assert or convert to
208+ typID := typ .id ()
192209 next := getExec (n .tnext )
193210
194211 switch {
195- case n . child [ 0 ]. typ . cat == valueT :
212+ case isInterfaceSrc ( typ ) :
196213 n .exec = func (f * frame ) bltn {
197- if value (f ).IsValid () && ! value (f ).IsNil () {
198- value0 (f ).Set (value (f ).Elem ())
214+ v , ok := value (f ).Interface ().(valueInterface )
215+ if ok && v .node .typ .id () == typID {
216+ value0 (f ).Set (value (f ))
217+ } else {
218+ ok = false
199219 }
200- value1 (f ).SetBool (true )
220+ value1 (f ).SetBool (ok )
201221 return next
202222 }
203- case n .child [1 ].typ .cat == interfaceT :
223+ case isInterface (typ ):
224+ rtype := typ .rtype
204225 n .exec = func (f * frame ) bltn {
205- v , ok := value (f ).Interface ().(valueInterface )
206- // TODO: verify that value(f) implements asserted type.
207- value0 (f ).Set (reflect .ValueOf (valueInterface {v .node , v .value }))
226+ v := value (f )
227+ ok := v .IsValid () && v .Type ().Implements (rtype )
228+ if ok {
229+ value0 (f ).Set (v .Convert (rtype ))
230+ }
231+ value1 (f ).SetBool (ok )
232+ return next
233+ }
234+ case n .child [0 ].typ .cat == valueT :
235+ rtype := n .child [1 ].typ .rtype
236+ n .exec = func (f * frame ) bltn {
237+ v := value (f )
238+ ok := v .IsValid () && ! value (f ).IsNil ()
239+ if ok {
240+ if e := v .Elem (); e .Type () == rtype {
241+ value0 (f ).Set (e )
242+ } else {
243+ ok = false
244+ }
245+ }
208246 value1 (f ).SetBool (ok )
209247 return next
210248 }
211249 default :
212250 n .exec = func (f * frame ) bltn {
213251 v , ok := value (f ).Interface ().(valueInterface )
214- // TODO: verify that value(f) implements asserted type.
215- value0 (f ).Set (v .value )
252+ if ok {
253+ if v .node .typ .id () == typID {
254+ value0 (f ).Set (v .value )
255+ } else {
256+ ok = false
257+ }
258+ }
216259 value1 (f ).SetBool (ok )
217260 return next
218261 }
0 commit comments