Skip to content

Commit a683a72

Browse files
committed
Validate retained effect parameter names
1 parent 0169aed commit a683a72

3 files changed

Lines changed: 50 additions & 0 deletions

File tree

src/analyzer.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashSet;
2+
13
use crate::checks;
24
use crate::diagnostic::{Diagnostic, code};
35
use crate::hir::{DuplicateSymbolKind, Hir, HirTypeKind};
@@ -136,6 +138,36 @@ impl Analyzer<'_> {
136138
));
137139
}
138140
}
141+
142+
let param_names: HashSet<&str> = function
143+
.params
144+
.iter()
145+
.map(|param| param.name.as_str())
146+
.collect();
147+
for effect in &function.effects {
148+
let EffectDecl::Retains(param) = effect else {
149+
continue;
150+
};
151+
if !param_names.contains(param.as_str()) {
152+
self.diagnostics.push(
153+
Diagnostic::error(
154+
code::UNKNOWN_RETAINED_PARAMETER,
155+
format!(
156+
"`{}` declares `effects(retains({param}))`, but `{param}` is not a parameter.",
157+
function.name
158+
),
159+
function.span.clone(),
160+
"unknown retained parameter",
161+
)
162+
.with_cause("Retention effects must name a parameter from the same function signature.")
163+
.with_fix(
164+
"fix_retains_parameter",
165+
"Rename the retained parameter or remove this retention effect.",
166+
"manual",
167+
),
168+
);
169+
}
170+
}
139171
}
140172
}
141173

src/diagnostic.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod code {
77
pub const UNKNOWN_EFFECT: &str = "RS0004";
88
pub const DUPLICATE_DECLARATION: &str = "RS0005";
99
pub const DUPLICATE_FILE_MODE: &str = "RS0006";
10+
pub const UNKNOWN_RETAINED_PARAMETER: &str = "RS0007";
1011
pub const FILE_MODE_VIOLATION: &str = "RS0101";
1112
pub const UNNAMED_ARGUMENT: &str = "RS0201";
1213
pub const MISSING_DATA_EFFECT: &str = "RS0202";
@@ -224,6 +225,11 @@ static DIAGNOSTIC_EXPLANATIONS: &[DiagnosticExplanation] = &[
224225
title: "duplicate file mode",
225226
explanation: "Every RSScript source file must declare exactly one semantic mode. Multiple `mode:` declarations make local-capability review ambiguous.",
226227
},
228+
DiagnosticExplanation {
229+
code: code::UNKNOWN_RETAINED_PARAMETER,
230+
title: "unknown retained parameter",
231+
explanation: "`effects(retains(param))` must name a parameter declared by the function signature.",
232+
},
227233
DiagnosticExplanation {
228234
code: code::FILE_MODE_VIOLATION,
229235
title: "file mode violation",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// expect: RS0007
2+
mode: managed
3+
4+
struct Image {
5+
pixels: Buffer
6+
}
7+
8+
fn cache_put(image: read Image) -> Unit
9+
effects(retains(value))
10+
{
11+
return Unit
12+
}

0 commit comments

Comments
 (0)