Make is_shadowing_variable() failable

This commit is contained in:
René Kijewski 2022-01-31 08:38:44 +01:00 committed by Dirkjan Ochtman
parent 91874702f0
commit cd744f0aa7
2 changed files with 27 additions and 15 deletions

View File

@ -804,26 +804,38 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
buf.writeln(";")
}
fn is_shadowing_variable(&self, var: &Target<'a>) -> bool {
fn is_shadowing_variable(&self, var: &Target<'a>) -> Result<bool, CompileError> {
match var {
Target::Name(name) => {
let name = normalize_identifier(name);
match self.locals.get(&name) {
// declares a new variable
None => false,
None => Ok(false),
// an initialized variable gets shadowed
Some(meta) if meta.initialized => true,
Some(meta) if meta.initialized => Ok(true),
// initializes a variable that was introduced in a LetDecl before
_ => false,
_ => Ok(false),
}
}
Target::Tuple(_, targets) => targets
.iter()
.any(|target| self.is_shadowing_variable(target)),
Target::Struct(_, named_targets) => named_targets
.iter()
.any(|(_, target)| self.is_shadowing_variable(target)),
_ => panic!("Cannot have literals on the left-hand-side of an assignment."),
Target::Tuple(_, targets) => {
for target in targets {
match self.is_shadowing_variable(target) {
Ok(false) => continue,
outcome => return outcome,
}
}
Ok(false)
}
Target::Struct(_, named_targets) => {
for (_, target) in named_targets {
match self.is_shadowing_variable(target) {
Ok(false) => continue,
outcome => return outcome,
}
}
Ok(false)
}
_ => Err("literals are not allowed on the left-hand side of an assignment".into()),
}
}
@ -838,7 +850,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
let mut expr_buf = Buffer::new(0);
self.visit_expr(&mut expr_buf, val)?;
let shadowed = self.is_shadowing_variable(var);
let shadowed = self.is_shadowing_variable(var)?;
if shadowed {
// Need to flush the buffer if the variable is being shadowed,
// to ensure the old variable is used.

View File

@ -1,7 +1,7 @@
error: proc-macro derive panicked
--> $DIR/lit_on_assignment_lhs.rs:3:10
error: literals are not allowed on the left-hand side of an assignment
--> tests/ui/lit_on_assignment_lhs.rs:3:10
|
3 | #[derive(Template)]
| ^^^^^^^^
|
= help: message: Cannot have literals on the left-hand-side of an assignment.
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)