improve type inference

This commit is contained in:
JT 2021-08-17 12:26:05 +12:00
parent dda6554990
commit 739425431a
2 changed files with 26 additions and 4 deletions

View file

@ -182,9 +182,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
})
} else if decl.signature.name == "vars" {
state.parser_state.borrow().print_vars();
Ok(Value::Nothing {
span: call.positional[0].span,
})
Ok(Value::Nothing { span: call.head })
} else if decl.signature.name == "decls" {
state.parser_state.borrow().print_decls();
Ok(Value::Nothing { span: call.head })

View file

@ -1784,6 +1784,8 @@ impl<'a> ParserWorkingSet<'a> {
let mut args = vec![];
let mut contained_type: Option<Type> = None;
if !output.block.is_empty() {
for arg in &output.block[0].commands {
let mut spans_idx = 0;
@ -1793,6 +1795,14 @@ impl<'a> ParserWorkingSet<'a> {
self.parse_multispan_value(&arg.parts, &mut spans_idx, element_shape);
error = error.or(err);
if let Some(ref ctype) = contained_type {
if *ctype != arg.ty {
contained_type = Some(Type::Unknown);
}
} else {
contained_type = Some(arg.ty.clone());
}
args.push(arg);
spans_idx += 1;
@ -1804,7 +1814,11 @@ impl<'a> ParserWorkingSet<'a> {
Expression {
expr: Expr::List(args),
span,
ty: Type::List(Box::new(Type::Unknown)), // FIXME
ty: Type::List(Box::new(if let Some(ty) = contained_type {
ty.clone()
} else {
Type::Unknown
})),
},
error,
)
@ -2416,6 +2430,16 @@ impl<'a> ParserWorkingSet<'a> {
let (call, call_span, err) =
self.parse_internal_call(spans[0], &spans[1..], decl_id);
// Update the variable to the known type if we can.
if err.is_none() {
let var_id = call.positional[0]
.as_var()
.expect("internal error: expected variable");
let rhs_type = call.positional[1].ty.clone();
self.set_variable_type(var_id, rhs_type);
}
return (
Statement::Expression(Expression {
expr: Expr::Call(call),