forked from extern/nushell
Glob: don't allow implicit casting between glob and string (#11992)
# Description As title, currently on latest main, nushell confused user if it allows implicit casting between glob and string: ```nushell let x = "*.txt" def glob-test [g: glob] { open $g } glob-test $x ``` It always expand the glob although `$x` is defined as a string. This pr implements a solution from @kubouch : > We could make it really strict and disallow all autocasting between globs and strings because that's what's causing the "magic" confusion. Then, modify all builtins that accept globs to accept oneof(glob, string) and the rules would be that globs always expand and strings never expand # User-Facing Changes After this pr, user needs to use `into glob` to invoke `glob-test`, if user pass a string variable: ```nushell let x = "*.txt" def glob-test [g: glob] { open $g } glob-test ($x | into glob) ``` Or else nushell will return an error. ``` 3 │ glob-test $x · ─┬ · ╰── can't convert string to glob ``` # Tests + Formatting Done # After Submitting Nan
This commit is contained in:
@ -14,7 +14,7 @@ use nu_protocol::{
|
||||
engine::{StateWorkingSet, DEFAULT_OVERLAY_NAME},
|
||||
eval_const::eval_constant,
|
||||
span, Alias, BlockId, DeclId, Exportable, Module, ModuleId, ParseError, PositionalArg,
|
||||
ResolvedImportPattern, Span, Spanned, SyntaxShape, Type, VarId,
|
||||
ResolvedImportPattern, Span, Spanned, SyntaxShape, Type, Value, VarId,
|
||||
};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -3156,10 +3156,10 @@ pub fn parse_const(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipelin
|
||||
}
|
||||
|
||||
match eval_constant(working_set, &rvalue) {
|
||||
Ok(val) => {
|
||||
Ok(mut value) => {
|
||||
// In case rhs is parsed as 'any' but is evaluated to a concrete
|
||||
// type:
|
||||
let const_type = val.get_type();
|
||||
let mut const_type = value.get_type();
|
||||
|
||||
if let Some(explicit_type) = &explicit_type {
|
||||
if !type_compatible(explicit_type, &const_type) {
|
||||
@ -3169,12 +3169,25 @@ pub fn parse_const(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipelin
|
||||
nu_protocol::span(&spans[(span.0 + 1)..]),
|
||||
));
|
||||
}
|
||||
let val_span = value.span();
|
||||
|
||||
// need to convert to Value::glob if rhs is string, and
|
||||
// the const variable is annotated with glob type.
|
||||
match value {
|
||||
Value::String { val, .. }
|
||||
if explicit_type == &Type::Glob =>
|
||||
{
|
||||
value = Value::glob(val, false, val_span);
|
||||
const_type = value.get_type();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
working_set.set_variable_type(var_id, const_type);
|
||||
|
||||
// Assign the constant value to the variable
|
||||
working_set.set_variable_const_val(var_id, val);
|
||||
working_set.set_variable_const_val(var_id, value);
|
||||
}
|
||||
Err(err) => working_set.error(err.wrap(working_set, rvalue.span)),
|
||||
}
|
||||
|
@ -2483,7 +2483,7 @@ pub fn parse_glob_pattern(working_set: &mut StateWorkingSet, span: Span) -> Expr
|
||||
Expression {
|
||||
expr: Expr::GlobPattern(token, quoted),
|
||||
span,
|
||||
ty: Type::String,
|
||||
ty: Type::Glob,
|
||||
custom_completion: None,
|
||||
}
|
||||
} else {
|
||||
|
@ -64,7 +64,6 @@ pub fn type_compatible(lhs: &Type, rhs: &Type) -> bool {
|
||||
is_compatible(lhs, rhs)
|
||||
}
|
||||
(Type::Glob, Type::String) => true,
|
||||
(Type::String, Type::Glob) => true,
|
||||
(lhs, rhs) => lhs == rhs,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user