Skip to content

Commit 29aacea

Browse files
committed
fix: Use a struct ShallowVisitor instead of a trait to avoid
conflicting implementations
1 parent fda3af6 commit 29aacea

2 files changed

Lines changed: 48 additions & 26 deletions

File tree

rusty_linter/src/core/visitor.rs

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,59 @@ where
4646
}
4747
}
4848

49-
/// Indicates a visitor that can visit global statements
49+
/// Creates a delegate visitor for the given type T.
50+
pub trait DelegateVisitor<T> {
51+
fn delegate(&mut self) -> impl Visitor<T>;
52+
}
53+
54+
/// A visitor that can visit global statements
5055
/// but does not enter the implementations of functions or subs.
51-
pub trait ShallowGlobalStatementVisitor:
52-
Visitor<DefType>
53-
+ Visitor<FunctionDeclaration>
54-
+ Visitor<FunctionImplementation>
55-
+ Visitor<Statement>
56-
+ Visitor<SubDeclaration>
57-
+ Visitor<SubImplementation>
58-
+ Visitor<UserDefinedType>
56+
/// Actual visiting logic is handled by the delegate.
57+
pub struct ShallowVisitor<P> {
58+
delegate: P,
59+
}
60+
61+
impl<P> ShallowVisitor<P> {
62+
pub fn new(delegate: P) -> Self {
63+
Self { delegate }
64+
}
65+
66+
/// Returns the delegate back.
67+
pub fn delegate(self) -> P {
68+
self.delegate
69+
}
70+
}
71+
72+
impl<P> SetPosition for ShallowVisitor<P>
73+
where
74+
P: SetPosition,
5975
{
76+
fn set_position(&mut self, pos: Position) {
77+
self.delegate.set_position(pos);
78+
}
6079
}
6180

62-
impl<P> Visitor<GlobalStatement> for P
81+
impl<P> Visitor<GlobalStatement> for ShallowVisitor<P>
6382
where
64-
P: ShallowGlobalStatementVisitor,
83+
P: Visitor<DefType>
84+
+ Visitor<FunctionDeclaration>
85+
+ Visitor<FunctionImplementation>
86+
+ Visitor<Statement>
87+
+ Visitor<SubDeclaration>
88+
+ Visitor<SubImplementation>
89+
+ Visitor<UserDefinedType>,
6590
{
6691
fn visit(&mut self, element: &GlobalStatement) -> VisitResult {
6792
match element {
68-
GlobalStatement::DefType(def_type) => self.visit(def_type),
69-
GlobalStatement::FunctionDeclaration(f) => self.visit(f),
70-
GlobalStatement::FunctionImplementation(f) => self.visit(f),
71-
GlobalStatement::Statement(statement) => self.visit(statement),
72-
GlobalStatement::SubDeclaration(s) => self.visit(s),
73-
GlobalStatement::SubImplementation(s) => self.visit(s),
74-
GlobalStatement::UserDefinedType(user_defined_type) => self.visit(user_defined_type),
93+
GlobalStatement::DefType(def_type) => self.delegate.visit(def_type),
94+
GlobalStatement::FunctionDeclaration(f) => self.delegate.visit(f),
95+
GlobalStatement::FunctionImplementation(f) => self.delegate.visit(f),
96+
GlobalStatement::Statement(statement) => self.delegate.visit(statement),
97+
GlobalStatement::SubDeclaration(s) => self.delegate.visit(s),
98+
GlobalStatement::SubImplementation(s) => self.delegate.visit(s),
99+
GlobalStatement::UserDefinedType(user_defined_type) => {
100+
self.delegate.visit(user_defined_type)
101+
}
75102
}
76103
}
77104
}
78-
79-
pub trait DelegateVisitor<T> {
80-
fn delegate(&mut self) -> impl Visitor<T>;
81-
}

rusty_linter/src/pre_linter/main.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ struct MainContext {
2020
}
2121

2222
pub fn pre_lint_program(program: &Program) -> Result<PreLinterResult, LintErrorPos> {
23-
let mut ctx = MainContext::default();
24-
<MainContext as Visitor<Program>>::visit(&mut ctx, program)?;
23+
let mut visitor = ShallowVisitor::new(MainContext::default());
24+
visitor.visit(program)?;
25+
let ctx = visitor.delegate();
2526
ctx.post_visit_functions()?;
2627
ctx.post_visit_subs()?;
2728
Ok(PreLinterResult::new(
@@ -131,8 +132,6 @@ impl DelegateVisitor<UserDefinedType> for MainContext {
131132
}
132133
}
133134

134-
impl ShallowGlobalStatementVisitor for MainContext {}
135-
136135
impl MainContext {
137136
fn on_parameters(&self, parameters: &Parameters) -> Result<ResolvedParamTypes, LintErrorPos> {
138137
parameters

0 commit comments

Comments
 (0)