vyperlang / vyper

Pythonic Smart Contract Language for the EVM
https://vyperlang.org
Other
4.91k stars 802 forks source link

`AttributeError` when using types as argument #3246

Open trocher opened 1 year ago

trocher commented 1 year ago

Version Information

What's your issue about?

The compiler outputs an AttributeError when trying to use a type as an argument to a function for the following types while it would return a InvalidReference for other types:

For example:

@internal
def bar(a:uint256):
    pass

@external
def foo():
    self.bar(String[5])
Error compiling: tests/customs/code.vy
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/bin/vyper", line 8, in <module>
    sys.exit(_parse_cli_args())
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 57, in _parse_cli_args
    return _parse_args(sys.argv[1:])
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 154, in _parse_args
    compiled = compile_files(
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 294, in compile_files
    compiler_data = vyper.compile_codes(
  File "/Users/trocher/Documents/thesis/vyper/vyper/evm/opcodes.py", line 226, in _wrapper
    return fn(*args, **kwargs)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/__init__.py", line 141, in compile_codes
    exc_handler(contract_name, exc)
  File "/Users/trocher/Documents/thesis/vyper/vyper/cli/vyper_compile.py", line 189, in exc_handler
    raise exception
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/__init__.py", line 138, in compile_codes
    out[contract_name][output_format] = OUTPUT_FORMATS[output_format](compiler_data)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/output.py", line 248, in build_bytecode_output
    return f"0x{compiler_data.bytecode.hex()}"
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/functools.py", line 966, in __get__
    val = self.func(instance)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 150, in bytecode
    self.assembly, is_runtime=False, no_bytecode_metadata=self.no_bytecode_metadata
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/functools.py", line 966, in __get__
    val = self.func(instance)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 141, in assembly
    return generate_assembly(self.ir_nodes, self.no_optimize)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 126, in ir_nodes
    ir, ir_runtime, sigs = self._ir_output
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/functools.py", line 966, in __get__
    val = self.func(instance)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 122, in _ir_output
    return generate_ir_nodes(self.global_ctx, self.no_optimize)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 117, in global_ctx
    return GlobalContext(self.vyper_module_folded)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 107, in vyper_module_folded
    module, storage_layout = self._folded_module
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/functools.py", line 966, in __get__
    val = self.func(instance)
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 101, in _folded_module
    return generate_folded_ast(
  File "/Users/trocher/Documents/thesis/vyper/vyper/compiler/phases.py", line 229, in generate_folded_ast
    validate_semantics(vyper_module_folded, interface_codes)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/__init__.py", line 13, in validate_semantics
    validate_functions(vyper_ast)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 59, in validate_functions
    FunctionNodeVisitor(vy_module, node, namespace)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 179, in __init__
    self.visit(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 222, in visit
    super().visit(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/common.py", line 20, in visit
    visitor_fn(node, *args)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/local.py", line 508, in visit_Expr
    return_value = fn_type.fetch_call_return(node.value)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/types/function.py", line 475, in fetch_call_return
    validate_expected_type(arg, expected)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/utils.py", line 492, in validate_expected_type
    given_types = _ExprAnalyser().get_possible_types_from_node(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/utils.py", line 143, in get_possible_types_from_node
    ret = fn(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/utils.py", line 338, in types_from_Subscript
    t = self.get_exact_type_from_node(node.value)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/utils.py", line 116, in get_exact_type_from_node
    types_list = self.get_possible_types_from_node(node, include_type_exprs=include_type_exprs)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/utils.py", line 143, in get_possible_types_from_node
    ret = fn(node)
  File "/Users/trocher/Documents/thesis/vyper/vyper/semantics/analysis/utils.py", line 324, in types_from_Name
    return [t.typ]
AttributeError: type object 'StringT' has no attribute 'typ'

How can it be fixed?

This seems to happen when trying to get the type of the value of the Subscript representing the type. The isinstance test shown below returns False as t is not an instance of VyperType but a class inheriting it (In the case above: <class 'vyper.semantics.types.bytestrings.StringT'>.

https://github.com/vyperlang/vyper/blob/02339dfda0f3caabad142060d511d10bfe93c520/vyper/semantics/analysis/utils.py#L314-L322

cyberthirst commented 2 weeks ago

for 0abcf452b29f5348cb14233fd9a8444224392184

we have this related poc:

def foo(b: Bytes[32], s: String[32]):  
    String[64] = concat(s, b)
AttributeError: type object 'StringT' has no attribute 'typ'

During handling of the above exception, another exception occurred:

vyper.exceptions.CompilerPanic: unhandled exception type object 'StringT' has no attribute 'typ'

  contract "tests/custom/test4.vy:2", function "foo", line 2:4 
       1 def foo(b: Bytes[32], s: String[32]):
  ---> 2     String[64] = concat(s, b)
  -----------^

This is an unhandled internal compiler error. Please create an issue on Github to notify the developers!
https://github.com/vyperlang/vyper/issues/new?template=bug.md