Emit type arguments to builder methods that need it.
Use the inferred type variables to construct a type argument for builder methods. This is for those instructions where the result types cannot be computed from the result types.
This commit is contained in:
@@ -9,7 +9,7 @@ from . import instructions
|
|||||||
from .typevar import TypeVar
|
from .typevar import TypeVar
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from typing import Union, Tuple # noqa
|
from typing import Union, Tuple, Sequence # noqa
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -389,12 +389,18 @@ class Apply(Expr):
|
|||||||
args = ', '.join(map(str, self.args))
|
args = ', '.join(map(str, self.args))
|
||||||
return '{}({})'.format(self.instname(), args)
|
return '{}({})'.format(self.instname(), args)
|
||||||
|
|
||||||
def rust_builder(self):
|
def rust_builder(self, defs=None):
|
||||||
# type: () -> str
|
# type: (Sequence[Var]) -> str
|
||||||
"""
|
"""
|
||||||
Return a Rust Builder method call for instantiating this instruction
|
Return a Rust Builder method call for instantiating this instruction
|
||||||
application.
|
application.
|
||||||
|
|
||||||
|
The `defs` argument should be a list of variables defined by this
|
||||||
|
instruction. It is used to construct a result type if necessary.
|
||||||
"""
|
"""
|
||||||
args = ', '.join(map(str, self.args))
|
args = ', '.join(map(str, self.args))
|
||||||
|
# Do we need to pass an explicit type argument?
|
||||||
|
if self.inst.is_polymorphic and not self.inst.use_typevar_operand:
|
||||||
|
args = defs[0].rust_type() + ', ' + args
|
||||||
method = self.inst.snake_name()
|
method = self.inst.snake_name()
|
||||||
return '{}({})'.format(method, args)
|
return '{}({})'.format(method, args)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ the input instruction.
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from srcgen import Formatter
|
from srcgen import Formatter
|
||||||
from base import legalize
|
from base import legalize
|
||||||
|
from cdsl.ast import Var
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from typing import Sequence # noqa
|
from typing import Sequence # noqa
|
||||||
@@ -72,6 +73,12 @@ def unwrap_inst(iref, node, fmt):
|
|||||||
fmt.outdented_line('} else {')
|
fmt.outdented_line('} else {')
|
||||||
fmt.line('unreachable!("bad instruction format")')
|
fmt.line('unreachable!("bad instruction format")')
|
||||||
|
|
||||||
|
# Get the types of any variables where it is needed.
|
||||||
|
for i in iform.value_operands:
|
||||||
|
v = expr.args[i]
|
||||||
|
if isinstance(v, Var) and v.has_free_typevar():
|
||||||
|
fmt.line('let typeof_{0} = dfg.value_type({0});'.format(v))
|
||||||
|
|
||||||
# If the node has multiple results, detach the values.
|
# If the node has multiple results, detach the values.
|
||||||
# Place the secondary values in 'src_{}' locals.
|
# Place the secondary values in 'src_{}' locals.
|
||||||
if len(node.defs) > 1:
|
if len(node.defs) > 1:
|
||||||
@@ -91,6 +98,11 @@ def unwrap_inst(iref, node, fmt):
|
|||||||
for d in node.defs[1:]:
|
for d in node.defs[1:]:
|
||||||
fmt.line('src_{} = vals.next().unwrap();'.format(d))
|
fmt.line('src_{} = vals.next().unwrap();'.format(d))
|
||||||
fmt.line('assert_eq!(vals.next(), None);')
|
fmt.line('assert_eq!(vals.next(), None);')
|
||||||
|
for d in node.defs[1:]:
|
||||||
|
if d.has_free_typevar():
|
||||||
|
fmt.line(
|
||||||
|
'let typeof_{0} = dfg.value_type(src_{0});'
|
||||||
|
.format(d))
|
||||||
|
|
||||||
|
|
||||||
def wrap_tup(seq):
|
def wrap_tup(seq):
|
||||||
@@ -128,7 +140,7 @@ def emit_dst_inst(node, fmt):
|
|||||||
builder = 'let {} = dfg.ins(pos)'.format(wrap_tup(node.defs))
|
builder = 'let {} = dfg.ins(pos)'.format(wrap_tup(node.defs))
|
||||||
fixup_first_result = node.defs[0].is_output()
|
fixup_first_result = node.defs[0].is_output()
|
||||||
|
|
||||||
fmt.line('{}.{};'.format(builder, node.expr.rust_builder()))
|
fmt.line('{}.{};'.format(builder, node.expr.rust_builder(node.defs)))
|
||||||
|
|
||||||
# If we just replaced an instruction, we need to bump the cursor so
|
# If we just replaced an instruction, we need to bump the cursor so
|
||||||
# following instructions are inserted *after* the replaced insruction.
|
# following instructions are inserted *after* the replaced insruction.
|
||||||
|
|||||||
Reference in New Issue
Block a user