diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index a8298cb0..c9f41e88 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -259,10 +259,16 @@ You can use '{discard}' and numbers to distinguish between similar names. name: String, }, - #[error("I found an expect assignment involving an opaque type. This is not allowed.\n")] + #[error("I caught an opaque type possibly breaking its abstraction boundary.\n")] #[diagnostic(code("illegal::expect_on_opaque"))] + #[diagnostic(url("https://aiken-lang.org/language-tour/modules#opaque-types"))] + #[diagnostic(help( + "This expression is trying to convert something unknown into an opaque type. An opaque type is a data-type which hides its internal details; usually because it enforces some specific invariant on its internal structure. For example, you might define a {Natural} type that holds an {Integer} but ensures that it never gets negative.\n\nA direct consequence means that it isn't generally possible, nor safe, to turn *any* value into an opaque type. Instead, use the constructors and methods provided for lifting values into that opaque type while ensuring that any structural invariant is checked for.", + Natural = "Natural".if_supports_color(Stdout, |s| s.cyan()), + Integer = "Integer".if_supports_color(Stdout, |s| s.cyan()), + ))] ExpectOnOpaqueType { - #[label] + #[label("reckless opaque cast")] location: Span, },