forked from M-Labs/nac3
[core] Fix resolution of exception names in raise short form
Previous implementation fails as `resolver.get_identifier_def` in ARTIQ would return the exception __init__ function rather than the class. We fix this by limiting the exception class resolution to only include raise statements, and to force the exception name to always be treated as a class. Fixes #501.
This commit is contained in:
parent
d9f96dab33
commit
2b2b2dbf8f
@ -2876,29 +2876,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
|||||||
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
|
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
|
||||||
None => {
|
None => {
|
||||||
let resolver = ctx.resolver.clone();
|
let resolver = ctx.resolver.clone();
|
||||||
if let Some(res) = resolver.get_symbol_value(*id, ctx) {
|
resolver.get_symbol_value(*id, ctx).unwrap()
|
||||||
res
|
|
||||||
} else {
|
|
||||||
// Allow "raise Exception" short form
|
|
||||||
let def_id = resolver.get_identifier_def(*id).map_err(|e| {
|
|
||||||
format!("{} (at {})", e.iter().next().unwrap(), expr.location)
|
|
||||||
})?;
|
|
||||||
let def = ctx.top_level.definitions.read();
|
|
||||||
if let TopLevelDef::Class { constructor, .. } = *def[def_id.0].read() {
|
|
||||||
let TypeEnum::TFunc(signature) =
|
|
||||||
ctx.unifier.get_ty(constructor.unwrap()).as_ref().clone()
|
|
||||||
else {
|
|
||||||
return Err(format!(
|
|
||||||
"Failed to resolve symbol {} (at {})",
|
|
||||||
id, expr.location
|
|
||||||
));
|
|
||||||
};
|
|
||||||
return Ok(generator
|
|
||||||
.gen_call(ctx, None, (&signature, def_id), Vec::default())?
|
|
||||||
.map(Into::into));
|
|
||||||
}
|
|
||||||
return Err(format!("Failed to resolve symbol {} (at {})", id, expr.location));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExprKind::List { elts, .. } => {
|
ExprKind::List { elts, .. } => {
|
||||||
|
@ -1762,7 +1762,30 @@ pub fn gen_stmt<G: CodeGenerator>(
|
|||||||
StmtKind::Try { .. } => gen_try(generator, ctx, stmt)?,
|
StmtKind::Try { .. } => gen_try(generator, ctx, stmt)?,
|
||||||
StmtKind::Raise { exc, .. } => {
|
StmtKind::Raise { exc, .. } => {
|
||||||
if let Some(exc) = exc {
|
if let Some(exc) = exc {
|
||||||
let exc = if let Some(v) = generator.gen_expr(ctx, exc)? {
|
let exn = if let ExprKind::Name { id, .. } = &exc.node {
|
||||||
|
// Handle "raise Exception" short form
|
||||||
|
let def_id = ctx.resolver.get_identifier_def(*id).map_err(|e| {
|
||||||
|
format!("{} (at {})", e.iter().next().unwrap(), exc.location)
|
||||||
|
})?;
|
||||||
|
let def = ctx.top_level.definitions.read();
|
||||||
|
let TopLevelDef::Class { constructor, .. } = *def[def_id.0].read() else {
|
||||||
|
return Err(format!("Failed to resolve symbol {id} (at {})", exc.location));
|
||||||
|
};
|
||||||
|
|
||||||
|
let TypeEnum::TFunc(signature) =
|
||||||
|
ctx.unifier.get_ty(constructor.unwrap()).as_ref().clone()
|
||||||
|
else {
|
||||||
|
return Err(format!("Failed to resolve symbol {id} (at {})", exc.location));
|
||||||
|
};
|
||||||
|
|
||||||
|
generator
|
||||||
|
.gen_call(ctx, None, (&signature, def_id), Vec::default())?
|
||||||
|
.map(Into::into)
|
||||||
|
} else {
|
||||||
|
generator.gen_expr(ctx, exc)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let exc = if let Some(v) = exn {
|
||||||
v.to_basic_value_enum(ctx, generator, exc.custom.unwrap())?
|
v.to_basic_value_enum(ctx, generator, exc.custom.unwrap())?
|
||||||
} else {
|
} else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
Loading…
Reference in New Issue
Block a user