mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 23:08:11 +08:00
Treat Modify bounds as transparent and drop the redundant fold-context validation
This commit is contained in:
@@ -940,11 +940,15 @@ fn parse_context_feature_idents(ty: &Type) -> Vec<ContextFeatureDecl> {
|
|||||||
| "InjectVarArgs" => {
|
| "InjectVarArgs" => {
|
||||||
features.push(ContextFeatureDecl::new(segment.ident.clone()));
|
features.push(ContextFeatureDecl::new(segment.ident.clone()));
|
||||||
}
|
}
|
||||||
|
// Modify* is conditionally transparent: the node rewrites the
|
||||||
|
// field only on its content's behalf, so it names no
|
||||||
|
// requirement of its own and the field nullifies early when
|
||||||
|
// nothing upstream reads it.
|
||||||
|
"ModifyFootprint" | "ModifyRealTime" | "ModifyAnimationTime" | "ModifyPointerPosition" | "ModifyPosition" | "ModifyIndex" | "ModifyVarArgs" => {}
|
||||||
// InjectIndex stays undeclared: a record node's injection
|
// InjectIndex stays undeclared: a record node's injection
|
||||||
// re-addresses lanes derived from the incoming index, so it
|
// re-addresses lanes derived from the incoming index, so it
|
||||||
// must not cancel the cone's index requirement in the
|
// must not cancel the cone's index requirement in the
|
||||||
// nullification pass.
|
// nullification pass.
|
||||||
// Skip Modify* traits as they don't affect usage tracking
|
|
||||||
// Also ignore other traits like Ctx, ExtractAll, etc.
|
// Also ignore other traits like Ctx, ExtractAll, etc.
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ pub fn validate_node_fn(parsed: &ParsedNodeFn) -> syn::Result<()> {
|
|||||||
validate_lend_fields,
|
validate_lend_fields,
|
||||||
validate_record_io,
|
validate_record_io,
|
||||||
validate_lazy_reads,
|
validate_lazy_reads,
|
||||||
validate_materialized_ctx,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
for validator in validators {
|
for validator in validators {
|
||||||
@@ -262,30 +261,6 @@ fn validate_async_source(parsed: &ParsedNodeFn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_materialized_ctx(parsed: &ParsedNodeFn) {
|
|
||||||
let materialized = parsed
|
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.any(|field| matches!(&field.ty, ParsedFieldType::Regular(RegularParsedField { list_levels, .. }) if *list_levels > 0));
|
|
||||||
if !materialized {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let Some(ctx) = crate::codegen::classify::context_param(parsed) else { return };
|
|
||||||
let has = |name: &str| {
|
|
||||||
ctx.bounds
|
|
||||||
.iter()
|
|
||||||
.any(|bound| matches!(bound, syn::TypeParamBound::Trait(bound) if bound.path.segments.last().is_some_and(|segment| segment.ident == name)))
|
|
||||||
};
|
|
||||||
let missing: Vec<&str> = ["InjectIndex", "Copy"].into_iter().filter(|name| !has(name)).collect();
|
|
||||||
if !missing.is_empty() {
|
|
||||||
emit_error!(
|
|
||||||
parsed.input.pat_ident.span(),
|
|
||||||
"a node folding a ranked `List` input drives `eval_batch` over it, so its context must add `{}`; spell `impl Ctx + InjectIndex + Copy`",
|
|
||||||
missing.join(" + ")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_lend_fields(parsed: &ParsedNodeFn) {
|
fn validate_lend_fields(parsed: &ParsedNodeFn) {
|
||||||
let future_kernel = crate::codegen::is_source_kernel(&parsed.output_type);
|
let future_kernel = crate::codegen::is_source_kernel(&parsed.output_type);
|
||||||
for field in &parsed.fields {
|
for field in &parsed.fields {
|
||||||
|
|||||||
Reference in New Issue
Block a user