Skip to content

Commit

Permalink
Don't immediately drop ignored variables
Browse files Browse the repository at this point in the history
Values assigned to the variable "_" shouldn't be dropped immediately.
Doing so means guard types assigned to such variables are dropped
immediately, effectively making them useless.

Changelog: fixed
  • Loading branch information
yorickpeterse committed Sep 28, 2022
1 parent a419af9 commit 3e62e9e
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 1 deletion.
3 changes: 3 additions & 0 deletions compiler/src/hir.rs
Expand Up @@ -753,6 +753,7 @@ pub(crate) struct DefineElse {

#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct DefineVariable {
pub(crate) resolved_type: types::TypeRef,
pub(crate) variable_id: Option<types::VariableId>,
pub(crate) mutable: bool,
pub(crate) name: Identifier,
Expand Down Expand Up @@ -2327,6 +2328,7 @@ impl<'a> LowerToHir<'a> {
node: ast::DefineVariable,
) -> Box<DefineVariable> {
Box::new(DefineVariable {
resolved_type: types::TypeRef::Unknown,
mutable: node.mutable,
variable_id: None,
name: self.identifier(node.name),
Expand Down Expand Up @@ -5371,6 +5373,7 @@ mod tests {
assert_eq!(
hir,
Expression::DefineVariable(Box::new(DefineVariable {
resolved_type: types::TypeRef::Unknown,
variable_id: None,
name: Identifier {
name: "a".to_string(),
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/mir/passes.rs
Expand Up @@ -2382,8 +2382,11 @@ impl<'a> LowerMethod<'a> {
self.current_block_mut().move_register(reg, src, loc);
} else {
let src = self.input_expression(node.value, None);
let reg = self.new_register(node.resolved_type);

self.unconditional_drop_register(src, loc);
// We don't drop immediately as this would break e.g. guards bounds
// to `_` (e.g. `let _ = something_that_returns_a_guard`).
self.current_block_mut().move_register(reg, src, loc);
}

self.get_nil(loc)
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/type_check/expressions.rs
Expand Up @@ -1707,6 +1707,8 @@ impl<'a> CheckMethodBody<'a> {
let name = &node.name.name;
let rtype = TypeRef::nil();

node.resolved_type = var_type;

if name == IGNORE_VARIABLE {
return rtype;
}
Expand Down

0 comments on commit 3e62e9e

Please sign in to comment.