Rollup merge of #61023 - spastorino:use-iterate-qualify-consts, r=oli-obk
Migrate from recursion to iterate on qualify consts visitor impl r? @oli-obk
This commit is contained in:
commit
fba5ed355a
1 changed files with 51 additions and 49 deletions
|
@ -930,58 +930,60 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
||||||
context: PlaceContext,
|
context: PlaceContext,
|
||||||
location: Location) {
|
location: Location) {
|
||||||
debug!("visit_place: place={:?} context={:?} location={:?}", place, context, location);
|
debug!("visit_place: place={:?} context={:?} location={:?}", place, context, location);
|
||||||
self.super_place(place, context, location);
|
place.iterate(|place_base, place_projections| {
|
||||||
match *place {
|
match place_base {
|
||||||
Place::Base(PlaceBase::Local(_)) => {}
|
PlaceBase::Local(_) => {}
|
||||||
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
|
PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
|
PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => {
|
||||||
if self.tcx
|
if self.tcx
|
||||||
.get_attrs(def_id)
|
.get_attrs(*def_id)
|
||||||
.iter()
|
.iter()
|
||||||
.any(|attr| attr.check_name(sym::thread_local)) {
|
.any(|attr| attr.check_name(sym::thread_local)) {
|
||||||
|
if self.mode != Mode::Fn {
|
||||||
|
span_err!(self.tcx.sess, self.span, E0625,
|
||||||
|
"thread-local statics cannot be \
|
||||||
|
accessed at compile-time");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only allow statics (not consts) to refer to other statics.
|
||||||
|
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
|
||||||
|
if self.mode == Mode::Static && context.is_mutating_use() {
|
||||||
|
// this is not strictly necessary as miri will also bail out
|
||||||
|
// For interior mutability we can't really catch this statically as that
|
||||||
|
// goes through raw pointers and intermediate temporaries, so miri has
|
||||||
|
// to catch this anyway
|
||||||
|
self.tcx.sess.span_err(
|
||||||
|
self.span,
|
||||||
|
"cannot mutate statics in the initializer of another static",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unleash_miri!(self);
|
||||||
|
|
||||||
if self.mode != Mode::Fn {
|
if self.mode != Mode::Fn {
|
||||||
span_err!(self.tcx.sess, self.span, E0625,
|
let mut err = struct_span_err!(self.tcx.sess, self.span, E0013,
|
||||||
"thread-local statics cannot be \
|
"{}s cannot refer to statics, use \
|
||||||
accessed at compile-time");
|
a constant instead", self.mode);
|
||||||
|
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||||
|
err.note(
|
||||||
|
"Static and const variables can refer to other const variables. \
|
||||||
|
But a const variable cannot refer to a static variable."
|
||||||
|
);
|
||||||
|
err.help(
|
||||||
|
"To fix this, the value can be extracted as a const and then used."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
err.emit()
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only allow statics (not consts) to refer to other statics.
|
|
||||||
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
|
|
||||||
if self.mode == Mode::Static && context.is_mutating_use() {
|
|
||||||
// this is not strictly necessary as miri will also bail out
|
|
||||||
// For interior mutability we can't really catch this statically as that
|
|
||||||
// goes through raw pointers and intermediate temporaries, so miri has
|
|
||||||
// to catch this anyway
|
|
||||||
self.tcx.sess.span_err(
|
|
||||||
self.span,
|
|
||||||
"cannot mutate statics in the initializer of another static",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
unleash_miri!(self);
|
|
||||||
|
|
||||||
if self.mode != Mode::Fn {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, self.span, E0013,
|
|
||||||
"{}s cannot refer to statics, use \
|
|
||||||
a constant instead", self.mode);
|
|
||||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
|
||||||
err.note(
|
|
||||||
"Static and const variables can refer to other const variables. But a \
|
|
||||||
const variable cannot refer to a static variable."
|
|
||||||
);
|
|
||||||
err.help(
|
|
||||||
"To fix this, the value can be extracted as a const and then used."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
err.emit()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Place::Projection(ref proj) => {
|
|
||||||
|
for proj in place_projections {
|
||||||
match proj.elem {
|
match proj.elem {
|
||||||
ProjectionElem::Deref => {
|
ProjectionElem::Deref => {
|
||||||
if context.is_mutating_use() {
|
if context.is_mutating_use() {
|
||||||
|
@ -1041,7 +1043,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
|
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue