mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 11:55:55 +02:00
Shrink the size of Expr
(#12610)
# Description Continuing from #12568, this PR further reduces the size of `Expr` from 64 to 40 bytes. It also reduces `Expression` from 128 to 96 bytes and `Type` from 32 to 24 bytes. This was accomplished by: - for `Expr` with multiple fields (e.g., `Expr::Thing(A, B, C)`), merging the fields into new AST struct types and then boxing this struct (e.g. `Expr::Thing(Box<ABC>)`). - replacing `Vec<T>` with `Box<[T]>` in multiple places. `Expr`s and `Expression`s should rarely be mutated, if at all, so this optimization makes sense. By reducing the size of these types, I didn't notice a large performance improvement (at least compared to #12568). But this PR does reduce the memory usage of nushell. My config is somewhat light so I only noticed a difference of 1.4MiB (38.9MiB vs 37.5MiB). --------- Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
This commit is contained in:
@ -242,7 +242,7 @@ pub fn flatten_expression(
|
||||
}
|
||||
}
|
||||
|
||||
for arg in args {
|
||||
for arg in args.as_ref() {
|
||||
//output.push((*arg, FlatShape::ExternalArg));
|
||||
match arg {
|
||||
ExternalArgument::Regular(expr) => match expr {
|
||||
@ -297,9 +297,9 @@ pub fn flatten_expression(
|
||||
|
||||
output
|
||||
}
|
||||
Expr::ValueWithUnit(x, unit) => {
|
||||
let mut output = flatten_expression(working_set, x);
|
||||
output.push((unit.span, FlatShape::String));
|
||||
Expr::ValueWithUnit(value) => {
|
||||
let mut output = flatten_expression(working_set, &value.expr);
|
||||
output.push((value.unit.span, FlatShape::String));
|
||||
|
||||
output
|
||||
}
|
||||
@ -346,17 +346,17 @@ pub fn flatten_expression(
|
||||
Expr::Overlay(_) => {
|
||||
vec![(expr.span, FlatShape::String)]
|
||||
}
|
||||
Expr::Range(from, next, to, op) => {
|
||||
Expr::Range(range) => {
|
||||
let mut output = vec![];
|
||||
if let Some(f) = from {
|
||||
if let Some(f) = &range.from {
|
||||
output.extend(flatten_expression(working_set, f));
|
||||
}
|
||||
if let Some(s) = next {
|
||||
output.extend(vec![(op.next_op_span, FlatShape::Operator)]);
|
||||
if let Some(s) = &range.next {
|
||||
output.extend(vec![(range.operator.next_op_span, FlatShape::Operator)]);
|
||||
output.extend(flatten_expression(working_set, s));
|
||||
}
|
||||
output.extend(vec![(op.span, FlatShape::Operator)]);
|
||||
if let Some(t) = to {
|
||||
output.extend(vec![(range.operator.span, FlatShape::Operator)]);
|
||||
if let Some(t) = &range.to {
|
||||
output.extend(flatten_expression(working_set, t));
|
||||
}
|
||||
output
|
||||
@ -495,9 +495,9 @@ pub fn flatten_expression(
|
||||
|
||||
output
|
||||
}
|
||||
Expr::Keyword(_, span, expr) => {
|
||||
let mut output = vec![(*span, FlatShape::Keyword)];
|
||||
output.extend(flatten_expression(working_set, expr));
|
||||
Expr::Keyword(kw) => {
|
||||
let mut output = vec![(kw.span, FlatShape::Keyword)];
|
||||
output.extend(flatten_expression(working_set, &kw.expr));
|
||||
output
|
||||
}
|
||||
Expr::Operator(_) => {
|
||||
@ -509,12 +509,12 @@ pub fn flatten_expression(
|
||||
Expr::String(_) => {
|
||||
vec![(expr.span, FlatShape::String)]
|
||||
}
|
||||
Expr::Table(headers, cells) => {
|
||||
Expr::Table(table) => {
|
||||
let outer_span = expr.span;
|
||||
let mut last_end = outer_span.start;
|
||||
|
||||
let mut output = vec![];
|
||||
for e in headers {
|
||||
for e in table.columns.as_ref() {
|
||||
let flattened = flatten_expression(working_set, e);
|
||||
if let Some(first) = flattened.first() {
|
||||
if first.0.start > last_end {
|
||||
@ -528,8 +528,8 @@ pub fn flatten_expression(
|
||||
|
||||
output.extend(flattened);
|
||||
}
|
||||
for row in cells {
|
||||
for expr in row {
|
||||
for row in table.rows.as_ref() {
|
||||
for expr in row.as_ref() {
|
||||
let flattened = flatten_expression(working_set, expr);
|
||||
if let Some(first) = flattened.first() {
|
||||
if first.0.start > last_end {
|
||||
|
@ -1041,10 +1041,10 @@ pub fn parse_alias(
|
||||
// Then from the command itself
|
||||
true => match alias_call.arguments.get(1) {
|
||||
Some(Argument::Positional(Expression {
|
||||
expr: Expr::Keyword(.., expr),
|
||||
expr: Expr::Keyword(kw),
|
||||
..
|
||||
})) => {
|
||||
let aliased = working_set.get_span_contents(expr.span);
|
||||
let aliased = working_set.get_span_contents(kw.expr.span);
|
||||
(
|
||||
format!("Alias for `{}`", String::from_utf8_lossy(aliased)),
|
||||
String::new(),
|
||||
|
@ -256,8 +256,6 @@ fn parse_external_arg(working_set: &mut StateWorkingSet, span: Span) -> External
|
||||
pub fn parse_external_call(working_set: &mut StateWorkingSet, spans: &[Span]) -> Expression {
|
||||
trace!("parse external");
|
||||
|
||||
let mut args = vec![];
|
||||
|
||||
let head_contents = working_set.get_span_contents(spans[0]);
|
||||
|
||||
let head_span = if head_contents.starts_with(b"^") {
|
||||
@ -286,10 +284,10 @@ pub fn parse_external_call(working_set: &mut StateWorkingSet, spans: &[Span]) ->
|
||||
})
|
||||
};
|
||||
|
||||
for span in &spans[1..] {
|
||||
let arg = parse_external_arg(working_set, *span);
|
||||
args.push(arg);
|
||||
}
|
||||
let args = spans[1..]
|
||||
.iter()
|
||||
.map(|&span| parse_external_arg(working_set, span))
|
||||
.collect();
|
||||
|
||||
Expression {
|
||||
expr: Expr::ExternalCall(head, args),
|
||||
@ -695,25 +693,29 @@ pub fn parse_multispan_value(
|
||||
String::from_utf8_lossy(keyword).into(),
|
||||
Span::new(spans[*spans_idx - 1].end, spans[*spans_idx - 1].end),
|
||||
));
|
||||
let keyword = Keyword {
|
||||
keyword: keyword.as_slice().into(),
|
||||
span: spans[*spans_idx - 1],
|
||||
expr: Expression::garbage(arg_span),
|
||||
};
|
||||
return Expression {
|
||||
expr: Expr::Keyword(
|
||||
keyword.clone(),
|
||||
spans[*spans_idx - 1],
|
||||
Box::new(Expression::garbage(arg_span)),
|
||||
),
|
||||
expr: Expr::Keyword(Box::new(keyword)),
|
||||
span: arg_span,
|
||||
ty: Type::Any,
|
||||
custom_completion: None,
|
||||
};
|
||||
}
|
||||
let keyword_span = spans[*spans_idx - 1];
|
||||
let expr = parse_multispan_value(working_set, spans, spans_idx, arg);
|
||||
let ty = expr.ty.clone();
|
||||
|
||||
let keyword = Keyword {
|
||||
keyword: keyword.as_slice().into(),
|
||||
span: spans[*spans_idx - 1],
|
||||
expr: parse_multispan_value(working_set, spans, spans_idx, arg),
|
||||
};
|
||||
|
||||
Expression {
|
||||
expr: Expr::Keyword(keyword.clone(), keyword_span, Box::new(expr)),
|
||||
ty: keyword.expr.ty.clone(),
|
||||
expr: Expr::Keyword(Box::new(keyword)),
|
||||
span: arg_span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
}
|
||||
}
|
||||
@ -1128,18 +1130,17 @@ pub fn parse_call(working_set: &mut StateWorkingSet, spans: &[Span], head: Span)
|
||||
{
|
||||
trace!("parsing: alias of external call");
|
||||
|
||||
let mut final_args = args.clone();
|
||||
let mut head = head.clone();
|
||||
head.span = spans[0]; // replacing the spans preserves syntax highlighting
|
||||
|
||||
for arg_span in spans.iter().skip(1) {
|
||||
let mut final_args = args.clone().into_vec();
|
||||
for arg_span in &spans[1..] {
|
||||
let arg = parse_external_arg(working_set, *arg_span);
|
||||
final_args.push(arg);
|
||||
}
|
||||
|
||||
let mut head = head.clone();
|
||||
head.span = spans[0]; // replacing the spans preserves syntax highlighting
|
||||
|
||||
return Expression {
|
||||
expr: Expr::ExternalCall(head, final_args),
|
||||
expr: Expr::ExternalCall(head, final_args.into()),
|
||||
span: span(spans),
|
||||
ty: ty.clone(),
|
||||
custom_completion: *custom_completion,
|
||||
@ -1493,22 +1494,14 @@ pub fn parse_range(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
None
|
||||
} else {
|
||||
let from_span = Span::new(span.start, span.start + dotdot_pos[0]);
|
||||
Some(Box::new(parse_value(
|
||||
working_set,
|
||||
from_span,
|
||||
&SyntaxShape::Number,
|
||||
)))
|
||||
Some(parse_value(working_set, from_span, &SyntaxShape::Number))
|
||||
};
|
||||
|
||||
let to = if token.ends_with(range_op_str) {
|
||||
None
|
||||
} else {
|
||||
let to_span = Span::new(range_op_span.end, span.end);
|
||||
Some(Box::new(parse_value(
|
||||
working_set,
|
||||
to_span,
|
||||
&SyntaxShape::Number,
|
||||
)))
|
||||
Some(parse_value(working_set, to_span, &SyntaxShape::Number))
|
||||
};
|
||||
|
||||
trace!("-- from: {:?} to: {:?}", from, to);
|
||||
@ -1523,25 +1516,28 @@ pub fn parse_range(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
let next_span = Span::new(next_op_span.end, range_op_span.start);
|
||||
|
||||
(
|
||||
Some(Box::new(parse_value(
|
||||
working_set,
|
||||
next_span,
|
||||
&SyntaxShape::Number,
|
||||
))),
|
||||
Some(parse_value(working_set, next_span, &SyntaxShape::Number)),
|
||||
next_op_span,
|
||||
)
|
||||
} else {
|
||||
(None, span)
|
||||
};
|
||||
|
||||
let range_op = RangeOperator {
|
||||
let operator = RangeOperator {
|
||||
inclusion,
|
||||
span: range_op_span,
|
||||
next_op_span,
|
||||
};
|
||||
|
||||
let range = Range {
|
||||
from,
|
||||
next,
|
||||
to,
|
||||
operator,
|
||||
};
|
||||
|
||||
Expression {
|
||||
expr: Expr::Range(from, next, to, range_op),
|
||||
expr: Expr::Range(Box::new(range)),
|
||||
span,
|
||||
ty: Type::Range,
|
||||
custom_completion: None,
|
||||
@ -2317,19 +2313,20 @@ pub fn parse_unit_value<'res>(
|
||||
};
|
||||
|
||||
trace!("-- found {} {:?}", num, unit);
|
||||
let value = ValueWithUnit {
|
||||
expr: Expression {
|
||||
expr: Expr::Int(num),
|
||||
span: lhs_span,
|
||||
ty: Type::Number,
|
||||
custom_completion: None,
|
||||
},
|
||||
unit: Spanned {
|
||||
item: unit,
|
||||
span: unit_span,
|
||||
},
|
||||
};
|
||||
let expr = Expression {
|
||||
expr: Expr::ValueWithUnit(
|
||||
Box::new(Expression {
|
||||
expr: Expr::Int(num),
|
||||
span: lhs_span,
|
||||
ty: Type::Number,
|
||||
custom_completion: None,
|
||||
}),
|
||||
Spanned {
|
||||
item: unit,
|
||||
span: unit_span,
|
||||
},
|
||||
),
|
||||
expr: Expr::ValueWithUnit(Box::new(value)),
|
||||
span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
@ -4007,11 +4004,16 @@ fn parse_table_expression(working_set: &mut StateWorkingSet, span: Span) -> Expr
|
||||
working_set.parse_errors.extend(errs);
|
||||
ty
|
||||
} else {
|
||||
Type::Table(vec![])
|
||||
Type::table()
|
||||
};
|
||||
|
||||
let table = Table {
|
||||
columns: head.into(),
|
||||
rows: rows.into_iter().map(Into::into).collect(),
|
||||
};
|
||||
|
||||
Expression {
|
||||
expr: Expr::Table(head, rows),
|
||||
expr: Expr::Table(table),
|
||||
span,
|
||||
ty,
|
||||
custom_completion: None,
|
||||
@ -4057,7 +4059,7 @@ fn table_type(head: &[Expression], rows: &[Vec<Expression>]) -> (Type, Vec<Parse
|
||||
|
||||
ty.reverse();
|
||||
|
||||
(Type::Table(ty), errors)
|
||||
(Type::Table(ty.into()), errors)
|
||||
}
|
||||
|
||||
pub fn parse_block_expression(working_set: &mut StateWorkingSet, span: Span) -> Expression {
|
||||
@ -5371,7 +5373,7 @@ pub fn parse_record(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
match &inner.ty {
|
||||
Type::Record(inner_fields) => {
|
||||
if let Some(fields) = &mut field_types {
|
||||
for (field, ty) in inner_fields {
|
||||
for (field, ty) in inner_fields.as_ref() {
|
||||
fields.push((field.clone(), ty.clone()));
|
||||
}
|
||||
}
|
||||
@ -5450,7 +5452,7 @@ pub fn parse_record(working_set: &mut StateWorkingSet, span: Span) -> Expression
|
||||
expr: Expr::Record(output),
|
||||
span,
|
||||
ty: (if let Some(fields) = field_types {
|
||||
Type::Record(fields)
|
||||
Type::Record(fields.into())
|
||||
} else {
|
||||
Type::Any
|
||||
}),
|
||||
@ -5988,7 +5990,7 @@ pub fn discover_captures_in_expr(
|
||||
Expr::ExternalCall(head, args) => {
|
||||
discover_captures_in_expr(working_set, head, seen, seen_blocks, output)?;
|
||||
|
||||
for ExternalArgument::Regular(expr) | ExternalArgument::Spread(expr) in args {
|
||||
for ExternalArgument::Regular(expr) | ExternalArgument::Spread(expr) in args.as_ref() {
|
||||
discover_captures_in_expr(working_set, expr, seen, seen_blocks, output)?;
|
||||
}
|
||||
}
|
||||
@ -6004,8 +6006,8 @@ pub fn discover_captures_in_expr(
|
||||
Expr::Nothing => {}
|
||||
Expr::GlobPattern(_, _) => {}
|
||||
Expr::Int(_) => {}
|
||||
Expr::Keyword(_, _, expr) => {
|
||||
discover_captures_in_expr(working_set, expr, seen, seen_blocks, output)?;
|
||||
Expr::Keyword(kw) => {
|
||||
discover_captures_in_expr(working_set, &kw.expr, seen, seen_blocks, output)?;
|
||||
}
|
||||
Expr::List(list) => {
|
||||
for item in list {
|
||||
@ -6013,15 +6015,15 @@ pub fn discover_captures_in_expr(
|
||||
}
|
||||
}
|
||||
Expr::Operator(_) => {}
|
||||
Expr::Range(expr1, expr2, expr3, _) => {
|
||||
if let Some(expr) = expr1 {
|
||||
discover_captures_in_expr(working_set, expr, seen, seen_blocks, output)?;
|
||||
Expr::Range(range) => {
|
||||
if let Some(from) = &range.from {
|
||||
discover_captures_in_expr(working_set, from, seen, seen_blocks, output)?;
|
||||
}
|
||||
if let Some(expr) = expr2 {
|
||||
discover_captures_in_expr(working_set, expr, seen, seen_blocks, output)?;
|
||||
if let Some(next) = &range.next {
|
||||
discover_captures_in_expr(working_set, next, seen, seen_blocks, output)?;
|
||||
}
|
||||
if let Some(expr) = expr3 {
|
||||
discover_captures_in_expr(working_set, expr, seen, seen_blocks, output)?;
|
||||
if let Some(to) = &range.to {
|
||||
discover_captures_in_expr(working_set, to, seen, seen_blocks, output)?;
|
||||
}
|
||||
}
|
||||
Expr::Record(items) => {
|
||||
@ -6107,18 +6109,18 @@ pub fn discover_captures_in_expr(
|
||||
}
|
||||
}
|
||||
}
|
||||
Expr::Table(headers, values) => {
|
||||
for header in headers {
|
||||
Expr::Table(table) => {
|
||||
for header in table.columns.as_ref() {
|
||||
discover_captures_in_expr(working_set, header, seen, seen_blocks, output)?;
|
||||
}
|
||||
for row in values {
|
||||
for cell in row {
|
||||
for row in table.rows.as_ref() {
|
||||
for cell in row.as_ref() {
|
||||
discover_captures_in_expr(working_set, cell, seen, seen_blocks, output)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Expr::ValueWithUnit(expr, _) => {
|
||||
discover_captures_in_expr(working_set, expr, seen, seen_blocks, output)?;
|
||||
Expr::ValueWithUnit(value) => {
|
||||
discover_captures_in_expr(working_set, &value.expr, seen, seen_blocks, output)?;
|
||||
}
|
||||
Expr::Var(var_id) => {
|
||||
if (*var_id > ENV_VARIABLE_ID || *var_id == IN_VARIABLE_ID) && !seen.contains(var_id) {
|
||||
|
@ -90,8 +90,8 @@ pub fn math_result_type(
|
||||
(Type::Duration, Type::Duration) => (Type::Duration, None),
|
||||
(Type::Filesize, Type::Filesize) => (Type::Filesize, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
@ -146,8 +146,8 @@ pub fn math_result_type(
|
||||
(Type::Duration, Type::Duration) => (Type::Duration, None),
|
||||
(Type::Filesize, Type::Filesize) => (Type::Filesize, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
@ -197,8 +197,8 @@ pub fn math_result_type(
|
||||
(Type::Duration, Type::Float) => (Type::Duration, None),
|
||||
(Type::Float, Type::Duration) => (Type::Duration, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
@ -246,8 +246,8 @@ pub fn math_result_type(
|
||||
(Type::Number, Type::Float) => (Type::Number, None),
|
||||
(Type::Float, Type::Number) => (Type::Number, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
@ -296,8 +296,8 @@ pub fn math_result_type(
|
||||
(Type::Duration, Type::Int) => (Type::Duration, None),
|
||||
(Type::Duration, Type::Float) => (Type::Duration, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
@ -380,10 +380,8 @@ pub fn math_result_type(
|
||||
match (&lhs.ty, &rhs.ty) {
|
||||
(Type::Bool, Type::Bool) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => {
|
||||
(Type::Custom(a.to_string()), None)
|
||||
}
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Any, None),
|
||||
(_, Type::Any) => (Type::Any, None),
|
||||
@ -434,8 +432,8 @@ pub fn math_result_type(
|
||||
(Type::Date, Type::Date) => (Type::Bool, None),
|
||||
(Type::Filesize, Type::Filesize) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Nothing, _) => (Type::Nothing, None),
|
||||
(_, Type::Nothing) => (Type::Nothing, None),
|
||||
@ -484,8 +482,8 @@ pub fn math_result_type(
|
||||
(Type::Date, Type::Date) => (Type::Bool, None),
|
||||
(Type::Filesize, Type::Filesize) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Nothing, _) => (Type::Nothing, None),
|
||||
(_, Type::Nothing) => (Type::Nothing, None),
|
||||
@ -534,8 +532,8 @@ pub fn math_result_type(
|
||||
(Type::Date, Type::Date) => (Type::Bool, None),
|
||||
(Type::Filesize, Type::Filesize) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
@ -584,8 +582,8 @@ pub fn math_result_type(
|
||||
(Type::Date, Type::Date) => (Type::Bool, None),
|
||||
(Type::Filesize, Type::Filesize) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
@ -620,14 +618,14 @@ pub fn math_result_type(
|
||||
}
|
||||
},
|
||||
Operator::Comparison(Comparison::Equal) => match (&lhs.ty, &rhs.ty) {
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
_ => (Type::Bool, None),
|
||||
},
|
||||
Operator::Comparison(Comparison::NotEqual) => match (&lhs.ty, &rhs.ty) {
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
_ => (Type::Bool, None),
|
||||
},
|
||||
@ -636,8 +634,8 @@ pub fn math_result_type(
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::String, _) => {
|
||||
*op = Expression::garbage(op.span);
|
||||
@ -671,8 +669,8 @@ pub fn math_result_type(
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::String, _) => {
|
||||
*op = Expression::garbage(op.span);
|
||||
@ -706,8 +704,8 @@ pub fn math_result_type(
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::String, _) => {
|
||||
*op = Expression::garbage(op.span);
|
||||
@ -741,8 +739,8 @@ pub fn math_result_type(
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::String, _) => {
|
||||
*op = Expression::garbage(op.span);
|
||||
@ -777,8 +775,8 @@ pub fn math_result_type(
|
||||
(Type::String, Type::String) => (Type::Bool, None),
|
||||
(Type::String, Type::Record(_)) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
@ -815,8 +813,8 @@ pub fn math_result_type(
|
||||
(Type::String, Type::String) => (Type::Bool, None),
|
||||
(Type::String, Type::Record(_)) => (Type::Bool, None),
|
||||
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.to_string()), None),
|
||||
(Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.clone()), None),
|
||||
(Type::Custom(a), _) => (Type::Custom(a.clone()), None),
|
||||
|
||||
(Type::Any, _) => (Type::Bool, None),
|
||||
(_, Type::Any) => (Type::Bool, None),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use nu_parser::*;
|
||||
use nu_protocol::{
|
||||
ast::{Argument, Call, Expr, PathMember},
|
||||
ast::{Argument, Call, Expr, PathMember, Range},
|
||||
engine::{Command, EngineState, Stack, StateWorkingSet},
|
||||
ParseError, PipelineData, ShellError, Signature, Span, SyntaxShape,
|
||||
};
|
||||
@ -311,7 +311,7 @@ pub fn parse_cell_path() {
|
||||
working_set.add_variable(
|
||||
"foo".to_string().into_bytes(),
|
||||
Span::test_data(),
|
||||
nu_protocol::Type::Record(vec![]),
|
||||
nu_protocol::Type::record(),
|
||||
false,
|
||||
);
|
||||
|
||||
@ -356,7 +356,7 @@ pub fn parse_cell_path_optional() {
|
||||
working_set.add_variable(
|
||||
"foo".to_string().into_bytes(),
|
||||
Span::test_data(),
|
||||
nu_protocol::Type::Record(vec![]),
|
||||
nu_protocol::Type::record(),
|
||||
false,
|
||||
);
|
||||
|
||||
@ -986,20 +986,25 @@ mod range {
|
||||
assert_eq!(pipeline.len(), 1, "{tag}: expression length");
|
||||
let element = &pipeline.elements[0];
|
||||
assert!(element.redirection.is_none());
|
||||
if let Expr::Range(
|
||||
Some(_),
|
||||
None,
|
||||
Some(_),
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
) = element.expr.expr
|
||||
{
|
||||
assert_eq!(
|
||||
the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
if let Expr::Range(range) = &element.expr.expr {
|
||||
if let Range {
|
||||
from: Some(_),
|
||||
next: None,
|
||||
to: Some(_),
|
||||
operator:
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
} = range.as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
*the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
}
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
};
|
||||
@ -1040,20 +1045,25 @@ mod range {
|
||||
assert_eq!(pipeline.len(), 1, "{tag}: expression length 1");
|
||||
let element = &pipeline.elements[0];
|
||||
assert!(element.redirection.is_none());
|
||||
if let Expr::Range(
|
||||
Some(_),
|
||||
None,
|
||||
Some(_),
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
) = element.expr.expr
|
||||
{
|
||||
assert_eq!(
|
||||
the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
if let Expr::Range(range) = &element.expr.expr {
|
||||
if let Range {
|
||||
from: Some(_),
|
||||
next: None,
|
||||
to: Some(_),
|
||||
operator:
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
} = range.as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
*the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
}
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
};
|
||||
@ -1081,20 +1091,25 @@ mod range {
|
||||
assert_eq!(pipeline.len(), 1, "{tag}: expression length");
|
||||
let element = &pipeline.elements[0];
|
||||
assert!(element.redirection.is_none());
|
||||
if let Expr::Range(
|
||||
Some(_),
|
||||
None,
|
||||
None,
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
) = element.expr.expr
|
||||
{
|
||||
assert_eq!(
|
||||
the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
if let Expr::Range(range) = &element.expr.expr {
|
||||
if let Range {
|
||||
from: Some(_),
|
||||
next: None,
|
||||
to: None,
|
||||
operator:
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
} = range.as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
*the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
}
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
};
|
||||
@ -1122,20 +1137,25 @@ mod range {
|
||||
assert_eq!(pipeline.len(), 1, "{tag}: expression length");
|
||||
let element = &pipeline.elements[0];
|
||||
assert!(element.redirection.is_none());
|
||||
if let Expr::Range(
|
||||
None,
|
||||
None,
|
||||
Some(_),
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
) = element.expr.expr
|
||||
{
|
||||
assert_eq!(
|
||||
the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
if let Expr::Range(range) = &element.expr.expr {
|
||||
if let Range {
|
||||
from: None,
|
||||
next: None,
|
||||
to: Some(_),
|
||||
operator:
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
} = range.as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
*the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
}
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
};
|
||||
@ -1163,20 +1183,25 @@ mod range {
|
||||
assert_eq!(pipeline.len(), 1, "{tag}: expression length");
|
||||
let element = &pipeline.elements[0];
|
||||
assert!(element.redirection.is_none());
|
||||
if let Expr::Range(
|
||||
Some(_),
|
||||
Some(_),
|
||||
Some(_),
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
) = element.expr.expr
|
||||
{
|
||||
assert_eq!(
|
||||
the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
if let Expr::Range(range) = &element.expr.expr {
|
||||
if let Range {
|
||||
from: Some(_),
|
||||
next: Some(_),
|
||||
to: Some(_),
|
||||
operator:
|
||||
RangeOperator {
|
||||
inclusion: the_inclusion,
|
||||
..
|
||||
},
|
||||
} = range.as_ref()
|
||||
{
|
||||
assert_eq!(
|
||||
*the_inclusion, inclusion,
|
||||
"{tag}: wrong RangeInclusion {the_inclusion:?}"
|
||||
);
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
}
|
||||
} else {
|
||||
panic!("{tag}: expression mismatch.")
|
||||
};
|
||||
|
Reference in New Issue
Block a user