Don't mix feature gates and hard errors, decide on one per op and stick with it
This commit is contained in:
parent
3ed14033f7
commit
aaee3f27ee
@ -237,13 +237,6 @@ impl NonConstOp for TransientCellBorrow {
|
||||
/// it in the future for static items.
|
||||
pub struct CellBorrow;
|
||||
impl NonConstOp for CellBorrow {
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||
match ccx.const_kind() {
|
||||
// The borrow checker does a much better job at handling these than we do.
|
||||
hir::ConstContext::ConstFn => Status::Unstable(sym::const_refs_to_cell),
|
||||
_ => Status::Forbidden,
|
||||
}
|
||||
}
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(
|
||||
ccx.tcx.sess,
|
||||
|
@ -582,14 +582,24 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
);
|
||||
|
||||
if borrowed_place_has_mut_interior {
|
||||
// Locals without StorageDead follow the "enclosing scope" rule, meaning
|
||||
// they are essentially anonymous static items themselves.
|
||||
// Note: This is only sound if every local that has a `StorageDead` has a
|
||||
// `StorageDead` in every control flow path leading to a `return` terminator.
|
||||
if self.local_has_storage_dead(place.local) {
|
||||
self.check_op(ops::TransientCellBorrow);
|
||||
} else {
|
||||
self.check_op(ops::CellBorrow);
|
||||
match self.const_kind() {
|
||||
// In a const fn all borrows are transient or point to the places given via
|
||||
// references in the arguments. The borrow checker guarantees that.
|
||||
// NOTE: Once we have heap allocations during CTFE we need to figure out
|
||||
// how to prevent `const fn` to create long-lived allocations that point
|
||||
// to (interior) mutable memory.
|
||||
hir::ConstContext::ConstFn => self.check_op(ops::TransientCellBorrow),
|
||||
_ => {
|
||||
// Locals without StorageDead follow the "enclosing scope" rule, meaning
|
||||
// they are essentially anonymous static items themselves.
|
||||
// Note: This is only sound if every local that has a `StorageDead` has a
|
||||
// `StorageDead` in every control flow path leading to a `return` terminator.
|
||||
if self.local_has_storage_dead(place.local) {
|
||||
self.check_op(ops::TransientCellBorrow);
|
||||
} else {
|
||||
self.check_op(ops::CellBorrow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user