When there's an error in an expression, such as referencing an undefined symbol or when no matching overload is found for a function call, an error value is produced at the point the error is detected and reported. These error values then propagate and suppress further errors when consumed, to prevent cascades of spurious subsequent errors.
Usually, if any input to a sub-expression is an error value, then the output will also be an error value. This is good for suppressing subsequent spurious errors, but it can reduce the information available to the language extension. For example, it means that variable types can be inferred to be !!! (error), or function call overloads do not resolve, which in turn breaks hover or navigate to definition features.
In some cases, we can stop the propagation of error values if the result of a sub-expression, involving one or more error values, is nevertheless unambiguously typed. For example, we may still find a reasonable operator or function overload match even if one of the operands or some of the arguments are error values.
This approach is safe, even if we actually pick an incorrect overload, because there will always have been a prior error message issued at the point of origin for any error value. That error message will prevent the compiler from producing executable output. In other words, in the worst-case scenario, we could offer misleading information to the user through the language extension, but we will not generate incorrect code.
When there's an error in an expression, such as referencing an undefined symbol or when no matching overload is found for a function call, an error value is produced at the point the error is detected and reported. These error values then propagate and suppress further errors when consumed, to prevent cascades of spurious subsequent errors.
Usually, if any input to a sub-expression is an error value, then the output will also be an error value. This is good for suppressing subsequent spurious errors, but it can reduce the information available to the language extension. For example, it means that variable types can be inferred to be !!! (error), or function call overloads do not resolve, which in turn breaks hover or navigate to definition features.
In some cases, we can stop the propagation of error values if the result of a sub-expression, involving one or more error values, is nevertheless unambiguously typed. For example, we may still find a reasonable operator or function overload match even if one of the operands or some of the arguments are error values.
This approach is safe, even if we actually pick an incorrect overload, because there will always have been a prior error message issued at the point of origin for any error value. That error message will prevent the compiler from producing executable output. In other words, in the worst-case scenario, we could offer misleading information to the user through the language extension, but we will not generate incorrect code.