Enforce that extern shared structs are declared unsafe
diff --git a/syntax/check.rs b/syntax/check.rs
index 5980f75..f823964 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -167,16 +167,22 @@
 }
 
 fn check_api_struct(cx: &mut Check, strct: &Struct) {
-    check_reserved_name(cx, &strct.ident);
+    let ident = &strct.ident;
+    check_reserved_name(cx, ident);
 
     if strct.fields.is_empty() {
         let span = span_for_struct_error(strct);
         cx.error(span, "structs without any fields are not supported");
     }
 
-    if cx.types.cxx.contains(&strct.ident) {
-        let span = span_for_struct_error(strct);
-        cx.error(span, "extern C++ structs are not implemented yet");
+    if cx.types.cxx.contains(ident) {
+        if let Some(ety) = cx.types.untrusted.get(ident) {
+            let msg = "extern shared struct must be declared in an `unsafe extern` block";
+            cx.error(ety, msg);
+        } else {
+            let span = span_for_struct_error(strct);
+            cx.error(span, "extern C++ structs are not implemented yet");
+        }
     }
 
     for field in &strct.fields {
diff --git a/syntax/types.rs b/syntax/types.rs
index 533ea48..8a86a46 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -1,7 +1,7 @@
 use crate::syntax::atom::Atom::{self, *};
 use crate::syntax::report::Errors;
 use crate::syntax::set::OrderedSet as Set;
-use crate::syntax::{Api, Derive, Enum, Struct, Type, TypeAlias};
+use crate::syntax::{Api, Derive, Enum, ExternType, Struct, Type, TypeAlias};
 use proc_macro2::Ident;
 use quote::ToTokens;
 use std::collections::{BTreeMap as Map, HashSet as UnorderedSet};
@@ -13,7 +13,7 @@
     pub cxx: Set<&'a Ident>,
     pub rust: Set<&'a Ident>,
     pub aliases: Map<&'a Ident, &'a TypeAlias>,
-    pub trusted: Set<&'a Ident>,
+    pub untrusted: Map<&'a Ident, &'a ExternType>,
 }
 
 impl<'a> Types<'a> {
@@ -24,7 +24,7 @@
         let mut cxx = Set::new();
         let mut rust = Set::new();
         let mut aliases = Map::new();
-        let mut trusted = Set::new();
+        let mut untrusted = Map::new();
 
         fn visit<'a>(all: &mut Set<&'a Type>, ty: &'a Type) {
             all.insert(ty);
@@ -101,8 +101,8 @@
                         duplicate_name(cx, ety, ident);
                     }
                     cxx.insert(ident);
-                    if ety.trusted {
-                        trusted.insert(ident);
+                    if !ety.trusted {
+                        untrusted.insert(ident, ety);
                     }
                 }
                 Api::RustType(ety) => {
@@ -142,7 +142,7 @@
             cxx,
             rust,
             aliases,
-            trusted,
+            untrusted,
         }
     }