Skip to content

Commit

Permalink
Implement RFC 1861: Extern types
Browse files Browse the repository at this point in the history
  • Loading branch information
plietar authored and Paul Liétar committed Oct 27, 2017
1 parent bed9a85 commit 77f7e85
Show file tree
Hide file tree
Showing 81 changed files with 737 additions and 120 deletions.
16 changes: 9 additions & 7 deletions src/libcore/ptr.rs
Expand Up @@ -485,8 +485,9 @@ impl<T: ?Sized> *const T {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_null(self) -> bool where T: Sized {
self == null()
pub fn is_null(self) -> bool {
// cast to () pointer, as T may not be sized
self as *const () == null()
}

/// Returns `None` if the pointer is null, or else returns a reference to
Expand Down Expand Up @@ -517,7 +518,7 @@ impl<T: ?Sized> *const T {
/// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Expand Down Expand Up @@ -1116,8 +1117,9 @@ impl<T: ?Sized> *mut T {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_null(self) -> bool where T: Sized {
self == null_mut()
pub fn is_null(self) -> bool {
// cast to () pointer, as T may not be sized
self as *mut () == null_mut()
}

/// Returns `None` if the pointer is null, or else returns a reference to
Expand Down Expand Up @@ -1148,7 +1150,7 @@ impl<T: ?Sized> *mut T {
/// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
if self.is_null() {
None
} else {
Expand Down Expand Up @@ -1272,7 +1274,7 @@ impl<T: ?Sized> *mut T {
/// ```
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> where T: Sized {
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
if self.is_null() {
None
} else {
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/hir/def.rs
Expand Up @@ -35,6 +35,7 @@ pub enum Def {
Variant(DefId),
Trait(DefId),
TyAlias(DefId),
TyForeign(DefId),
AssociatedTy(DefId),
PrimTy(hir::PrimTy),
TyParam(DefId),
Expand Down Expand Up @@ -152,7 +153,7 @@ impl Def {
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
Def::AssociatedConst(id) | Def::Macro(id, ..) |
Def::GlobalAsm(id) => {
Def::GlobalAsm(id) | Def::TyForeign(id) => {
id
}

Expand Down Expand Up @@ -186,6 +187,7 @@ impl Def {
Def::StructCtor(.., CtorKind::Fictive) => bug!("impossible struct constructor"),
Def::Union(..) => "union",
Def::Trait(..) => "trait",
Def::TyForeign(..) => "foreign type",
Def::Method(..) => "method",
Def::Const(..) => "constant",
Def::AssociatedConst(..) => "associated constant",
Expand Down
1 change: 1 addition & 0 deletions src/librustc/hir/intravisit.rs
Expand Up @@ -704,6 +704,7 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v
}
}
ForeignItemStatic(ref typ, _) => visitor.visit_ty(typ),
ForeignItemType => (),
}

walk_list!(visitor, visit_attribute, &foreign_item.attrs);
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/hir/lowering.rs
Expand Up @@ -1722,6 +1722,9 @@ impl<'a> LoweringContext<'a> {
ForeignItemKind::Static(ref t, m) => {
hir::ForeignItemStatic(this.lower_ty(t), m)
}
ForeignItemKind::Ty => {
hir::ForeignItemType
}
},
vis: this.lower_visibility(&i.vis, None),
span: i.span,
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/hir/mod.rs
Expand Up @@ -1912,13 +1912,16 @@ pub enum ForeignItem_ {
/// A foreign static item (`static ext: u8`), with optional mutability
/// (the boolean is true when mutable)
ForeignItemStatic(P<Ty>, bool),
/// A foreign type
ForeignItemType,
}

impl ForeignItem_ {
pub fn descriptive_variant(&self) -> &str {
match *self {
ForeignItemFn(..) => "foreign function",
ForeignItemStatic(..) => "foreign static item",
ForeignItemType => "foreign type",
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/hir/print.rs
Expand Up @@ -478,6 +478,13 @@ impl<'a> State<'a> {
self.end()?; // end the head-ibox
self.end() // end the outer cbox
}
hir::ForeignItemType => {
self.head(&visibility_qualified(&item.vis, "type"))?;
self.print_name(item.name)?;
self.s.word(";")?;
self.end()?; // end the head-ibox
self.end() // end the outer cbox
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/librustc/ich/impls_hir.rs
Expand Up @@ -977,7 +977,8 @@ impl_stable_hash_for!(struct hir::ForeignItem {

impl_stable_hash_for!(enum hir::ForeignItem_ {
ForeignItemFn(fn_decl, arg_names, generics),
ForeignItemStatic(ty, is_mutbl)
ForeignItemStatic(ty, is_mutbl),
ForeignItemType
});

impl_stable_hash_for!(enum hir::Stmt_ {
Expand Down Expand Up @@ -1086,6 +1087,7 @@ impl_stable_hash_for!(enum hir::def::Def {
PrimTy(prim_ty),
TyParam(def_id),
SelfTy(trait_def_id, impl_def_id),
TyForeign(def_id),
Fn(def_id),
Const(def_id),
Static(def_id, is_mutbl),
Expand Down
6 changes: 4 additions & 2 deletions src/librustc/ich/impls_ty.rs
Expand Up @@ -610,8 +610,7 @@ for ty::TypeVariants<'gcx>
def_id.hash_stable(hcx, hasher);
closure_substs.hash_stable(hcx, hasher);
}
TyGenerator(def_id, closure_substs, interior)
=> {
TyGenerator(def_id, closure_substs, interior) => {
def_id.hash_stable(hcx, hasher);
closure_substs.hash_stable(hcx, hasher);
interior.hash_stable(hcx, hasher);
Expand All @@ -630,6 +629,9 @@ for ty::TypeVariants<'gcx>
TyParam(param_ty) => {
param_ty.hash_stable(hcx, hasher);
}
TyForeign(def_id) => {
def_id.hash_stable(hcx, hasher);
}
TyInfer(..) => {
bug!("ty::TypeVariants::hash_stable() - Unexpected variant {:?}.", *self)
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/infer/freshen.rs
Expand Up @@ -312,6 +312,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
ty::TyNever |
ty::TyTuple(..) |
ty::TyProjection(..) |
ty::TyForeign(..) |
ty::TyParam(..) |
ty::TyAnon(..) => {
t.super_fold_with(self)
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/resolve_lifetime.rs
Expand Up @@ -365,6 +365,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir::ForeignItemStatic(..) => {
intravisit::walk_foreign_item(self, item);
}
hir::ForeignItemType => {
intravisit::walk_foreign_item(self, item);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/librustc/traits/coherence.rs
Expand Up @@ -304,6 +304,10 @@ fn ty_is_local_constructor(ty: Ty, infer_is_local: InferIsLocal)-> bool {
def.did.is_local()
}

ty::TyForeign(did) => {
did.is_local()
}

ty::TyDynamic(ref tt, ..) => {
tt.principal().map_or(false, |p| p.def_id().is_local())
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/traits/error_reporting.rs
Expand Up @@ -255,6 +255,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
AdtKind::Enum => Some(17),
},
ty::TyGenerator(..) => Some(18),
ty::TyForeign(..) => Some(19),
ty::TyInfer(..) | ty::TyError => None
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/librustc/traits/select.rs
Expand Up @@ -1705,6 +1705,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// say nothing; a candidate may be added by
// `assemble_candidates_from_object_ty`.
}
ty::TyForeign(..) => {
// Since the contents of foreign types is unknown,
// we don't add any `..` impl. Default traits could
// still be provided by a manual implementation for
// this trait and type.
}
ty::TyParam(..) |
ty::TyProjection(..) => {
// In these cases, we don't know what the actual
Expand Down Expand Up @@ -2022,7 +2028,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
Where(ty::Binder(Vec::new()))
}

ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) => Never,
ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) => Never,

ty::TyTuple(tys, _) => {
Where(ty::Binder(tys.last().into_iter().cloned().collect()))
Expand Down Expand Up @@ -2066,7 +2072,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
Where(ty::Binder(Vec::new()))
}

ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) | ty::TyGenerator(..) |
ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) |
ty::TyGenerator(..) | ty::TyForeign(..) |
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
Never
}
Expand Down Expand Up @@ -2148,6 +2155,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {

ty::TyDynamic(..) |
ty::TyParam(..) |
ty::TyForeign(..) |
ty::TyProjection(..) |
ty::TyInfer(ty::TyVar(_)) |
ty::TyInfer(ty::FreshTy(_)) |
Expand Down
6 changes: 5 additions & 1 deletion src/librustc/ty/context.rs
Expand Up @@ -1610,7 +1610,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
pub fn print_debug_stats(self) {
sty_debug_print!(
self,
TyAdt, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, TyGenerator,
TyAdt, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, TyGenerator, TyForeign,
TyDynamic, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon);

println!("Substs interner: #{}", self.interners.substs.borrow().len());
Expand Down Expand Up @@ -1861,6 +1861,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.mk_ty(TyAdt(def, substs))
}

pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
self.mk_ty(TyForeign(def_id))
}

pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
let adt_def = self.adt_def(def_id);
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/error.rs
Expand Up @@ -182,6 +182,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
ty::TyTuple(ref tys, _) if tys.is_empty() => self.to_string(),

ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)),
ty::TyForeign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)),
ty::TyArray(_, n) => {
if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
format!("array of {} elements", n)
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/ty/fast_reject.rs
Expand Up @@ -49,6 +49,7 @@ pub enum SimplifiedTypeGen<D>
AnonSimplifiedType(D),
FunctionSimplifiedType(usize),
ParameterSimplifiedType,
ForeignSimplifiedType(DefId),
}

/// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
Expand Down Expand Up @@ -113,6 +114,9 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty::TyAnon(def_id, _) => {
Some(AnonSimplifiedType(def_id))
}
ty::TyForeign(def_id) => {
Some(ForeignSimplifiedType(def_id))
}
ty::TyInfer(_) | ty::TyError => None,
}
}
Expand Down Expand Up @@ -140,6 +144,7 @@ impl<D: Copy + Debug + Ord + Eq + Hash> SimplifiedTypeGen<D> {
AnonSimplifiedType(d) => AnonSimplifiedType(map(d)),
FunctionSimplifiedType(n) => FunctionSimplifiedType(n),
ParameterSimplifiedType => ParameterSimplifiedType,
ForeignSimplifiedType(d) => ForeignSimplifiedType(d),
}
}
}
Expand Down Expand Up @@ -172,6 +177,7 @@ impl<'gcx, D> HashStable<StableHashingContext<'gcx>> for SimplifiedTypeGen<D>
GeneratorSimplifiedType(d) => d.hash_stable(hcx, hasher),
AnonSimplifiedType(d) => d.hash_stable(hcx, hasher),
FunctionSimplifiedType(n) => n.hash_stable(hcx, hasher),
ForeignSimplifiedType(d) => d.hash_stable(hcx, hasher),
}
}
}
3 changes: 2 additions & 1 deletion src/librustc/ty/flags.rs
Expand Up @@ -63,7 +63,8 @@ impl FlagComputation {
&ty::TyFloat(_) |
&ty::TyUint(_) |
&ty::TyNever |
&ty::TyStr => {
&ty::TyStr |
&ty::TyForeign(..) => {
}

// You might think that we could just return TyError for
Expand Down
7 changes: 5 additions & 2 deletions src/librustc/ty/item_path.rs
Expand Up @@ -281,6 +281,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

ty::TyForeign(did) => self.push_item_path(buffer, did),

ty::TyBool |
ty::TyChar |
ty::TyInt(_) |
Expand Down Expand Up @@ -344,8 +346,9 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
.next(),

ty::TyFnDef(def_id, _) |
ty::TyClosure(def_id, _) => Some(def_id),
ty::TyGenerator(def_id, _, _) => Some(def_id),
ty::TyClosure(def_id, _) |
ty::TyGenerator(def_id, _, _) |
ty::TyForeign(def_id) => Some(def_id),

ty::TyBool |
ty::TyChar |
Expand Down
22 changes: 12 additions & 10 deletions src/librustc/ty/layout.rs
Expand Up @@ -1141,14 +1141,15 @@ impl<'a, 'tcx> Layout {
Ok(Scalar { value: Pointer, non_zero: non_zero })
} else {
let unsized_part = tcx.struct_tail(pointee);
let meta = match unsized_part.sty {
ty::TySlice(_) | ty::TyStr => {
Int(dl.ptr_sized_integer())
}
ty::TyDynamic(..) => Pointer,
_ => return Err(LayoutError::Unknown(unsized_part))
};
Ok(FatPointer { metadata: meta, non_zero: non_zero })
match unsized_part.sty {
ty::TySlice(_) | ty::TyStr => Ok(FatPointer {
metadata: Int(dl.ptr_sized_integer()),
non_zero: non_zero
}),
ty::TyDynamic(..) => Ok(FatPointer { metadata: Pointer, non_zero: non_zero }),
ty::TyForeign(..) => Ok(Scalar { value: Pointer, non_zero: non_zero }),
_ => Err(LayoutError::Unknown(unsized_part)),
}
}
};

Expand Down Expand Up @@ -1239,7 +1240,7 @@ impl<'a, 'tcx> Layout {
non_zero: false
}
}
ty::TyDynamic(..) => {
ty::TyDynamic(..) | ty::TyForeign(..) => {
let mut unit = Struct::new(dl, &vec![], &ReprOptions::default(),
StructKind::AlwaysSizedUnivariant, ty)?;
unit.sized = false;
Expand Down Expand Up @@ -2252,7 +2253,8 @@ impl<'a, 'tcx> TyLayout<'tcx> {
ty::TyFnPtr(_) |
ty::TyNever |
ty::TyFnDef(..) |
ty::TyDynamic(..) => {
ty::TyDynamic(..) |
ty::TyForeign(..) => {
bug!("TyLayout::field_type({:?}): not applicable", self)
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/mod.rs
Expand Up @@ -1784,7 +1784,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
vec![]
}

TyStr | TyDynamic(..) | TySlice(_) | TyError => {
TyStr | TyDynamic(..) | TySlice(_) | TyForeign(..) | TyError => {
// these are never sized - return the target type
vec![ty]
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/outlives.rs
Expand Up @@ -142,6 +142,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
ty::TyNever | // ...
ty::TyAdt(..) | // OutlivesNominalType
ty::TyAnon(..) | // OutlivesNominalType (ish)
ty::TyForeign(..) | // OutlivesNominalType
ty::TyStr | // OutlivesScalar (ish)
ty::TyArray(..) | // ...
ty::TySlice(..) | // ...
Expand Down

0 comments on commit 77f7e85

Please sign in to comment.