Remove unnecessary boxing of ASDL product children

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
This commit is contained in:
Anders Kaseorg 2022-12-11 15:39:47 -08:00
parent 6e89b3ab1a
commit f4672e4256
5 changed files with 15 additions and 17 deletions

View file

@ -89,6 +89,7 @@ class TypeInfo:
self.has_userdata = None self.has_userdata = None
self.children = set() self.children = set()
self.boxed = False self.boxed = False
self.product = False
def __repr__(self): def __repr__(self):
return f"<TypeInfo: {self.name}>" return f"<TypeInfo: {self.name}>"
@ -145,6 +146,7 @@ class FindUserdataTypesVisitor(asdl.VisitorBase):
info.has_userdata = True info.has_userdata = True
if len(product.fields) > 2: if len(product.fields) > 2:
info.boxed = True info.boxed = True
info.product = True
self.add_children(name, product.fields) self.add_children(name, product.fields)
def add_children(self, name, fields): def add_children(self, name, fields):
@ -236,7 +238,7 @@ class StructVisitor(TypeInfoEmitVisitor):
if fieldtype and fieldtype.has_userdata: if fieldtype and fieldtype.has_userdata:
typ = f"{typ}<U>" typ = f"{typ}<U>"
# don't box if we're doing Vec<T>, but do box if we're doing Vec<Option<Box<T>>> # don't box if we're doing Vec<T>, but do box if we're doing Vec<Option<Box<T>>>
if fieldtype and fieldtype.boxed and (not field.seq or field.opt): if fieldtype and fieldtype.boxed and (not (parent.product or field.seq) or field.opt):
typ = f"Box<{typ}>" typ = f"Box<{typ}>"
if field.opt: if field.opt:
typ = f"Option<{typ}>" typ = f"Option<{typ}>"

View file

@ -337,8 +337,8 @@ pub enum Cmpop {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Comprehension<U = ()> { pub struct Comprehension<U = ()> {
pub target: Box<Expr<U>>, pub target: Expr<U>,
pub iter: Box<Expr<U>>, pub iter: Expr<U>,
pub ifs: Vec<Expr<U>>, pub ifs: Vec<Expr<U>>,
pub is_async: usize, pub is_async: usize,
} }
@ -375,7 +375,7 @@ pub type Arg<U = ()> = Located<ArgData<U>, U>;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct KeywordData<U = ()> { pub struct KeywordData<U = ()> {
pub arg: Option<Ident>, pub arg: Option<Ident>,
pub value: Box<Expr<U>>, pub value: Expr<U>,
} }
pub type Keyword<U = ()> = Located<KeywordData<U>, U>; pub type Keyword<U = ()> = Located<KeywordData<U>, U>;
@ -388,13 +388,13 @@ pub type Alias<U = ()> = Located<AliasData, U>;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Withitem<U = ()> { pub struct Withitem<U = ()> {
pub context_expr: Box<Expr<U>>, pub context_expr: Expr<U>,
pub optional_vars: Option<Box<Expr<U>>>, pub optional_vars: Option<Box<Expr<U>>>,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct MatchCase<U = ()> { pub struct MatchCase<U = ()> {
pub pattern: Box<Pattern<U>>, pub pattern: Pattern<U>,
pub guard: Option<Box<Expr<U>>>, pub guard: Option<Box<Expr<U>>>,
pub body: Vec<Stmt<U>>, pub body: Vec<Stmt<U>>,
} }

View file

@ -520,12 +520,12 @@ WithItems: Vec<ast::Withitem> = {
<items:TestAs<ExprOrWithitemsGoal>> =>? items.try_into(), <items:TestAs<ExprOrWithitemsGoal>> =>? items.try_into(),
<first:TestAs<ExprOrWithitemsGoal>> "as" <vars:Expression> =>? { <first:TestAs<ExprOrWithitemsGoal>> "as" <vars:Expression> =>? {
let optional_vars = Some(Box::new(set_context(vars, ast::ExprContext::Store))); let optional_vars = Some(Box::new(set_context(vars, ast::ExprContext::Store)));
let context_expr = Box::new(first.try_into()?); let context_expr = first.try_into()?;
Ok(vec![ast::Withitem { context_expr, optional_vars }]) Ok(vec![ast::Withitem { context_expr, optional_vars }])
}, },
<first:TestAs<ExprOrWithitemsGoal>> <n:("as" Expression)?> "," <mut items:OneOrMore<WithItem>> =>? { <first:TestAs<ExprOrWithitemsGoal>> <n:("as" Expression)?> "," <mut items:OneOrMore<WithItem>> =>? {
let optional_vars = n.map(|val| Box::new(set_context(val.1, ast::ExprContext::Store))); let optional_vars = n.map(|val| Box::new(set_context(val.1, ast::ExprContext::Store)));
let context_expr = Box::new(first.try_into()?); let context_expr = first.try_into()?;
items.insert(0, ast::Withitem { context_expr, optional_vars }); items.insert(0, ast::Withitem { context_expr, optional_vars });
Ok(items) Ok(items)
} }
@ -534,7 +534,6 @@ WithItems: Vec<ast::Withitem> = {
WithItem: ast::Withitem = { WithItem: ast::Withitem = {
<context_expr:Test> <n:("as" Expression)?> => { <context_expr:Test> <n:("as" Expression)?> => {
let optional_vars = n.map(|val| Box::new(set_context(val.1, ast::ExprContext::Store))); let optional_vars = n.map(|val| Box::new(set_context(val.1, ast::ExprContext::Store)));
let context_expr = Box::new(context_expr);
ast::Withitem { context_expr, optional_vars } ast::Withitem { context_expr, optional_vars }
}, },
}; };
@ -1280,8 +1279,8 @@ SingleForComprehension: ast::Comprehension = {
<location:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:OrTest> <ifs:ComprehensionIf*> <end_location:@R> => { <location:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:OrTest> <ifs:ComprehensionIf*> <end_location:@R> => {
let is_async = is_async.is_some(); let is_async = is_async.is_some();
ast::Comprehension { ast::Comprehension {
target: Box::new(set_context(target, ast::ExprContext::Store)), target: set_context(target, ast::ExprContext::Store),
iter: Box::new(iter), iter,
ifs, ifs,
is_async: if is_async { 1 } else { 0 }, is_async: if is_async { 1 } else { 0 },
} }

View file

@ -72,10 +72,7 @@ pub fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ArgumentList, Lexi
keywords.push(ast::Keyword::new( keywords.push(ast::Keyword::new(
start, start,
end, end,
ast::KeywordData { ast::KeywordData { arg: name, value },
arg: name,
value: Box::new(value),
},
)); ));
} }
None => { None => {

View file

@ -117,7 +117,7 @@ impl TryFrom<ExprOrWithitems> for Vec<ast::Withitem> {
.items .items
.into_iter() .into_iter()
.map(|(context_expr, optional_vars)| ast::Withitem { .map(|(context_expr, optional_vars)| ast::Withitem {
context_expr: Box::new(context_expr), context_expr,
optional_vars: optional_vars.map(|expr| { optional_vars: optional_vars.map(|expr| {
Box::new(context::set_context(*expr, ast::ExprContext::Store)) Box::new(context::set_context(*expr, ast::ExprContext::Store))
}), }),
@ -125,7 +125,7 @@ impl TryFrom<ExprOrWithitems> for Vec<ast::Withitem> {
.collect()) .collect())
} }
_ => Ok(vec![ast::Withitem { _ => Ok(vec![ast::Withitem {
context_expr: Box::new(expr_or_withitems.try_into()?), context_expr: expr_or_withitems.try_into()?,
optional_vars: None, optional_vars: None,
}]), }]),
} }