[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
c5ae0e7c36
commit
552dbc02f1
|
@ -2873,29 +2873,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, .. } => {
|
||||||
|
|
|
@ -1760,7 +1760,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