if let (local, []) = (&place.local, proj_base) {
let decl = &self.body.local_decls[*local];
if decl.internal {
- // Internal locals are used in the `move_val_init` desugaring.
- // We want to check unsafety against the source info of the
- // desugaring, rather than the source info of the RHS.
- self.source_info = self.body.local_decls[*local].source_info;
- } else if let LocalInfo::StaticRef { def_id, .. } = decl.local_info {
- if self.tcx.is_mutable_static(def_id) {
- self.require_unsafe(
- "use of mutable static",
- "mutable statics can be mutated by multiple threads: aliasing \
- violations or data races will cause undefined behavior",
- UnsafetyViolationKind::General,
- );
- return;
- } else if self.tcx.is_foreign_item(def_id) {
- self.require_unsafe(
- "use of extern static",
- "extern statics are not controlled by the Rust type system: \
- invalid data, aliasing violations or data races will cause \
- undefined behavior",
- UnsafetyViolationKind::General,
- );
- return;
+ if let LocalInfo::StaticRef { def_id, .. } = decl.local_info {
+ if self.tcx.is_mutable_static(def_id) {
+ self.require_unsafe(
+ "use of mutable static",
+ "mutable statics can be mutated by multiple threads: aliasing \
+ violations or data races will cause undefined behavior",
+ UnsafetyViolationKind::General,
+ );
+ return;
+ } else if self.tcx.is_foreign_item(def_id) {
+ self.require_unsafe(
+ "use of extern static",
+ "extern statics are not controlled by the Rust type system: \
+ invalid data, aliasing violations or data races will cause \
+ undefined behavior",
+ UnsafetyViolationKind::General,
+ );
+ return;
+ }
+ } else {
+ // Internal locals are used in the `move_val_init` desugaring.
+ // We want to check unsafety against the source info of the
+ // desugaring, rather than the source info of the RHS.
+ self.source_info = self.body.local_decls[*local].source_info;
}
}
}
}
if let ExprKind::StaticRef { def_id, .. } = expr.kind {
let is_thread_local = this.hir.tcx().has_attr(def_id, sym::thread_local);
+ local_decl.internal = true;
local_decl.local_info = LocalInfo::StaticRef { def_id, is_thread_local };
}
this.local_decls.push(local_decl)
}
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
- let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
-
match &expr.kind {
ExprKind::Call(callee, args) => match &callee.kind {
ExprKind::Path(qpath) => {
}
_ => intravisit::walk_expr(self, expr),
},
- ExprKind::Path(qpath) => {
- let res = self.fcx.tables.borrow().qpath_res(qpath, expr.hir_id);
- if let Res::Def(DefKind::Static, def_id) = res {
- // Statics are lowered to temporary references or
- // pointers in MIR, so record that type.
- let ptr_ty = self.fcx.tcx.static_ptr_ty(def_id);
- self.record(ptr_ty, scope, Some(expr), expr.span);
- }
- }
_ => intravisit::walk_expr(self, expr),
}
self.expr_count += 1;
+ let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
+
// If there are adjustments, then record the final type --
// this is the actual value that is being produced.
if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {
--- /dev/null
+// build-pass
+// edition:2018
+
+static mut A: [i32; 5] = [1, 2, 3, 4, 5];
+
+fn is_send_sync<T: Send + Sync>(_: T) {}
+
+async fn fun() {
+ let u = unsafe { A[async { 1 }.await] };
+ unsafe {
+ match A {
+ i if async { true }.await => (),
+ _ => (),
+ }
+ }
+}
+
+fn main() {
+ let index_block = async {
+ let u = unsafe { A[async { 1 }.await] };
+ };
+ let match_block = async {
+ unsafe {
+ match A {
+ i if async { true }.await => (),
+ _ => (),
+ }
+ }
+ };
+ is_send_sync(index_block);
+ is_send_sync(match_block);
+ is_send_sync(fun());
+}
--- /dev/null
+// build-pass
+#![feature(generators)]
+
+static mut A: [i32; 5] = [1, 2, 3, 4, 5];
+
+fn is_send_sync<T: Send + Sync>(_: T) {}
+
+fn main() {
+ unsafe {
+ let gen_index = static || {
+ let u = A[{
+ yield;
+ 1
+ }];
+ };
+ let gen_match = static || match A {
+ i if {
+ yield;
+ true
+ } =>
+ {
+ ()
+ }
+ _ => (),
+ };
+ is_send_sync(gen_index);
+ is_send_sync(gen_match);
+ }
+}