use crate::convert_parse_tree_error::ConvertParseTreeError;
use crate::lex_error::LexError;
use crate::parser_error::ParseError;
use crate::type_error::TypeError;
use core::fmt;
use std::path::PathBuf;
use std::sync::Arc;
use sway_types::constants::STORAGE_PURITY_ATTRIBUTE_NAME;
use sway_types::{Ident, Span, Spanned};
use thiserror::Error;
#[derive(Error, Debug, Clone, PartialEq, Eq, Hash)]
pub enum InterfaceName {
Abi(Ident),
Trait(Ident),
}
impl fmt::Display for InterfaceName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
InterfaceName::Abi(name) => write!(f, "ABI \"{name}\""),
InterfaceName::Trait(name) => write!(f, "trait \"{name}\""),
}
}
}
#[derive(Error, Debug, Clone, PartialEq, Eq, Hash)]
pub enum CompileError {
#[error("Variable \"{var_name}\" does not exist in this scope.")]
UnknownVariable { var_name: Ident, span: Span },
#[error("Identifier \"{name}\" was used as a variable, but it is actually a {what_it_is}.")]
NotAVariable {
name: Ident,
what_it_is: &'static str,
span: Span,
},
#[error("Unimplemented feature: {0}")]
Unimplemented(&'static str, Span),
#[error(
"Unimplemented feature: {0}\n\
help: {1}.\n\
"
)]
UnimplementedWithHelp(&'static str, &'static str, Span),
#[error("{0}")]
TypeError(TypeError),
#[error("Error parsing input: {err:?}")]
ParseError { span: Span, err: String },
#[error(
"Internal compiler error: {0}\nPlease file an issue on the repository and include the \
code that triggered this error."
)]
Internal(&'static str, Span),
#[error(
"Internal compiler error: {0}\nPlease file an issue on the repository and include the \
code that triggered this error."
)]
InternalOwned(String, Span),
#[error(
"Predicate declaration contains no main function. Predicates require a main function."
)]
NoPredicateMainFunction(Span),
#[error("A predicate's main function must return a boolean.")]
PredicateMainDoesNotReturnBool(Span),
#[error("Script declaration contains no main function. Scripts require a main function.")]
NoScriptMainFunction(Span),
#[error("Function \"{name}\" was already defined in scope.")]
MultipleDefinitionsOfFunction { name: Ident, span: Span },
#[error("Name \"{name}\" is defined multiple times.")]
MultipleDefinitionsOfName { name: Ident, span: Span },
#[error("Constant \"{name}\" was already defined in scope.")]
MultipleDefinitionsOfConstant { name: Ident, span: Span },
#[error("Assignment to immutable variable. Variable {name} is not declared as mutable.")]
AssignmentToNonMutable { name: Ident, span: Span },
#[error(
"Cannot call method \"{method_name}\" on variable \"{variable_name}\" because \
\"{variable_name}\" is not declared as mutable."
)]
MethodRequiresMutableSelf {
method_name: Ident,
variable_name: Ident,
span: Span,
},
#[error(
"This parameter was declared as mutable, which is not supported yet, did you mean to use ref mut?"
)]
MutableParameterNotSupported { param_name: Ident, span: Span },
#[error("Cannot pass immutable argument to mutable parameter.")]
ImmutableArgumentToMutableParameter { span: Span },
#[error("ref mut or mut parameter is not allowed for contract ABI function.")]
RefMutableNotAllowedInContractAbi { param_name: Ident, span: Span },
#[error(
"Cannot call associated function \"{fn_name}\" as a method. Use associated function \
syntax instead."
)]
AssociatedFunctionCalledAsMethod { fn_name: Ident, span: Span },
#[error(
"Generic type \"{name}\" is not in scope. Perhaps you meant to specify type parameters in \
the function signature? For example: \n`fn \
{fn_name}<{comma_separated_generic_params}>({args}) -> ... `"
)]
TypeParameterNotInTypeScope {
name: Ident,
span: Span,
comma_separated_generic_params: String,
fn_name: Ident,
args: String,
},
#[error(
"expected: {expected} \n\
found: {given} \n\
help: The definition of this {decl_type} must \
match the one in the {interface_name} declaration."
)]
MismatchedTypeInInterfaceSurface {
interface_name: InterfaceName,
span: Span,
decl_type: String,
given: String,
expected: String,
},
#[error("Trait \"{name}\" cannot be found in the current scope.")]
UnknownTrait { span: Span, name: Ident },
#[error("Function \"{name}\" is not a part of {interface_name}'s interface surface.")]
FunctionNotAPartOfInterfaceSurface {
name: Ident,
interface_name: InterfaceName,
span: Span,
},
#[error("Constant \"{name}\" is not a part of {interface_name}'s interface surface.")]
ConstantNotAPartOfInterfaceSurface {
name: Ident,
interface_name: InterfaceName,
span: Span,
},
#[error("Constants are missing from this trait implementation: {missing_constants}")]
MissingInterfaceSurfaceConstants {
missing_constants: String,
span: Span,
},
#[error("Functions are missing from this trait implementation: {missing_functions}")]
MissingInterfaceSurfaceMethods {
missing_functions: String,
span: Span,
},
#[error("Expected {} type {}, but instead found {}.", expected, if *expected == 1usize { "argument" } else { "arguments" }, given)]
IncorrectNumberOfTypeArguments {
given: usize,
expected: usize,
span: Span,
},
#[error("\"{name}\" does not take type arguments.")]
DoesNotTakeTypeArguments { name: Ident, span: Span },
#[error("\"{name}\" does not take type arguments as prefix.")]
DoesNotTakeTypeArgumentsAsPrefix { name: Ident, span: Span },
#[error("Type arguments are not allowed for this type.")]
TypeArgumentsNotAllowed { span: Span },
#[error("\"{name}\" needs type arguments.")]
NeedsTypeArguments { name: Ident, span: Span },
#[error(
"Enum with name \"{name}\" could not be found in this scope. Perhaps you need to import \
it?"
)]
EnumNotFound { name: Ident, span: Span },
#[error("Initialization of struct \"{struct_name}\" is missing field \"{field_name}\".")]
StructMissingField {
field_name: Ident,
struct_name: Ident,
span: Span,
},
#[error("Struct \"{struct_name}\" does not have field \"{field_name}\".")]
StructDoesNotHaveField {
field_name: Ident,
struct_name: Ident,
span: Span,
},
#[error("No method named \"{method_name}\" found for type \"{type_name}\".")]
MethodNotFound {
method_name: Ident,
type_name: String,
span: Span,
},
#[error("Module \"{name}\" could not be found.")]
ModuleNotFound { span: Span, name: String },
#[error("This is a {actually}, not a struct. Fields can only be accessed on structs.")]
FieldAccessOnNonStruct { actually: String, span: Span },
#[error("\"{name}\" is a {actually}, not a tuple. Elements can only be access on tuples.")]
NotATuple {
name: String,
span: Span,
actually: String,
},
#[error("\"{name}\" is a {actually}, which is not an indexable expression.")]
NotIndexable {
name: String,
span: Span,
actually: String,
},
#[error("\"{name}\" is a {actually}, not an enum.")]
NotAnEnum {
name: String,
span: Span,
actually: String,
},
#[error("This is a {actually}, not a struct.")]
NotAStruct { span: Span, actually: String },
#[error("This is a {actually}, not an enum.")]
DeclIsNotAnEnum { actually: String, span: Span },
#[error("This is a {actually}, not a struct.")]
DeclIsNotAStruct { actually: String, span: Span },
#[error("This is a {actually}, not a function.")]
DeclIsNotAFunction { actually: String, span: Span },
#[error("This is a {actually}, not a variable.")]
DeclIsNotAVariable { actually: String, span: Span },
#[error("This is a {actually}, not an ABI.")]
DeclIsNotAnAbi { actually: String, span: Span },
#[error("This is a {actually}, not a trait.")]
DeclIsNotATrait { actually: String, span: Span },
#[error("This is a {actually}, not an impl block.")]
DeclIsNotAnImplTrait { actually: String, span: Span },
#[error("This is a {actually}, not a trait function.")]
DeclIsNotATraitFn { actually: String, span: Span },
#[error("This is a {actually}, not storage.")]
DeclIsNotStorage { actually: String, span: Span },
#[error("This is a {actually}, not a constant")]
DeclIsNotAConstant { actually: String, span: Span },
#[error("This is a {actually}, not a type alias")]
DeclIsNotATypeAlias { actually: String, span: Span },
#[error(
"Field \"{field_name}\" not found on struct \"{struct_name}\". Available fields are:\n \
{available_fields}"
)]
FieldNotFound {
field_name: Ident,
available_fields: String,
struct_name: Ident,
span: Span,
},
#[error("Could not find symbol \"{name}\" in this scope.")]
SymbolNotFound { name: Ident, span: Span },
#[error("Symbol \"{name}\" is private.")]
ImportPrivateSymbol { name: Ident, span: Span },
#[error(
"Because this if expression's value is used, an \"else\" branch is required and it must \
return type \"{r#type}\""
)]
NoElseBranch { span: Span, r#type: String },
#[error(
"Symbol \"{name}\" does not refer to a type, it refers to a {actually_is}. It cannot be \
used in this position."
)]
NotAType {
span: Span,
name: String,
actually_is: &'static str,
},
#[error(
"This enum variant requires an instantiation expression. Try initializing it with \
arguments in parentheses."
)]
MissingEnumInstantiator { span: Span },
#[error(
"This path must return a value of type \"{ty}\" from function \"{function_name}\", but it \
does not."
)]
PathDoesNotReturn {
span: Span,
ty: String,
function_name: Ident,
},
#[error(
"Expected Module level doc comment. All other attributes are unsupported at this level."
)]
ExpectedModuleDocComment { span: Span },
#[error(
"This register was not initialized in the initialization section of the ASM expression. \
Initialized registers are: {initialized_registers}"
)]
UnknownRegister {
span: Span,
initialized_registers: String,
},
#[error("This opcode takes an immediate value but none was provided.")]
MissingImmediate { span: Span },
#[error("This immediate value is invalid.")]
InvalidImmediateValue { span: Span },
#[error("Variant \"{variant_name}\" does not exist on enum \"{enum_name}\"")]
UnknownEnumVariant {
enum_name: Ident,
variant_name: Ident,
span: Span,
},
#[error("Unknown opcode: \"{op_name}\".")]
UnrecognizedOp { op_name: Ident, span: Span },
#[error("Cannot infer type for type parameter \"{ty}\". Insufficient type information provided. Try annotating its type.")]
UnableToInferGeneric { ty: String, span: Span },
#[error("The generic type parameter \"{ty}\" is unconstrained.")]
UnconstrainedGenericParameter { ty: String, span: Span },
#[error("Trait \"{trait_name}\" is not implemented for type \"{ty}\".")]
TraitConstraintNotSatisfied {
ty: String,
trait_name: String,
span: Span,
},
#[error("The value \"{val}\" is too large to fit in this 6-bit immediate spot.")]
Immediate06TooLarge { val: u64, span: Span },
#[error("The value \"{val}\" is too large to fit in this 12-bit immediate spot.")]
Immediate12TooLarge { val: u64, span: Span },
#[error("The value \"{val}\" is too large to fit in this 18-bit immediate spot.")]
Immediate18TooLarge { val: u64, span: Span },
#[error("The value \"{val}\" is too large to fit in this 24-bit immediate spot.")]
Immediate24TooLarge { val: u64, span: Span },
#[error(
"This op expects {expected} register(s) as arguments, but you provided {received} register(s)."
)]
IncorrectNumberOfAsmRegisters {
span: Span,
expected: usize,
received: usize,
},
#[error("This op does not take an immediate value.")]
UnnecessaryImmediate { span: Span },
#[error("This reference is ambiguous, and could refer to a module, enum, or function of the same name. Try qualifying the name with a path.")]
AmbiguousPath { span: Span },
#[error("Unknown type name.")]
UnknownType { span: Span },
#[error("Unknown type name \"{name}\".")]
UnknownTypeName { name: String, span: Span },
#[error("The file {file_path} could not be read: {stringified_error}")]
FileCouldNotBeRead {
span: Span,
file_path: String,
stringified_error: String,
},
#[error("This imported file must be a library. It must start with \"library;\"")]
ImportMustBeLibrary { span: Span },
#[error("An enum instantiaton cannot contain more than one value. This should be a single value of type {ty}.")]
MoreThanOneEnumInstantiator { span: Span, ty: String },
#[error("This enum variant represents the unit type, so it should not be instantiated with any value.")]
UnnecessaryEnumInstantiator { span: Span },
#[error("The enum variant `{ty}` is of type `unit`, so its constructor does not take arguments or parentheses. Try removing the ().")]
UnitVariantWithParenthesesEnumInstantiator { span: Span, ty: String },
#[error("Cannot find trait \"{name}\" in this scope.")]
TraitNotFound { name: String, span: Span },
#[error("This expression is not valid on the left hand side of a reassignment.")]
InvalidExpressionOnLhs { span: Span },
#[error("{} \"{method_name}\" expects {expected} {} but you provided {received}.",
if *dot_syntax_used { "Method" } else { "Function" },
if *expected == 1usize { "argument" } else {"arguments"},
)]
TooManyArgumentsForFunction {
span: Span,
method_name: Ident,
dot_syntax_used: bool,
expected: usize,
received: usize,
},
#[error("{} \"{method_name}\" expects {expected} {} but you provided {received}.",
if *dot_syntax_used { "Method" } else { "Function" },
if *expected == 1usize { "argument" } else {"arguments"},
)]
TooFewArgumentsForFunction {
span: Span,
method_name: Ident,
dot_syntax_used: bool,
expected: usize,
received: usize,
},
#[error("The function \"{method_name}\" was called without parentheses. Try adding ().")]
MissingParenthesesForFunction { span: Span, method_name: Ident },
#[error("This type is invalid in a function selector. A contract ABI function selector must be a known sized type, not generic.")]
InvalidAbiType { span: Span },
#[error("This is a {actually_is}, not an ABI. An ABI cast requires a valid ABI to cast the address to.")]
NotAnAbi {
span: Span,
actually_is: &'static str,
},
#[error("An ABI can only be implemented for the `Contract` type, so this implementation of an ABI for type \"{ty}\" is invalid.")]
ImplAbiForNonContract { span: Span, ty: String },
#[error("Conflicting implementations of trait \"{trait_name}\" for type \"{type_implementing_for}\".")]
ConflictingImplsForTraitAndType {
trait_name: String,
type_implementing_for: String,
second_impl_span: Span,
},
#[error("Duplicate definitions for the {decl_kind} \"{decl_name}\" for type \"{type_implementing_for}\".")]
DuplicateDeclDefinedForType {
decl_kind: String,
decl_name: String,
type_implementing_for: String,
span: Span,
},
#[error("The function \"{fn_name}\" in {interface_name} is defined with {num_parameters} parameters, but the provided implementation has {provided_parameters} parameters.")]
IncorrectNumberOfInterfaceSurfaceFunctionParameters {
fn_name: Ident,
interface_name: InterfaceName,
num_parameters: usize,
provided_parameters: usize,
span: Span,
},
#[error("This parameter was declared as type {should_be}, but argument of type {provided} was provided.")]
ArgumentParameterTypeMismatch {
span: Span,
should_be: String,
provided: String,
},
#[error("Function {fn_name} is recursive, which is unsupported at this time.")]
RecursiveCall { fn_name: Ident, span: Span },
#[error(
"Function {fn_name} is recursive via {call_chain}, which is unsupported at this time."
)]
RecursiveCallChain {
fn_name: Ident,
call_chain: String, span: Span,
},
#[error("Type {name} is recursive, which is unsupported at this time.")]
RecursiveType { name: Ident, span: Span },
#[error("Type {name} is recursive via {type_chain}, which is unsupported at this time.")]
RecursiveTypeChain {
name: Ident,
type_chain: String, span: Span,
},
#[error("The GM (get-metadata) opcode, when called from an external context, will cause the VM to panic.")]
GMFromExternalContext { span: Span },
#[error("The MINT opcode cannot be used in an external context.")]
MintFromExternalContext { span: Span },
#[error("The BURN opcode cannot be used in an external context.")]
BurnFromExternalContext { span: Span },
#[error("Contract storage cannot be used in an external context.")]
ContractStorageFromExternalContext { span: Span },
#[error("The {opcode} opcode cannot be used in a predicate.")]
InvalidOpcodeFromPredicate { opcode: String, span: Span },
#[error("The {opcode} opcode cannot jump backwards in a predicate.")]
InvalidBackwardJumpFromPredicate { opcode: String, span: Span },
#[error("Array index out of bounds; the length is {count} but the index is {index}.")]
ArrayOutOfBounds { index: u64, count: u64, span: Span },
#[error("Tuple index out of bounds; the arity is {count} but the index is {index}.")]
TupleIndexOutOfBounds {
index: usize,
count: usize,
span: Span,
},
#[error("The name \"{name}\" shadows another symbol with the same name.")]
ShadowsOtherSymbol { name: Ident },
#[error("The name \"{name}\" is already used for a generic parameter in this scope.")]
GenericShadowsGeneric { name: Ident },
#[error("Non-exhaustive match expression. Missing patterns {missing_patterns}")]
MatchExpressionNonExhaustive {
missing_patterns: String,
span: Span,
},
#[error("Pattern does not mention {}: {}",
if missing_fields.len() == 1 { "field" } else { "fields" },
missing_fields.join(", "))]
MatchStructPatternMissingFields {
missing_fields: Vec<String>,
span: Span,
},
#[error(
"Storage attribute access mismatch. Try giving the surrounding function more access by \
adding \"#[{STORAGE_PURITY_ATTRIBUTE_NAME}({attrs})]\" to the function declaration."
)]
StorageAccessMismatch { attrs: String, span: Span },
#[error(
"The function \"{fn_name}\" in {interface_name} is pure, but this \
implementation is not. The \"{STORAGE_PURITY_ATTRIBUTE_NAME}\" annotation must be \
removed, or the trait declaration must be changed to \
\"#[{STORAGE_PURITY_ATTRIBUTE_NAME}({attrs})]\"."
)]
TraitDeclPureImplImpure {
fn_name: Ident,
interface_name: InterfaceName,
attrs: String,
span: Span,
},
#[error(
"Storage attribute access mismatch. The function \"{fn_name}\" in \
{interface_name} requires the storage attribute(s) #[{STORAGE_PURITY_ATTRIBUTE_NAME}({attrs})]."
)]
TraitImplPurityMismatch {
fn_name: Ident,
interface_name: InterfaceName,
attrs: String,
span: Span,
},
#[error("Impure function inside of non-contract. Contract storage is only accessible from contracts.")]
ImpureInNonContract { span: Span },
#[error(
"This function performs a storage {storage_op} but does not have the required \
attribute(s). Try adding \"#[{STORAGE_PURITY_ATTRIBUTE_NAME}({attrs})]\" to the function \
declaration."
)]
ImpureInPureContext {
storage_op: &'static str,
attrs: String,
span: Span,
},
#[error(
"Parameter reference type or mutability mismatch between the trait function declaration and its implementation."
)]
ParameterRefMutabilityMismatch { span: Span },
#[error("Literal value is too large for type {ty}.")]
IntegerTooLarge { span: Span, ty: String },
#[error("Literal value underflows type {ty}.")]
IntegerTooSmall { span: Span, ty: String },
#[error("Literal value contains digits which are not valid for type {ty}.")]
IntegerContainsInvalidDigit { span: Span, ty: String },
#[error("A trait cannot be a subtrait of an ABI.")]
AbiAsSupertrait { span: Span },
#[error(
"Implementation of trait \"{supertrait_name}\" is required by this bound in \"{trait_name}\""
)]
SupertraitImplRequired {
supertrait_name: String,
trait_name: Ident,
span: Span,
},
#[error(
"Contract ABI method parameter \"{param_name}\" is set multiple times for this contract ABI method call"
)]
ContractCallParamRepeated { param_name: String, span: Span },
#[error(
"Unrecognized contract ABI method parameter \"{param_name}\". The only available parameters are \"gas\", \"coins\", and \"asset_id\""
)]
UnrecognizedContractParam { param_name: String, span: Span },
#[error("Attempting to specify a contract method parameter for a non-contract function call")]
CallParamForNonContractCallMethod { span: Span },
#[error("Storage field {name} does not exist")]
StorageFieldDoesNotExist { name: Ident, span: Span },
#[error("No storage has been declared")]
NoDeclaredStorage { span: Span },
#[error("Multiple storage declarations were found")]
MultipleStorageDeclarations { span: Span },
#[error("Type {ty} can only be declared directly as a storage field")]
InvalidStorageOnlyTypeDecl { ty: String, span: Span },
#[error(
"Internal compiler error: Unexpected {decl_type} declaration found.\n\
Please file an issue on the repository and include the code that triggered this error."
)]
UnexpectedDeclaration { decl_type: &'static str, span: Span },
#[error("This contract caller has no known address. Try instantiating a contract caller with a known contract address instead.")]
ContractAddressMustBeKnown { span: Span },
#[error("{}", error)]
ConvertParseTree {
#[from]
error: ConvertParseTreeError,
},
#[error("{}", error)]
Lex { error: LexError },
#[error("{}", error)]
Parse { error: ParseError },
#[error("\"where\" clauses are not yet supported")]
WhereClauseNotYetSupported { span: Span },
#[error("Could not evaluate initializer to a const declaration.")]
NonConstantDeclValue { span: Span },
#[error("Declaring storage in a {program_kind} is not allowed.")]
StorageDeclarationInNonContract { program_kind: String, span: Span },
#[error("Unsupported argument type to intrinsic \"{name}\". {hint}")]
IntrinsicUnsupportedArgType {
name: String,
span: Span,
hint: Hint,
},
#[error("Call to \"{name}\" expects {expected} arguments")]
IntrinsicIncorrectNumArgs {
name: String,
expected: u64,
span: Span,
},
#[error("Call to \"{name}\" expects {expected} type arguments")]
IntrinsicIncorrectNumTArgs {
name: String,
expected: u64,
span: Span,
},
#[error("\"break\" used outside of a loop")]
BreakOutsideLoop { span: Span },
#[error("\"continue\" used outside of a loop")]
ContinueOutsideLoop { span: Span },
#[error("Contract ID is not a constant item.")]
ContractIdConstantNotAConstDecl { span: Span },
#[error("Contract ID value is not a literal.")]
ContractIdValueNotALiteral { span: Span },
#[error("The type \"{ty}\" is not allowed in storage.")]
TypeNotAllowedInContractStorage { ty: String, span: Span },
#[error("ref mut parameter not allowed for main()")]
RefMutableNotAllowedInMain { param_name: Ident, span: Span },
#[error(
"Returning a type containing `raw_slice` from `main()` is not allowed. \
Consider converting it into a flat `raw_slice` first."
)]
NestedSliceReturnNotAllowedInMain { span: Span },
#[error(
"Register \"{name}\" is initialized and later reassigned which is not allowed. \
Consider assigning to a different register inside the ASM block."
)]
InitializedRegisterReassignment { name: String, span: Span },
#[error("Control flow VM instructions are not allowed in assembly blocks.")]
DisallowedControlFlowInstruction { name: String, span: Span },
#[error("Calling private library method {name} is not allowed.")]
CallingPrivateLibraryMethod { name: String, span: Span },
#[error("Using \"while\" in a predicate is not allowed.")]
DisallowedWhileInPredicate { span: Span },
#[error("Possibly non-zero amount of coins transferred to non-payable contract method \"{fn_name}\".")]
CoinsPassedToNonPayableMethod { fn_name: Ident, span: Span },
#[error(
"Payable attribute mismatch. The \"{fn_name}\" method implementation \
{} in its signature in {interface_name}.",
if *missing_impl_attribute {
"is missing #[payable] attribute specified"
} else {
"has extra #[payable] attribute not mentioned"
}
)]
TraitImplPayabilityMismatch {
fn_name: Ident,
interface_name: InterfaceName,
missing_impl_attribute: bool,
span: Span,
},
#[error("Configurable constants are not allowed in libraries.")]
ConfigurableInLibrary { span: Span },
#[error("The name `{name}` is defined multiple times")]
NameDefinedMultipleTimes { name: String, span: Span },
}
impl std::convert::From<TypeError> for CompileError {
fn from(other: TypeError) -> CompileError {
CompileError::TypeError(other)
}
}
impl Spanned for CompileError {
fn span(&self) -> Span {
use CompileError::*;
match self {
UnknownVariable { span, .. } => span.clone(),
NotAVariable { span, .. } => span.clone(),
Unimplemented(_, span) => span.clone(),
UnimplementedWithHelp(_, _, span) => span.clone(),
TypeError(err) => err.span(),
ParseError { span, .. } => span.clone(),
Internal(_, span) => span.clone(),
InternalOwned(_, span) => span.clone(),
NoPredicateMainFunction(span) => span.clone(),
PredicateMainDoesNotReturnBool(span) => span.clone(),
NoScriptMainFunction(span) => span.clone(),
MultipleDefinitionsOfFunction { span, .. } => span.clone(),
MultipleDefinitionsOfName { span, .. } => span.clone(),
MultipleDefinitionsOfConstant { span, .. } => span.clone(),
AssignmentToNonMutable { span, .. } => span.clone(),
MutableParameterNotSupported { span, .. } => span.clone(),
ImmutableArgumentToMutableParameter { span } => span.clone(),
RefMutableNotAllowedInContractAbi { span, .. } => span.clone(),
MethodRequiresMutableSelf { span, .. } => span.clone(),
AssociatedFunctionCalledAsMethod { span, .. } => span.clone(),
TypeParameterNotInTypeScope { span, .. } => span.clone(),
MismatchedTypeInInterfaceSurface { span, .. } => span.clone(),
UnknownTrait { span, .. } => span.clone(),
FunctionNotAPartOfInterfaceSurface { span, .. } => span.clone(),
ConstantNotAPartOfInterfaceSurface { span, .. } => span.clone(),
MissingInterfaceSurfaceConstants { span, .. } => span.clone(),
MissingInterfaceSurfaceMethods { span, .. } => span.clone(),
IncorrectNumberOfTypeArguments { span, .. } => span.clone(),
DoesNotTakeTypeArguments { span, .. } => span.clone(),
DoesNotTakeTypeArgumentsAsPrefix { span, .. } => span.clone(),
TypeArgumentsNotAllowed { span } => span.clone(),
NeedsTypeArguments { span, .. } => span.clone(),
StructMissingField { span, .. } => span.clone(),
StructDoesNotHaveField { span, .. } => span.clone(),
MethodNotFound { span, .. } => span.clone(),
ModuleNotFound { span, .. } => span.clone(),
NotATuple { span, .. } => span.clone(),
NotAStruct { span, .. } => span.clone(),
NotIndexable { span, .. } => span.clone(),
FieldAccessOnNonStruct { span, .. } => span.clone(),
FieldNotFound { span, .. } => span.clone(),
SymbolNotFound { span, .. } => span.clone(),
ImportPrivateSymbol { span, .. } => span.clone(),
NoElseBranch { span, .. } => span.clone(),
NotAType { span, .. } => span.clone(),
MissingEnumInstantiator { span, .. } => span.clone(),
PathDoesNotReturn { span, .. } => span.clone(),
ExpectedModuleDocComment { span } => span.clone(),
UnknownRegister { span, .. } => span.clone(),
MissingImmediate { span, .. } => span.clone(),
InvalidImmediateValue { span, .. } => span.clone(),
UnknownEnumVariant { span, .. } => span.clone(),
UnrecognizedOp { span, .. } => span.clone(),
UnableToInferGeneric { span, .. } => span.clone(),
UnconstrainedGenericParameter { span, .. } => span.clone(),
TraitConstraintNotSatisfied { span, .. } => span.clone(),
Immediate06TooLarge { span, .. } => span.clone(),
Immediate12TooLarge { span, .. } => span.clone(),
Immediate18TooLarge { span, .. } => span.clone(),
Immediate24TooLarge { span, .. } => span.clone(),
IncorrectNumberOfAsmRegisters { span, .. } => span.clone(),
UnnecessaryImmediate { span, .. } => span.clone(),
AmbiguousPath { span, .. } => span.clone(),
UnknownType { span, .. } => span.clone(),
UnknownTypeName { span, .. } => span.clone(),
FileCouldNotBeRead { span, .. } => span.clone(),
ImportMustBeLibrary { span, .. } => span.clone(),
MoreThanOneEnumInstantiator { span, .. } => span.clone(),
UnnecessaryEnumInstantiator { span, .. } => span.clone(),
UnitVariantWithParenthesesEnumInstantiator { span, .. } => span.clone(),
TraitNotFound { span, .. } => span.clone(),
InvalidExpressionOnLhs { span, .. } => span.clone(),
TooManyArgumentsForFunction { span, .. } => span.clone(),
TooFewArgumentsForFunction { span, .. } => span.clone(),
MissingParenthesesForFunction { span, .. } => span.clone(),
InvalidAbiType { span, .. } => span.clone(),
NotAnAbi { span, .. } => span.clone(),
ImplAbiForNonContract { span, .. } => span.clone(),
ConflictingImplsForTraitAndType {
second_impl_span, ..
} => second_impl_span.clone(),
DuplicateDeclDefinedForType { span, .. } => span.clone(),
IncorrectNumberOfInterfaceSurfaceFunctionParameters { span, .. } => span.clone(),
ArgumentParameterTypeMismatch { span, .. } => span.clone(),
RecursiveCall { span, .. } => span.clone(),
RecursiveCallChain { span, .. } => span.clone(),
RecursiveType { span, .. } => span.clone(),
RecursiveTypeChain { span, .. } => span.clone(),
GMFromExternalContext { span, .. } => span.clone(),
MintFromExternalContext { span, .. } => span.clone(),
BurnFromExternalContext { span, .. } => span.clone(),
ContractStorageFromExternalContext { span, .. } => span.clone(),
InvalidOpcodeFromPredicate { span, .. } => span.clone(),
InvalidBackwardJumpFromPredicate { span, .. } => span.clone(),
ArrayOutOfBounds { span, .. } => span.clone(),
ShadowsOtherSymbol { name } => name.span(),
GenericShadowsGeneric { name } => name.span(),
MatchExpressionNonExhaustive { span, .. } => span.clone(),
MatchStructPatternMissingFields { span, .. } => span.clone(),
NotAnEnum { span, .. } => span.clone(),
StorageAccessMismatch { span, .. } => span.clone(),
TraitDeclPureImplImpure { span, .. } => span.clone(),
TraitImplPurityMismatch { span, .. } => span.clone(),
DeclIsNotAnEnum { span, .. } => span.clone(),
DeclIsNotAStruct { span, .. } => span.clone(),
DeclIsNotAFunction { span, .. } => span.clone(),
DeclIsNotAVariable { span, .. } => span.clone(),
DeclIsNotAnAbi { span, .. } => span.clone(),
DeclIsNotATrait { span, .. } => span.clone(),
DeclIsNotAnImplTrait { span, .. } => span.clone(),
DeclIsNotATraitFn { span, .. } => span.clone(),
DeclIsNotStorage { span, .. } => span.clone(),
DeclIsNotAConstant { span, .. } => span.clone(),
DeclIsNotATypeAlias { span, .. } => span.clone(),
ImpureInNonContract { span, .. } => span.clone(),
ImpureInPureContext { span, .. } => span.clone(),
ParameterRefMutabilityMismatch { span, .. } => span.clone(),
IntegerTooLarge { span, .. } => span.clone(),
IntegerTooSmall { span, .. } => span.clone(),
IntegerContainsInvalidDigit { span, .. } => span.clone(),
AbiAsSupertrait { span, .. } => span.clone(),
SupertraitImplRequired { span, .. } => span.clone(),
ContractCallParamRepeated { span, .. } => span.clone(),
UnrecognizedContractParam { span, .. } => span.clone(),
CallParamForNonContractCallMethod { span, .. } => span.clone(),
StorageFieldDoesNotExist { span, .. } => span.clone(),
InvalidStorageOnlyTypeDecl { span, .. } => span.clone(),
NoDeclaredStorage { span, .. } => span.clone(),
MultipleStorageDeclarations { span, .. } => span.clone(),
UnexpectedDeclaration { span, .. } => span.clone(),
ContractAddressMustBeKnown { span, .. } => span.clone(),
ConvertParseTree { error } => error.span(),
WhereClauseNotYetSupported { span, .. } => span.clone(),
Lex { error } => error.span(),
Parse { error } => error.span.clone(),
EnumNotFound { span, .. } => span.clone(),
TupleIndexOutOfBounds { span, .. } => span.clone(),
NonConstantDeclValue { span } => span.clone(),
StorageDeclarationInNonContract { span, .. } => span.clone(),
IntrinsicUnsupportedArgType { span, .. } => span.clone(),
IntrinsicIncorrectNumArgs { span, .. } => span.clone(),
IntrinsicIncorrectNumTArgs { span, .. } => span.clone(),
BreakOutsideLoop { span } => span.clone(),
ContinueOutsideLoop { span } => span.clone(),
ContractIdConstantNotAConstDecl { span } => span.clone(),
ContractIdValueNotALiteral { span } => span.clone(),
TypeNotAllowedInContractStorage { span, .. } => span.clone(),
RefMutableNotAllowedInMain { span, .. } => span.clone(),
NestedSliceReturnNotAllowedInMain { span } => span.clone(),
InitializedRegisterReassignment { span, .. } => span.clone(),
DisallowedControlFlowInstruction { span, .. } => span.clone(),
CallingPrivateLibraryMethod { span, .. } => span.clone(),
DisallowedWhileInPredicate { span } => span.clone(),
CoinsPassedToNonPayableMethod { span, .. } => span.clone(),
TraitImplPayabilityMismatch { span, .. } => span.clone(),
ConfigurableInLibrary { span } => span.clone(),
NameDefinedMultipleTimes { span, .. } => span.clone(),
}
}
}
impl CompileError {
pub fn path(&self) -> Option<Arc<PathBuf>> {
self.span().path().cloned()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Hint {
msg: Option<String>,
}
impl Hint {
pub fn empty() -> Hint {
Hint { msg: None }
}
pub fn new(msg: String) -> Hint {
Hint { msg: Some(msg) }
}
}
impl fmt::Display for Hint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Hint: {}", &self.msg.as_ref().unwrap_or(&"".to_string()))
}
}