plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
add63b7
— Peter John
2026-11-02T19:49:59+05:30
T4: checker trait rules
plum-checker/src/lib.rs
CHANGED
|
@@ -3284,7 +3284,11 @@ fn checkMatch(
|
|
|
3284
3284
|
let lowered = m.cases.iter().any(|c| {
|
|
3285
3285
|
c.patterns.iter().any(|p| match p {
|
|
3286
3286
|
ast::CasePattern::Class { name, .. } | ast::CasePattern::Name(name) => {
|
|
3287
|
-
name.
|
|
3287
|
+
name.starts_with(&format!("{tn}__"))
|
|
3288
|
+
&& ctx
|
|
3289
|
+
.enum_variants
|
|
3290
|
+
.get(name.as_str())
|
|
3291
|
+
.is_some_and(|i| &i.enum_name == tn)
|
|
3288
3292
|
}
|
|
3289
3293
|
_ => false,
|
|
3290
3294
|
})
|
plum-checker/tests/trait_fields_tests.rs
CHANGED
|
@@ -220,3 +220,33 @@ fn typed_source_lowers_field_access() {
|
|
|
220
220
|
let low = info.lowered.expect("lowered copy");
|
|
221
221
|
assert!(hasMethod(&low, "Ent", "__get_z") && hasMethod(&low, "Ent", "__set_z"));
|
|
222
222
|
}
|
|
223
|
+
|
|
224
|
+
#[test]
|
|
225
|
+
fn fieldless_and_memberless_traits_are_exact() {
|
|
226
|
+
let s = lowered("trait Bare =\n fun go(self)\ntrait Lonely(q: Float) =\n fun go(self)\n");
|
|
227
|
+
withCtx(&s, |ctx| {
|
|
228
|
+
beginPlan();
|
|
229
|
+
assert_eq!(
|
|
230
|
+
traitField(&named("Bare"), "x", 1, false, ctx),
|
|
231
|
+
Some(Err("trait Bare has no field x".to_string()))
|
|
232
|
+
);
|
|
233
|
+
assert_eq!(
|
|
234
|
+
traitField(&named("Lonely"), "q", 1, false, ctx),
|
|
235
|
+
Some(Err("trait Lonely has no field q".to_string()))
|
|
236
|
+
);
|
|
237
|
+
takePlan();
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#[test]
|
|
242
|
+
fn member_fallback_never_wraps_into_a_trait() {
|
|
243
|
+
let s = lowered("");
|
|
244
|
+
withCtx(&s, |ctx| {
|
|
245
|
+
// Hut is a member of trait Ent; `draw` is Ent's, but Hut has its own: no fallback.
|
|
246
|
+
assert!(plum_checker::unions::memberFallback(&named("Hut"), "draw", ctx).is_none());
|
|
247
|
+
// a method only the trait defines (default) must not wrap the record into it
|
|
248
|
+
assert!(plum_checker::unions::memberFallback(&named("Hut"), "nope", ctx).is_none());
|
|
249
|
+
// plain union enums still fall back
|
|
250
|
+
assert!(plum_checker::unions::memberFallback(&named("Circle"), "nope", ctx).is_none());
|
|
251
|
+
});
|
|
252
|
+
}
|