Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow builtin atoms to be shadowed by user type definitions #908

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions gen/src/write.rs
Expand Up @@ -204,7 +204,7 @@ fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) {

for ty in out.types {
match ty {
Type::Ident(ident) => match Atom::from(&ident.rust) {
Type::Ident(ident) => match out.types.builtins.get(&ident.rust) {
Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(I8) | Some(I16) | Some(I32)
| Some(I64) => out.include.cstdint = true,
Some(Usize) => out.include.cstddef = true,
Expand Down Expand Up @@ -1191,8 +1191,8 @@ fn write_extern_arg(out: &mut OutFile, arg: &Var) {

fn write_type(out: &mut OutFile, ty: &Type) {
match ty {
Type::Ident(ident) => match Atom::from(&ident.rust) {
Some(atom) => write_atom(out, atom),
Type::Ident(ident) => match out.types.builtins.get(&ident.rust) {
Some(&atom) => write_atom(out, atom),
None => write!(
out,
"{}",
Expand Down
26 changes: 13 additions & 13 deletions syntax/check.rs
@@ -1,4 +1,4 @@
use crate::syntax::atom::Atom::{self, *};
use crate::syntax::atom::Atom::*;
use crate::syntax::report::Errors;
use crate::syntax::visit::{self, Visit};
use crate::syntax::{
Expand Down Expand Up @@ -81,7 +81,7 @@ impl Check<'_> {

fn check_type_ident(cx: &mut Check, name: &NamedType) {
let ident = &name.rust;
if Atom::from(ident).is_none()
if cx.types.builtins.get(ident).is_none()
&& !cx.types.structs.contains_key(ident)
&& !cx.types.enums.contains_key(ident)
&& !cx.types.cxx.contains(ident)
Expand All @@ -102,7 +102,7 @@ fn check_type_box(cx: &mut Check, ptr: &Ty1) {
cx.error(ptr, error::BOX_CXX_TYPE.msg);
}

if Atom::from(&ident.rust).is_none() {
if cx.types.builtins.get(&ident.rust).is_none() {
return;
}
}
Expand All @@ -122,7 +122,7 @@ fn check_type_rust_vec(cx: &mut Check, ty: &Ty1) {
return;
}

match Atom::from(&ident.rust) {
match cx.types.builtins.get(&ident.rust) {
None | Some(Char) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize)
| Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32)
| Some(F64) | Some(RustString) => return,
Expand All @@ -144,7 +144,7 @@ fn check_type_unique_ptr(cx: &mut Check, ptr: &Ty1) {
return;
}

match Atom::from(&ident.rust) {
match cx.types.builtins.get(&ident.rust) {
None | Some(CxxString) => return,
_ => {}
}
Expand All @@ -162,7 +162,7 @@ fn check_type_shared_ptr(cx: &mut Check, ptr: &Ty1) {
return;
}

match Atom::from(&ident.rust) {
match cx.types.builtins.get(&ident.rust) {
None | Some(Bool) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize)
| Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32)
| Some(F64) | Some(CxxString) => return,
Expand All @@ -183,7 +183,7 @@ fn check_type_weak_ptr(cx: &mut Check, ptr: &Ty1) {
return;
}

match Atom::from(&ident.rust) {
match cx.types.builtins.get(&ident.rust) {
None | Some(Bool) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize)
| Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32)
| Some(F64) | Some(CxxString) => return,
Expand All @@ -207,7 +207,7 @@ fn check_type_cxx_vector(cx: &mut Check, ptr: &Ty1) {
return;
}

match Atom::from(&ident.rust) {
match cx.types.builtins.get(&ident.rust) {
None | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize) | Some(I8)
| Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32) | Some(F64)
| Some(CxxString) => return,
Expand Down Expand Up @@ -522,7 +522,7 @@ fn check_api_impl(cx: &mut Check, imp: &Impl) {
| Type::WeakPtr(ty)
| Type::CxxVector(ty) => {
if let Type::Ident(inner) = &ty.inner {
if Atom::from(&inner.rust).is_none() {
if cx.types.builtins.get(&inner.rust).is_none() {
return;
}
}
Expand Down Expand Up @@ -568,7 +568,7 @@ fn check_mut_return_restriction(cx: &mut Check, efn: &ExternFn) {
self.found |= match ty {
Type::Ref(ty) => ty.mutable,
Type::SliceRef(slice) => slice.mutable,
Type::Ident(ident) if Atom::from(&ident.rust).is_none() => {
Type::Ident(ident) if self.cx.types.builtins.get(&ident.rust).is_none() => {
match self.cx.types.try_resolve(ident) {
Some(resolve) => !resolve.generics.lifetimes.is_empty(),
None => true,
Expand Down Expand Up @@ -604,7 +604,7 @@ fn check_reserved_name(cx: &mut Check, ident: &Ident) {
|| ident == "Vec"
|| ident == "CxxVector"
|| ident == "str"
|| Atom::from(ident).is_some()
|| cx.types.builtins.get(ident).is_some()
{
cx.error(ident, "reserved name");
}
Expand Down Expand Up @@ -709,9 +709,9 @@ fn describe(cx: &mut Check, ty: &Type) -> String {
"opaque C++ type".to_owned()
} else if cx.types.rust.contains(&ident.rust) {
"opaque Rust type".to_owned()
} else if Atom::from(&ident.rust) == Some(CxxString) {
} else if cx.types.builtins.get(&ident.rust) == Some(&CxxString) {
"C++ string".to_owned()
} else if Atom::from(&ident.rust) == Some(Char) {
} else if cx.types.builtins.get(&ident.rust) == Some(&Char) {
"C char".to_owned()
} else {
ident.rust.to_string()
Expand Down
4 changes: 2 additions & 2 deletions syntax/improper.rs
@@ -1,5 +1,5 @@
use self::ImproperCtype::*;
use crate::syntax::atom::Atom::{self, *};
use crate::syntax::atom::Atom::*;
use crate::syntax::{Type, Types};
use proc_macro2::Ident;

Expand All @@ -14,7 +14,7 @@ impl<'a> Types<'a> {
match ty {
Type::Ident(ident) => {
let ident = &ident.rust;
if let Some(atom) = Atom::from(ident) {
if let Some(&atom) = self.builtins.get(ident) {
Definite(atom == RustString)
} else if let Some(strct) = self.structs.get(ident) {
Depends(&strct.name.rust) // iterate to fixed-point
Expand Down
4 changes: 2 additions & 2 deletions syntax/pod.rs
@@ -1,12 +1,12 @@
use crate::syntax::atom::Atom::{self, *};
use crate::syntax::atom::Atom::*;
use crate::syntax::{derive, Trait, Type, Types};

impl<'a> Types<'a> {
pub fn is_guaranteed_pod(&self, ty: &Type) -> bool {
match ty {
Type::Ident(ident) => {
let ident = &ident.rust;
if let Some(atom) = Atom::from(ident) {
if let Some(&atom) = self.builtins.get(ident) {
match atom {
Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64
| Isize | F32 | F64 => true,
Expand Down
13 changes: 13 additions & 0 deletions syntax/types.rs
Expand Up @@ -14,6 +14,7 @@ use quote::ToTokens;

pub struct Types<'a> {
pub all: OrderedSet<&'a Type>,
pub builtins: UnorderedMap<&'a Ident, Atom>,
pub structs: UnorderedMap<&'a Ident, &'a Struct>,
pub enums: UnorderedMap<&'a Ident, &'a Enum>,
pub cxx: UnorderedSet<&'a Ident>,
Expand All @@ -38,6 +39,7 @@ impl<'a> Types<'a> {
let mut untrusted = UnorderedMap::new();
let mut impls = OrderedMap::new();
let mut resolutions = UnorderedMap::new();
let builtins = UnorderedMap::new();
let struct_improper_ctypes = UnorderedSet::new();
let toposorted_structs = Vec::new();

Expand Down Expand Up @@ -198,6 +200,7 @@ impl<'a> Types<'a> {

let mut types = Types {
all,
builtins,
structs,
enums,
cxx,
Expand All @@ -211,6 +214,16 @@ impl<'a> Types<'a> {
toposorted_structs,
};

for ty in &types.all {
if let Type::Ident(name) = ty {
if types.resolutions.get(&name.rust).is_none() {
if let Some(atom) = Atom::from(&name.rust) {
types.builtins.insert(&name.rust, atom);
}
}
}
}

types.toposorted_structs = toposort::sort(cx, apis, &types);

let mut unresolved_structs = types.structs.keys();
Expand Down
5 changes: 3 additions & 2 deletions tests/ui/reserved_name.rs
@@ -1,15 +1,16 @@
#[cxx::bridge]
mod ffi {
struct UniquePtr {
// invalid; `UniquePtr` is a builtin
val: usize,
}

extern "C++" {
type Box;
type Box; // invalid; `Box` is a builtin
}

extern "Rust" {
type String;
type String; // valid; `String` is an atom
}
}

Expand Down
10 changes: 2 additions & 8 deletions tests/ui/reserved_name.stderr
Expand Up @@ -5,13 +5,7 @@ error: reserved name
| ^^^^^^^^^

error: reserved name
--> $DIR/reserved_name.rs:8:14
--> $DIR/reserved_name.rs:9:14
|
8 | type Box;
9 | type Box; // invalid; `Box` is a builtin
| ^^^

error: reserved name
--> $DIR/reserved_name.rs:12:14
|
12 | type String;
| ^^^^^^