Collect reason that each alias is required trivial
diff --git a/syntax/check.rs b/syntax/check.rs
index cfac236..1543918 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -338,7 +338,7 @@
         || cx.types.cxx.contains(ident)
             && !cx.types.structs.contains_key(ident)
             && !cx.types.enums.contains_key(ident)
-            && !cx.types.required_trivial_aliases.contains(ident)
+            && !cx.types.required_trivial_aliases.contains_key(ident)
         || cx.types.rust.contains(ident)
 }
 
@@ -377,7 +377,7 @@
             } else if cx.types.enums.contains_key(ident) {
                 "enum".to_owned()
             } else if cx.types.cxx.contains(ident) {
-                if cx.types.required_trivial_aliases.contains(ident) {
+                if cx.types.required_trivial_aliases.contains_key(ident) {
                     "trivial C++ type".to_owned()
                 } else {
                     "non-trivial C++ type".to_owned()
diff --git a/syntax/types.rs b/syntax/types.rs
index 7eb22d4..efccb2b 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, ExternType, Struct, Type, TypeAlias};
+use crate::syntax::{Api, Derive, Enum, ExternFn, ExternType, Struct, Type, TypeAlias};
 use proc_macro2::Ident;
 use quote::ToTokens;
 use std::collections::{BTreeMap as Map, HashSet as UnorderedSet};
@@ -14,7 +14,7 @@
     pub rust: Set<&'a Ident>,
     pub aliases: Map<&'a Ident, &'a TypeAlias>,
     pub untrusted: Map<&'a Ident, &'a ExternType>,
-    pub required_trivial_aliases: UnorderedSet<&'a Ident>,
+    pub required_trivial_aliases: Map<&'a Ident, TrivialReason<'a>>,
 }
 
 impl<'a> Types<'a> {
@@ -140,27 +140,30 @@
         // we check that this is permissible. We do this _after_ scanning all
         // the APIs above, in case some function or struct references a type
         // which is declared subsequently.
-        let mut required_trivial_aliases = UnorderedSet::new();
-        let mut insist_alias_types_are_trivial = |ty: &'a Type| {
+        let mut required_trivial_aliases = Map::new();
+        let mut insist_alias_types_are_trivial = |ty: &'a Type, reason| {
             if let Type::Ident(ident) = ty {
                 if aliases.contains_key(ident) {
-                    required_trivial_aliases.insert(ident);
+                    required_trivial_aliases.entry(ident).or_insert(reason);
                 }
             }
         };
         for api in apis {
             match api {
                 Api::Struct(strct) => {
+                    let reason = TrivialReason::StructField(strct);
                     for field in &strct.fields {
-                        insist_alias_types_are_trivial(&field.ty);
+                        insist_alias_types_are_trivial(&field.ty, reason);
                     }
                 }
                 Api::CxxFunction(efn) | Api::RustFunction(efn) => {
+                    let reason = TrivialReason::FunctionArgument(efn);
                     for arg in &efn.args {
-                        insist_alias_types_are_trivial(&arg.ty);
+                        insist_alias_types_are_trivial(&arg.ty, reason);
                     }
                     if let Some(ret) = &efn.ret {
-                        insist_alias_types_are_trivial(&ret);
+                        let reason = TrivialReason::FunctionReturn(efn);
+                        insist_alias_types_are_trivial(&ret, reason);
                     }
                 }
                 _ => {}
@@ -211,6 +214,13 @@
     }
 }
 
+#[derive(Copy, Clone)]
+pub enum TrivialReason<'a> {
+    StructField(&'a Struct),
+    FunctionArgument(&'a ExternFn),
+    FunctionReturn(&'a ExternFn),
+}
+
 fn duplicate_name(cx: &mut Errors, sp: impl ToTokens, ident: &Ident) {
     let msg = format!("the name `{}` is defined multiple times", ident);
     cx.error(sp, msg);