Replace &Span with Span since Span is Copy (#9770)

# Description
`Span` is `Copy`, so we probably should not be passing references of
`Span` around. This PR replaces all instances of `&Span` with `Span`,
copying spans where necessary.

# User-Facing Changes
This alters some public functions to take `Span` instead of `&Span` as
input. Namely, `EngineState::get_span_contents`,
`nu_protocol::extract_value`, a bunch of the math commands, and
`Gstat::gstat`.
This commit is contained in:
Ian Manske
2023-07-31 19:47:46 +00:00
committed by GitHub
parent 94bec72079
commit 583ef8674e
35 changed files with 356 additions and 365 deletions

View File

@ -70,10 +70,10 @@ pub fn get_pipeline_elements(
while i < pipeline.elements.len() {
let pipeline_element = &pipeline.elements[i];
let pipeline_expression = pipeline_element.expression().clone();
let pipeline_span = &pipeline_element.span();
let pipeline_span = pipeline_element.span();
let element_str =
String::from_utf8_lossy(engine_state.get_span_contents(pipeline_span));
let value = Value::string(element_str.to_string(), *pipeline_span);
let value = Value::string(element_str.to_string(), pipeline_span);
let expr = pipeline_expression.expr.clone();
let (command_name, command_args_value) = if let Expr::Call(call) = expr {
let command = engine_state.get_decl(call.decl_id);

View File

@ -41,7 +41,7 @@ impl Command for ViewSource {
let block = engine_state.get_block(block_id);
if let Some(span) = block.span {
let contents = engine_state.get_span_contents(&span);
let contents = engine_state.get_span_contents(span);
Ok(Value::string(String::from_utf8_lossy(contents), call.head)
.into_pipeline_data())
} else {
@ -61,7 +61,7 @@ impl Command for ViewSource {
if let Some(block_id) = decl.get_block_id() {
let block = engine_state.get_block(block_id);
if let Some(block_span) = block.span {
let contents = engine_state.get_span_contents(&block_span);
let contents = engine_state.get_span_contents(block_span);
// name of function
let mut final_contents = format!("def {val} [ ");
for n in vec_of_required {
@ -117,7 +117,7 @@ impl Command for ViewSource {
// arg is a module
let module = engine_state.get_module(module_id);
if let Some(module_span) = module.span {
let contents = engine_state.get_span_contents(&module_span);
let contents = engine_state.get_span_contents(module_span);
Ok(Value::string(String::from_utf8_lossy(contents), call.head)
.into_pipeline_data())
} else {

View File

@ -42,7 +42,7 @@ impl Command for ViewSpan {
if start_span.item < end_span.item {
let bin_contents =
engine_state.get_span_contents(&Span::new(start_span.item, end_span.item));
engine_state.get_span_contents(Span::new(start_span.item, end_span.item));
Ok(
Value::string(String::from_utf8_lossy(bin_contents), call.head)
.into_pipeline_data(),

View File

@ -295,7 +295,7 @@ fn highlight_terms_in_record_with_search_columns(
search_cols: &Vec<String>,
cols: &[String],
vals: &[Value],
span: &Span,
span: Span,
config: &Config,
terms: &[Value],
string_style: Style,
@ -332,7 +332,7 @@ fn highlight_terms_in_record_with_search_columns(
Value::String {
val: highlighted_str,
span: *span,
span,
}
})
.map(|v| v.unwrap_or_else(|v| v));
@ -340,7 +340,7 @@ fn highlight_terms_in_record_with_search_columns(
Value::Record {
cols: cols.to_vec(),
vals: new_vals.collect(),
span: *span,
span,
}
}
@ -397,7 +397,7 @@ fn find_with_rest_and_highlight(
&cols_to_search_in_map,
cols,
vals,
span,
*span,
&config,
&terms,
string_style,
@ -414,7 +414,7 @@ fn find_with_rest_and_highlight(
value,
&filter_config,
&lower_terms,
&span,
span,
&cols_to_search_in_filter,
invert,
)
@ -429,7 +429,7 @@ fn find_with_rest_and_highlight(
&cols_to_search_in_map,
cols,
vals,
span,
*span,
&config,
&terms,
string_style,
@ -443,7 +443,7 @@ fn find_with_rest_and_highlight(
value,
&filter_config,
&lower_terms,
&span,
span,
&cols_to_search_in_filter,
invert,
)
@ -509,7 +509,7 @@ fn value_should_be_printed(
value: &Value,
filter_config: &Config,
lower_terms: &[Value],
span: &Span,
span: Span,
columns_to_search: &Vec<String>,
invert: bool,
) -> bool {
@ -556,13 +556,13 @@ fn value_should_be_printed(
match_found
}
fn term_contains_value(term: &Value, value: &Value, span: &Span) -> bool {
term.r#in(*span, value, *span)
fn term_contains_value(term: &Value, value: &Value, span: Span) -> bool {
term.r#in(span, value, span)
.map_or(false, |value| value.is_true())
}
fn term_equals_value(term: &Value, value: &Value, span: &Span) -> bool {
term.eq(*span, value, *span)
fn term_equals_value(term: &Value, value: &Value, span: Span) -> bool {
term.eq(span, value, span)
.map_or(false, |value| value.is_true())
}
@ -572,7 +572,7 @@ fn record_matches_term(
columns_to_search: &Vec<String>,
filter_config: &Config,
term: &Value,
span: &Span,
span: Span,
) -> bool {
let cols_to_search = if columns_to_search.is_empty() {
cols.to_vec()

View File

@ -12,9 +12,9 @@ fn from_value_to_delimited_string(
) -> Result<String, ShellError> {
match value {
Value::Record { cols, vals, span } => {
record_to_delimited(cols, vals, span, separator, config, head)
record_to_delimited(cols, vals, *span, separator, config, head)
}
Value::List { vals, span } => table_to_delimited(vals, span, separator, config, head),
Value::List { vals, span } => table_to_delimited(vals, *span, separator, config, head),
// Propagate errors by explicitly matching them before the final case.
Value::Error { error } => Err(*error.clone()),
v => Err(make_unsupported_input_error(v, head, v.expect_span())),
@ -24,7 +24,7 @@ fn from_value_to_delimited_string(
fn record_to_delimited(
cols: &[String],
vals: &[Value],
span: &Span,
span: Span,
separator: char,
config: &Config,
head: Span,
@ -38,7 +38,7 @@ fn record_to_delimited(
for (k, v) in cols.iter().zip(vals.iter()) {
fields.push_back(k.clone());
values.push_back(to_string_tagged_value(v, config, head, *span)?);
values.push_back(to_string_tagged_value(v, config, head, span)?);
}
wtr.write_record(fields).expect("can not write.");
@ -49,13 +49,13 @@ fn record_to_delimited(
fn table_to_delimited(
vals: &Vec<Value>,
span: &Span,
span: Span,
separator: char,
config: &Config,
head: Span,
) -> Result<String, ShellError> {
if let Some(val) = find_non_record(vals) {
return Err(make_unsupported_input_error(val, head, *span));
return Err(make_unsupported_input_error(val, head, span));
}
let mut wtr = WriterBuilder::new()
@ -68,7 +68,7 @@ fn table_to_delimited(
let vals = vals
.iter()
.map(|ele| {
to_string_tagged_value(ele, config, head, *span).unwrap_or_else(|_| String::new())
to_string_tagged_value(ele, config, head, span).unwrap_or_else(|_| String::new())
})
.collect::<Vec<_>>();
wtr.write_record(vals).expect("can not write");
@ -80,7 +80,7 @@ fn table_to_delimited(
let mut row = vec![];
for desc in &merged_descriptors {
row.push(match l.to_owned().get_data_by_key(desc) {
Some(s) => to_string_tagged_value(&s, config, head, *span)?,
Some(s) => to_string_tagged_value(&s, config, head, span)?,
None => String::new(),
});
}
@ -94,11 +94,11 @@ fn writer_to_string(writer: Writer<Vec<u8>>) -> Result<String, Box<dyn Error>> {
Ok(String::from_utf8(writer.into_inner()?)?)
}
fn make_conversion_error(type_from: &str, span: &Span) -> ShellError {
fn make_conversion_error(type_from: &str, span: Span) -> ShellError {
ShellError::CantConvert {
to_type: type_from.to_string(),
from_type: "string".to_string(),
span: *span,
span,
help: None,
}
}

View File

@ -67,12 +67,12 @@ fn helper(engine_state: &EngineState, v: &Value) -> Result<toml::Value, ShellErr
}
Value::List { vals, .. } => toml::Value::Array(toml_list(engine_state, vals)?),
Value::Block { span, .. } => {
let code = engine_state.get_span_contents(span);
let code = engine_state.get_span_contents(*span);
let code = String::from_utf8_lossy(code).to_string();
toml::Value::String(code)
}
Value::Closure { span, .. } => {
let code = engine_state.get_span_contents(span);
let code = engine_state.get_span_contents(*span);
let code = String::from_utf8_lossy(code).to_string();
toml::Value::String(code)
}

View File

@ -131,7 +131,7 @@ pub fn help_aliases(
};
let alias_expansion =
String::from_utf8_lossy(engine_state.get_span_contents(&alias.wrapped_call.span));
String::from_utf8_lossy(engine_state.get_span_contents(alias.wrapped_call.span));
let usage = alias.usage();
let extra_usage = alias.extra_usage();

View File

@ -50,9 +50,9 @@ impl Command for SubCommand {
}
}
pub fn average(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellError> {
pub fn average(values: &[Value], span: Span, head: Span) -> Result<Value, ShellError> {
let sum = reducer_for(Reduce::Summation);
let total = &sum(Value::int(0, *head), values.to_vec(), span, *head)?;
let total = &sum(Value::int(0, head), values.to_vec(), span, head)?;
match total {
Value::Filesize { val, span } => Ok(Value::Filesize {
val: val / values.len() as i64,
@ -62,7 +62,7 @@ pub fn average(values: &[Value], span: Span, head: &Span) -> Result<Value, Shell
val: val / values.len() as i64,
span: *span,
}),
_ => total.div(*head, &Value::int(values.len() as i64, *head), *head),
_ => total.div(head, &Value::int(values.len() as i64, head), head),
}
}

View File

@ -60,9 +60,9 @@ impl Command for SubCommand {
}
}
pub fn maximum(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellError> {
pub fn maximum(values: &[Value], span: Span, head: Span) -> Result<Value, ShellError> {
let max_func = reducer_for(Reduce::Maximum);
max_func(Value::nothing(*head), values.to_vec(), span, *head)
max_func(Value::nothing(head), values.to_vec(), span, head)
}
#[cfg(test)]

View File

@ -69,7 +69,7 @@ enum Pick {
Median,
}
pub fn median(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellError> {
pub fn median(values: &[Value], span: Span, head: Span) -> Result<Value, ShellError> {
let take = if values.len() % 2 == 0 {
Pick::MedianAverage
} else {
@ -87,7 +87,7 @@ pub fn median(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellE
.map(|elem| {
if elem[0].partial_cmp(&elem[1]).is_none() {
return Err(ShellError::OperatorMismatch {
op_span: *head,
op_span: head,
lhs_ty: elem[0].get_type().to_string(),
lhs_span: elem[0].span()?,
rhs_ty: elem[1].get_type().to_string(),
@ -110,7 +110,7 @@ pub fn median(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellE
ShellError::UnsupportedInput(
"Empty input".to_string(),
"value originates from here".into(),
*head,
head,
span,
)
})?;
@ -126,7 +126,7 @@ pub fn median(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellE
ShellError::UnsupportedInput(
"Empty input".to_string(),
"value originates from here".into(),
*head,
head,
span,
)
})?
@ -138,7 +138,7 @@ pub fn median(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellE
ShellError::UnsupportedInput(
"Empty input".to_string(),
"value originates from here".into(),
*head,
head,
span,
)
})?

View File

@ -65,9 +65,9 @@ impl Command for SubCommand {
}
}
pub fn minimum(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellError> {
pub fn minimum(values: &[Value], span: Span, head: Span) -> Result<Value, ShellError> {
let min_func = reducer_for(Reduce::Minimum);
min_func(Value::nothing(*head), values.to_vec(), span, *head)
min_func(Value::nothing(head), values.to_vec(), span, head)
}
#[cfg(test)]

View File

@ -107,13 +107,13 @@ impl Command for SubCommand {
}
}
pub fn mode(values: &[Value], _span: Span, head: &Span) -> Result<Value, ShellError> {
pub fn mode(values: &[Value], _span: Span, head: Span) -> Result<Value, ShellError> {
if let Some(Err(values)) = values
.windows(2)
.map(|elem| {
if elem[0].partial_cmp(&elem[1]).is_none() {
return Err(ShellError::OperatorMismatch {
op_span: *head,
op_span: head,
lhs_ty: elem[0].get_type().to_string(),
lhs_span: elem[0].span()?,
rhs_ty: elem[1].get_type().to_string(),
@ -146,7 +146,7 @@ pub fn mode(values: &[Value], _span: Span, head: &Span) -> Result<Value, ShellEr
other => Err(ShellError::UnsupportedInput(
"Unable to give a result with this input".to_string(),
"value originates from here".into(),
*head,
head,
other.expect_span(),
)),
})
@ -165,10 +165,10 @@ pub fn mode(values: &[Value], _span: Span, head: &Span) -> Result<Value, ShellEr
Ordering::Less => {
max_freq = *frequency;
modes.clear();
modes.push(recreate_value(value, *head));
modes.push(recreate_value(value, head));
}
Ordering::Equal => {
modes.push(recreate_value(value, *head));
modes.push(recreate_value(value, head));
}
Ordering::Greater => (),
}
@ -177,7 +177,7 @@ pub fn mode(values: &[Value], _span: Span, head: &Span) -> Result<Value, ShellEr
modes.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
Ok(Value::List {
vals: modes,
span: *head,
span: head,
})
}

View File

@ -46,9 +46,9 @@ impl Command for SubCommand {
}
/// Calculate product of given values
pub fn product(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellError> {
pub fn product(values: &[Value], span: Span, head: Span) -> Result<Value, ShellError> {
let product_func = reducer_for(Reduce::Product);
product_func(Value::nothing(*head), values.to_vec(), span, *head)
product_func(Value::nothing(head), values.to_vec(), span, head)
}
#[cfg(test)]

View File

@ -65,8 +65,8 @@ impl Command for SubCommand {
}
}
pub fn compute_stddev(sample: bool) -> impl Fn(&[Value], Span, &Span) -> Result<Value, ShellError> {
move |values: &[Value], span: Span, head: &Span| {
pub fn compute_stddev(sample: bool) -> impl Fn(&[Value], Span, Span) -> Result<Value, ShellError> {
move |values: &[Value], span: Span, head: Span| {
let variance = variance(sample)(values, span, head);
match variance {
Ok(Value::Float { val, span }) => Ok(Value::Float {

View File

@ -59,9 +59,9 @@ impl Command for SubCommand {
}
}
pub fn summation(values: &[Value], span: Span, head: &Span) -> Result<Value, ShellError> {
pub fn summation(values: &[Value], span: Span, head: Span) -> Result<Value, ShellError> {
let sum_func = reducer_for(Reduce::Summation);
sum_func(Value::nothing(*head), values.to_vec(), span, *head)
sum_func(Value::nothing(head), values.to_vec(), span, head)
}
#[cfg(test)]

View File

@ -5,7 +5,7 @@ use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Span, Spanned, Val
pub fn run_with_function(
call: &Call,
input: PipelineData,
mf: impl Fn(&[Value], Span, &Span) -> Result<Value, ShellError>,
mf: impl Fn(&[Value], Span, Span) -> Result<Value, ShellError>,
) -> Result<PipelineData, ShellError> {
let name = call.head;
let res = calculate(input, name, mf);
@ -19,7 +19,7 @@ fn helper_for_tables(
values: &[Value],
val_span: Span,
name: Span,
mf: impl Fn(&[Value], Span, &Span) -> Result<Value, ShellError>,
mf: impl Fn(&[Value], Span, Span) -> Result<Value, ShellError>,
) -> Result<Value, ShellError> {
// If we are not dealing with Primitives, then perhaps we are dealing with a table
// Create a key for each column name
@ -37,14 +37,14 @@ fn helper_for_tables(
Value::Error { error } => return Err(*error.clone()),
_ => {
//Turns out we are not dealing with a table
return mf(values, val.expect_span(), &name);
return mf(values, val.expect_span(), name);
}
}
}
// The mathematical function operates over the columns of the table
let mut column_totals = IndexMap::new();
for (col_name, col_vals) in column_values {
if let Ok(out) = mf(&col_vals, val_span, &name) {
if let Ok(out) = mf(&col_vals, val_span, name) {
column_totals.insert(col_name, out);
}
}
@ -66,7 +66,7 @@ fn helper_for_tables(
pub fn calculate(
values: PipelineData,
name: Span,
mf: impl Fn(&[Value], Span, &Span) -> Result<Value, ShellError>,
mf: impl Fn(&[Value], Span, Span) -> Result<Value, ShellError>,
) -> Result<Value, ShellError> {
// TODO implement spans for ListStream, thus negating the need for unwrap_or().
let span = values.span().unwrap_or(name);
@ -81,13 +81,11 @@ pub fn calculate(
name,
mf,
),
_ => mf(vals, span, &name),
_ => mf(vals, span, name),
},
PipelineData::Value(Value::Record { vals, cols, span }, ..) => {
let new_vals: Result<Vec<Value>, ShellError> = vals
.into_iter()
.map(|val| mf(&[val], span, &name))
.collect();
let new_vals: Result<Vec<Value>, ShellError> =
vals.into_iter().map(|val| mf(&[val], span, name)).collect();
match new_vals {
Ok(vec) => Ok(Value::Record {
cols,
@ -100,12 +98,12 @@ pub fn calculate(
PipelineData::Value(Value::Range { val, span, .. }, ..) => {
let new_vals: Result<Vec<Value>, ShellError> = val
.into_range_iter(None)?
.map(|val| mf(&[val], span, &name))
.map(|val| mf(&[val], span, name))
.collect();
mf(&new_vals?, span, &name)
mf(&new_vals?, span, name)
}
PipelineData::Value(val, ..) => mf(&[val], span, &name),
PipelineData::Value(val, ..) => mf(&[val], span, name),
PipelineData::Empty { .. } => Err(ShellError::PipelineEmpty { dst_span: name }),
val => Err(ShellError::UnsupportedInput(
"Only integers, floats, lists, records or ranges are supported".into(),

View File

@ -57,10 +57,10 @@ impl Command for SubCommand {
}
}
fn sum_of_squares(values: &[Value], span: &Span) -> Result<Value, ShellError> {
let n = Value::int(values.len() as i64, *span);
let mut sum_x = Value::int(0, *span);
let mut sum_x2 = Value::int(0, *span);
fn sum_of_squares(values: &[Value], span: Span) -> Result<Value, ShellError> {
let n = Value::int(values.len() as i64, span);
let mut sum_x = Value::int(0, span);
let mut sum_x2 = Value::int(0, span);
for value in values {
let v = match &value {
Value::Int { .. } | Value::Float { .. } => Ok(value),
@ -69,36 +69,36 @@ fn sum_of_squares(values: &[Value], span: &Span) -> Result<Value, ShellError> {
"Attempted to compute the sum of squares of a non-integer, non-float value"
.to_string(),
"value originates from here".into(),
*span,
span,
value.expect_span(),
)),
}?;
let v_squared = &v.mul(*span, v, *span)?;
sum_x2 = sum_x2.add(*span, v_squared, *span)?;
sum_x = sum_x.add(*span, v, *span)?;
let v_squared = &v.mul(span, v, span)?;
sum_x2 = sum_x2.add(span, v_squared, span)?;
sum_x = sum_x.add(span, v, span)?;
}
let sum_x_squared = sum_x.mul(*span, &sum_x, *span)?;
let sum_x_squared_div_n = sum_x_squared.div(*span, &n, *span)?;
let sum_x_squared = sum_x.mul(span, &sum_x, span)?;
let sum_x_squared_div_n = sum_x_squared.div(span, &n, span)?;
let ss = sum_x2.sub(*span, &sum_x_squared_div_n, *span)?;
let ss = sum_x2.sub(span, &sum_x_squared_div_n, span)?;
Ok(ss)
}
pub fn compute_variance(
sample: bool,
) -> impl Fn(&[Value], Span, &Span) -> Result<Value, ShellError> {
move |values: &[Value], span: Span, head: &Span| {
) -> impl Fn(&[Value], Span, Span) -> Result<Value, ShellError> {
move |values: &[Value], span: Span, head: Span| {
let n = if sample {
values.len() - 1
} else {
values.len()
};
// sum_of_squares() needs the span of the original value, not the call head.
let ss = sum_of_squares(values, &span)?;
let n = Value::int(n as i64, *head);
ss.div(*head, &n, *head)
let ss = sum_of_squares(values, span)?;
let n = Value::int(n as i64, head);
ss.div(head, &n, head)
}
}

View File

@ -204,10 +204,10 @@ impl From<DirInfo> for Value {
});
cols.push("directories".into());
vals.push(value_from_vec(d.dirs, &d.tag));
vals.push(value_from_vec(d.dirs, d.tag));
cols.push("files".into());
vals.push(value_from_vec(d.files, &d.tag));
vals.push(value_from_vec(d.files, d.tag));
// if !d.errors.is_empty() {
// let v = d
@ -271,17 +271,17 @@ impl From<FileInfo> for Value {
}
}
fn value_from_vec<V>(vec: Vec<V>, tag: &Span) -> Value
fn value_from_vec<V>(vec: Vec<V>, tag: Span) -> Value
where
V: Into<Value>,
{
if vec.is_empty() {
Value::nothing(*tag)
Value::nothing(tag)
} else {
let values = vec.into_iter().map(Into::into).collect::<Vec<Value>>();
Value::List {
vals: values,
span: *tag,
span: tag,
}
}
}

View File

@ -262,7 +262,7 @@ impl Command for Char {
.positional_nth(i)
.expect("Unexpected missing argument")
.span;
multi_byte.push(integer_to_unicode_char(arg, &span)?)
multi_byte.push(integer_to_unicode_char(arg, span)?)
}
Ok(Value::string(multi_byte, call_span).into_pipeline_data())
} else if call.has_flag("unicode") {
@ -279,7 +279,7 @@ impl Command for Char {
.positional_nth(i)
.expect("Unexpected missing argument")
.span;
multi_byte.push(string_to_unicode_char(arg, &span)?)
multi_byte.push(string_to_unicode_char(arg, span)?)
}
Ok(Value::string(multi_byte, call_span).into_pipeline_data())
} else {
@ -306,7 +306,7 @@ impl Command for Char {
}
}
fn integer_to_unicode_char(value: i64, t: &Span) -> Result<char, ShellError> {
fn integer_to_unicode_char(value: i64, t: Span) -> Result<char, ShellError> {
let decoded_char = value.try_into().ok().and_then(std::char::from_u32);
if let Some(ch) = decoded_char {
@ -314,12 +314,12 @@ fn integer_to_unicode_char(value: i64, t: &Span) -> Result<char, ShellError> {
} else {
Err(ShellError::TypeMismatch {
err_message: "not a valid Unicode codepoint".into(),
span: *t,
span: t,
})
}
}
fn string_to_unicode_char(s: &str, t: &Span) -> Result<char, ShellError> {
fn string_to_unicode_char(s: &str, t: Span) -> Result<char, ShellError> {
let decoded_char = u32::from_str_radix(s, 16)
.ok()
.and_then(std::char::from_u32);
@ -329,7 +329,7 @@ fn string_to_unicode_char(s: &str, t: &Span) -> Result<char, ShellError> {
} else {
Err(ShellError::TypeMismatch {
err_message: "error decoding Unicode character".into(),
span: *t,
span: t,
})
}
}