···65656666 ([Surya Rose](https://github.com/GearsDatapacks))
67676868+- The compiler now emits a warning when using `let assert` to assert a value
6969+ whose variant has already been inferred. For example:
7070+7171+ ```gleam
7272+ // warning: This will always crash
7373+ let assert Ok(_) = Error("Some error")
7474+ ```
7575+7676+ ([Surya Rose](https://github.com/GearsDatapacks))
7777+6878### Build tool
69797080- Include a type annotation for the `main` function generated by `gleam new`.
···1212 UntypedUseAssignment, Use, UseAssignment,
1313 },
1414 build::Target,
1515- exhaustiveness::{self, Reachability},
1515+ exhaustiveness::{self, Match, Reachability},
1616 reference::ReferenceKind,
1717};
1818use hexpm::version::Version;
···15241524 }
1525152515261526 // Do not perform exhaustiveness checking if user explicitly used `let assert ... = ...`.
15271527- let exhaustiveness_check = self.check_let_exhaustiveness(location, value.type_(), &pattern);
15271527+ let (output, exhaustiveness_check) =
15281528+ self.check_let_exhaustiveness(location, value.type_(), &pattern);
15281529 match (&kind, exhaustiveness_check) {
15291530 // The pattern is exhaustive in a let assignment, there's no problem here.
15301531 (AssignmentKind::Let | AssignmentKind::Generated, Ok(_)) => {}
···15431544 })
15441545 }
1545154615461546- // Otherwise we just don't care, asserting will ignore the any missing
15471547- // pattern error.
15481548- (AssignmentKind::Assert { .. }, Err(_)) => {}
15471547+ // Otherwise, if the pattern is never reachable (through variant inference),
15481548+ // we can warn the user about this.
15491549+ (AssignmentKind::Assert { .. }, Err(_)) => {
15501550+ // There is only one pattern to match, so it is index 0
15511551+ match output.is_reachable(0) {
15521552+ Reachability::Unreachable(UnreachableCaseClauseReason::ImpossibleVariant) => {
15531553+ self.problems
15541554+ .warning(Warning::AssertAssignmentOnInferredVariant {
15551555+ location: pattern.location(),
15561556+ })
15571557+ }
15581558+ // A duplicate pattern warning should not happen, since there is only on pattern.
15591559+ Reachability::Reachable
15601560+ | Reachability::Unreachable(UnreachableCaseClauseReason::DuplicatePattern) => {}
15611561+ }
15621562+ }
15491563 }
1550156415511565 Assignment {
···40094023 location: SrcSpan,
40104024 subject: Arc<Type>,
40114025 pattern: &TypedPattern,
40124012- ) -> Result<(), Error> {
40264026+ ) -> (Match, Result<(), Error>) {
40134027 let mut case = exhaustiveness::CaseToCompile::new(&[subject]);
40144028 case.add_pattern(pattern);
40154029 let output = case.compile(self.environment);
4016403040174031 // Error for missing clauses that would cause a crash
40184018- if output.diagnostics.missing {
40324032+ let result = if output.diagnostics.missing {
40194033 Err(Error::InexhaustiveLetAssignment {
40204034 location,
40214035 missing: output.missing_patterns(self.environment),
40224036 })
40234037 } else {
40244038 Ok(())
40254025- }
40394039+ };
40404040+ (output, result)
40264041 }
4027404240284043 fn check_case_exhaustiveness(
···11---
22source: compiler-core/src/type_/tests/warnings.rs
33-expression: "\npub fn main() {\n let assert Ok(10) = Error(20) as \"This will crash...\"\n}\n"
33+expression: "\npub fn main() {\n let assert Ok(10) = Ok(20) as \"This will crash...\"\n}\n"
44---
55----- SOURCE CODE
6677pub fn main() {
88- let assert Ok(10) = Error(20) as "This will crash..."
88+ let assert Ok(10) = Ok(20) as "This will crash..."
99}
101011111212----- WARNING
1313warning: Incompatible gleam version range
1414- ┌─ /src/warning/wrn.gleam:3:36
1414+ ┌─ /src/warning/wrn.gleam:3:33
1515 │
1616-3 │ let assert Ok(10) = Error(20) as "This will crash..."
1717- │ ^^^^^^^^^^^^^^^^^^^^ This requires a Gleam version >= 1.7.0
1616+3 │ let assert Ok(10) = Ok(20) as "This will crash..."
1717+ │ ^^^^^^^^^^^^^^^^^^^^ This requires a Gleam version >= 1.7.0
18181919Specifying a custom panic message when using let assert was introduced in
2020version v1.7.0. But the Gleam version range specified in your `gleam.toml`