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(";") buf.writeln(";")
} }
fn is_shadowing_variable(&self, var: &Target<'a>) -> bool { fn is_shadowing_variable(&self, var: &Target<'a>) -> Result<bool, CompileError> {
match var { match var {
Target::Name(name) => { Target::Name(name) => {
let name = normalize_identifier(name); let name = normalize_identifier(name);
match self.locals.get(&name) { match self.locals.get(&name) {
// declares a new variable // declares a new variable
None => false, None => Ok(false),
// an initialized variable gets shadowed // 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 // initializes a variable that was introduced in a LetDecl before
_ => false, _ => Ok(false),
} }
} }
Target::Tuple(_, targets) => targets Target::Tuple(_, targets) => {
.iter() for target in targets {
.any(|target| self.is_shadowing_variable(target)), match self.is_shadowing_variable(target) {
Target::Struct(_, named_targets) => named_targets Ok(false) => continue,
.iter() outcome => return outcome,
.any(|(_, target)| self.is_shadowing_variable(target)), }
_ => panic!("Cannot have literals on the left-hand-side of an assignment."), }
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); let mut expr_buf = Buffer::new(0);
self.visit_expr(&mut expr_buf, val)?; self.visit_expr(&mut expr_buf, val)?;
let shadowed = self.is_shadowing_variable(var); let shadowed = self.is_shadowing_variable(var)?;
if shadowed { if shadowed {
// Need to flush the buffer if the variable is being shadowed, // Need to flush the buffer if the variable is being shadowed,
// to ensure the old variable is used. // to ensure the old variable is used.

View File

@ -1,7 +1,7 @@
error: proc-macro derive panicked error: literals are not allowed on the left-hand side of an assignment
--> $DIR/lit_on_assignment_lhs.rs:3:10 --> tests/ui/lit_on_assignment_lhs.rs:3:10
| |
3 | #[derive(Template)] 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)