Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions tooling/ast_fuzzer/src/program/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,13 @@ pub fn deref(rhs: Expression, tgt_type: Type) -> Expression {
unary(UnaryOp::Dereference { implicitly_added: false }, rhs, tgt_type)
}

/// Reference an expression as a target type
/// Mutable reference over expression with a target type
pub fn ref_mut(rhs: Expression, tgt_type: Type) -> Expression {
ref_with_mut(rhs, tgt_type, true)
}

fn ref_with_mut(rhs: Expression, tgt_type: Type, mutable: bool) -> Expression {
/// Reference over an expression with a target type
pub fn ref_with_mut(rhs: Expression, tgt_type: Type, mutable: bool) -> Expression {
unary(UnaryOp::Reference { mutable }, rhs, Type::Reference(Rc::new(tgt_type), mutable))
}

Expand Down
12 changes: 12 additions & 0 deletions tooling/ast_fuzzer/src/program/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@
return Ok(Some(VariableId::Local(id)));
}
}

// If we're looking for a mutable reference, we have to choose some
// mutable local variable and take a reference over it.
// We can't use a global for this, because they are immutable.
Expand All @@ -413,6 +414,12 @@
})
.map(|id| id.map(VariableId::Local));
}

// If we are looking for a read-only reference, we can choose anything that has the target type.
if let Type::Reference(typ, false) = typ {
return self.choose_producer(u, typ);
}

self.globals.choose_producer(u, typ).map(|id| id.map(VariableId::Global))
}

Expand Down Expand Up @@ -726,6 +733,11 @@
};
Ok(Some((expr, src_dyn)))
}
// Read-only reference over the source type.
(_, Type::Reference(typ, false)) if typ.as_ref() == src_type => {
let expr = expr::ref_with_mut(src_expr, typ.as_ref().clone(), false);
Ok(Some((expr, src_dyn)))
}
// Index a non-empty array.
(Type::Array(len, item_type), _) if *len > 0 => {
// Indexing arrays that contains references with dynamic indexes was banned in #8888
Expand Down Expand Up @@ -1314,7 +1326,7 @@
// We banned reassigning variables which contain mutable references in ACIR (#8790)
*mutable && (self.unconstrained() || !types::contains_reference(typ))
// We can deref-assign to `&mut` references even if they are not
// themselves mutable, but only when the pointee does not itself

Check warning on line 1329 in tooling/ast_fuzzer/src/program/func.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (pointee)
// contain a reference. In constrained code the frontend rejects
// assigning a reference-containing value (`*r = (&mut x, ..)`),
// and the AST fuzzer bypasses that check, so SSA-gen would fail
Expand Down
3 changes: 1 addition & 2 deletions tooling/ast_fuzzer/src/program/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,7 @@ impl Context {
}

if !is_main && !is_global && u.ratio(1, 5)? {
// Read-only references require the experimental "ownership" feature.
typ = types::ref_mut(typ);
typ = types::ref_with_mut(typ, bool::arbitrary(u)?);
}

self.types.insert(typ.clone());
Expand Down
9 changes: 7 additions & 2 deletions tooling/ast_fuzzer/src/program/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,14 @@ pub fn can_binary_op_return_from_input(op: &BinaryOp, input: &Type, output: &Typ
}
}

/// Reference an expression into a target type
/// Mutable reference with a target type.
pub fn ref_mut(typ: Type) -> Type {
Type::Reference(Rc::new(typ), true)
ref_with_mut(typ, true)
}

/// Reference an expression into a target type
pub fn ref_with_mut(typ: Type, mutable: bool) -> Type {
Type::Reference(Rc::new(typ), mutable)
}

/// Convert the type back into a HIR equivalent (not necessarily the original HIR type).
Expand Down
Loading