HaxeFoundation / HaxeFoundation/haxe
Add @:forward.is meta to abstracts
- Dominant language
- Haxe
- Stars
- 6.9k
- Forks
- 715
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 11
Description
The follows results in a compile error: Cannot use abstract as value
```hx
class Test {
static function main() {
final foo:Foo = cast "5";
if (foo is Foo)
trace("ok");
}
}
// @:forward.is
abstract Foo(String) {}
```
I suggest adding the meta `@:forward.is` which allows this. In my opinion, it will be clear that abstracts using this will simply cause `is` checks to become `foo is String`, and will not be a way to discern `Foo` instances from strings at runtime. I also think this behavior should be opt-in to avoid such a confusion, and perhaps the error message should be updated to mention this meta.
## Inb4 "There's a macro for that"
Way ahead of you, courtesy of @filt3rek
```hx
import haxe.macro.Context;
import haxe.macro.Expr;
using haxe.macro.Tools;
class Macro {
public macro static function _is(e:Expr, te:Expr) {
var t = Context.toComplexType(Context.followWithAbstracts(Context.getType(te.toString())));
return macro $e is $t;
}
}
```
usage:
```hx
using Macro;
class Test {
static function main() {
final foo:Foo = cast "5";
if (foo._is(Foo))
trace("ok");
}
}
abstract Foo(String) {}
```
Contributor guide
Research direction
Start by compiling the provided Test/Foo reproducer and trace how the compiler handles `is` checks on abstracts. Review the relevant abstract and type-checking paths, then verify that `@:forward.is` enables the proposed check while preserving the documented distinction from runtime abstract instances.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100