rtic_macros/syntax/
check.rs

1use std::collections::HashSet;
2
3use syn::parse;
4
5use crate::syntax::ast::App;
6
7pub fn app(app: &App) -> parse::Result<()> {
8    // Check that all referenced resources have been declared
9    // Check that resources are NOT `Exclusive`-ly shared
10    let mut owners = HashSet::new();
11    for (_, name, access) in app.shared_resource_accesses() {
12        if app.shared_resources.get(name).is_none() {
13            return Err(parse::Error::new(
14                name.span(),
15                "this shared resource has NOT been declared",
16            ));
17        }
18
19        if access.is_exclusive() {
20            owners.insert(name);
21        }
22    }
23
24    for name in app.local_resource_accesses() {
25        if app.local_resources.get(name).is_none() {
26            return Err(parse::Error::new(
27                name.span(),
28                "this local resource has NOT been declared",
29            ));
30        }
31    }
32
33    // Check that no resource has both types of access (`Exclusive` & `Shared`)
34    let exclusive_accesses = app
35        .shared_resource_accesses()
36        .filter_map(|(priority, name, access)| {
37            if priority.is_some() && access.is_exclusive() {
38                Some(name)
39            } else {
40                None
41            }
42        })
43        .collect::<HashSet<_>>();
44    for (_, name, access) in app.shared_resource_accesses() {
45        if access.is_shared() && exclusive_accesses.contains(name) {
46            return Err(parse::Error::new(
47                name.span(),
48                "this implementation doesn't support shared (`&-`) - exclusive (`&mut-`) locks; use `x` instead of `&x`",
49            ));
50        }
51    }
52
53    // check that dispatchers are not used as hardware tasks
54    for task in app.hardware_tasks.values() {
55        let binds = &task.args.binds;
56
57        if app.args.dispatchers.contains_key(binds) {
58            return Err(parse::Error::new(
59                binds.span(),
60                "dispatcher interrupts can't be used as hardware tasks",
61            ));
62        }
63    }
64
65    Ok(())
66}