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

RFC: Begin extracting frestanding components of libstd #11968

Closed
wants to merge 13 commits into from
4 changes: 2 additions & 2 deletions mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@
# automatically generated for all stage/host/target combinations.
################################################################################

TARGET_CRATES := std extra green rustuv native flate arena glob
TARGET_CRATES := prim std extra green rustuv native flate arena glob
HOST_CRATES := syntax rustc rustdoc rustpkg
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustpkg rustdoc rustc

DEPS_std := native:rustrt
DEPS_std := prim native:rustrt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a DEPS_prim := line just to be explicit? It may also prevent warning about an uninitialized variable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it'd be cool to see an empty dependency line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

DEPS_extra := std
DEPS_green := std
DEPS_rustuv := std native:uv native:uv_support
Expand Down
9 changes: 8 additions & 1 deletion src/libextra/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,14 @@ impl<T> Rawlink<T> {

/// Convert the `Rawlink` into an Option value
fn resolve_immut(&self) -> Option<&T> {
unsafe { self.p.to_option() }
if self.p.is_null() {
None
} else {
unsafe {
let p: &T = &*self.p;
Some(p)
}
}
}

/// Convert the `Rawlink` into an Option value
Expand Down
67 changes: 18 additions & 49 deletions src/libstd/cast.rs → src/libprim/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,7 @@

//! Unsafe casting functions

use ptr::RawPtr;
use mem;
use unstable::intrinsics;
use ptr::copy_nonoverlapping_memory;

/// Casts the value at `src` to U. The two types must have the same length.
#[inline]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
let mut dest: U = intrinsics::uninit();
let dest_ptr: *mut u8 = transmute(&mut dest);
let src_ptr: *u8 = transmute(src);
copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
dest
}
use intrinsics;

/**
* Move a thing into the void
Expand All @@ -35,13 +22,6 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
#[inline]
pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing); }

/**
* Force-increment the reference count on a shared box. If used
* carelessly, this can leak the box.
*/
#[inline]
pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }

/**
* Transform a value of one type into a value of another type.
* Both types must have the same size and alignment.
Expand Down Expand Up @@ -72,13 +52,13 @@ pub unsafe fn transmute_region<'a,'b,T>(ptr: &'a T) -> &'b T {

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_mut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *mut T {
pub unsafe fn transmute_mut_unsafe<T>(ptr: *T) -> *mut T {
transmute(ptr)
}

/// Coerce an immutable reference to be mutable.
#[inline]
pub unsafe fn transmute_immut_unsafe<T,P:RawPtr<T>>(ptr: P) -> *T {
pub unsafe fn transmute_immut_unsafe<T>(ptr: *mut T) -> *T {
transmute(ptr)
}

Expand Down Expand Up @@ -106,43 +86,32 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
transmute_region(ptr)
}


/****************************************************************************
* Tests
****************************************************************************/
/// Casts the value at `src` to U. The two types must have the same length.
#[inline]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
let mut dest: U = intrinsics::uninit();
let dest_ptr: *mut u8 = transmute(&mut dest);
let src_ptr: *u8 = transmute(src);
intrinsics::copy_nonoverlapping_memory(dest_ptr, src_ptr, intrinsics::size_of::<U>());
dest
}

#[cfg(test)]
mod tests {
use cast::{bump_box_refcount, transmute};
use unstable::raw;
use super::*;

#[test]
fn test_transmute_copy() {
assert_eq!(1u, unsafe { ::cast::transmute_copy(&1) });
}

#[test]
fn test_bump_managed_refcount() {
unsafe {
let managed = @~"box box box"; // refcount 1
bump_box_refcount(managed); // refcount 2
let ptr: *int = transmute(managed); // refcount 2
let _box1: @~str = ::cast::transmute_copy(&ptr);
let _box2: @~str = ::cast::transmute_copy(&ptr);
assert!(*_box1 == ~"box box box");
assert!(*_box2 == ~"box box box");
// Will destroy _box1 and _box2. Without the bump, this would
// use-after-free. With too many bumps, it would leak.
}
assert_eq!(1u, unsafe { transmute_copy(&1) });
}

#[test]
fn test_transmute() {
unsafe {
let x = @100u8;
let x: *raw::Box<u8> = transmute(x);
assert!((*x).data == 100);
let _x: @int = transmute(x);
let x = ~100u8;
let x: *u8 = transmute(x);
assert!(*x == 100);
let _x: ~u8 = transmute(x);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ A quick refresher on memory ordering:

// This is needed to prevent duplicate lang item definitions.
#[cfg(test)]
pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId};
pub use realprim::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId};

pub type GlueFn = extern "Rust" fn(*i8);

Expand Down Expand Up @@ -502,10 +502,9 @@ extern "rust-intrinsic" {
/// `TypeId` represents a globally unique identifier for a type
#[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and
// middle/lang_items.rs
#[deriving(Eq, IterBytes)]
#[cfg(not(test))]
pub struct TypeId {
priv t: u64,
t: u64,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we wanted this to be priv to allow us to change its format over time?

I suppose it doesn't matter too much if intrinsics are always unstable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I had to make it pub to separate it from its Clone and Eq impls.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could come up with some way to make this private. In the future it's conceivable that Clone and Eq will end up in this crate again.


#[cfg(not(test))]
Expand Down
10 changes: 0 additions & 10 deletions src/libstd/kinds.rs → src/libprim/kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ pub mod marker {
/// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
/// for some lifetime `'a`, but not the other way around).
#[lang="covariant_type"]
#[deriving(Eq,Clone)]
pub struct CovariantType<T>;

/// A marker type whose type parameter `T` is considered to be
Expand Down Expand Up @@ -130,7 +129,6 @@ pub mod marker {
/// function requires arguments of type `T`, it must also accept
/// arguments of type `U`, hence such a conversion is safe.
#[lang="contravariant_type"]
#[deriving(Eq,Clone)]
pub struct ContravariantType<T>;

/// A marker type whose type parameter `T` is considered to be
Expand All @@ -154,7 +152,6 @@ pub mod marker {
/// never written, but in fact `Cell` uses unsafe code to achieve
/// interior mutability.
#[lang="invariant_type"]
#[deriving(Eq,Clone)]
pub struct InvariantType<T>;

/// As `CovariantType`, but for lifetime parameters. Using
Expand All @@ -174,7 +171,6 @@ pub mod marker {
/// For more information about variance, refer to this Wikipedia
/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
#[lang="covariant_lifetime"]
#[deriving(Eq,Clone)]
pub struct CovariantLifetime<'a>;

/// As `ContravariantType`, but for lifetime parameters. Using
Expand All @@ -190,7 +186,6 @@ pub mod marker {
/// For more information about variance, refer to this Wikipedia
/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
#[lang="contravariant_lifetime"]
#[deriving(Eq,Clone)]
pub struct ContravariantLifetime<'a>;

/// As `InvariantType`, but for lifetime parameters. Using
Expand All @@ -201,35 +196,30 @@ pub mod marker {
/// and this pointer is itself stored in an inherently mutable
/// location (such as a `Cell`).
#[lang="invariant_lifetime"]
#[deriving(Eq,Clone)]
pub struct InvariantLifetime<'a>;

/// A type which is considered "not freezable", meaning that
/// its contents could change even if stored in an immutable
/// context or it is the referent of an `&T` pointer. This is
/// typically embedded in other types, such as `Cell`.
#[lang="no_freeze_bound"]
#[deriving(Eq,Clone)]
pub struct NoFreeze;

/// A type which is considered "not sendable", meaning that it cannot
/// be safely sent between tasks, even if it is owned. This is
/// typically embedded in other types, such as `Gc`, to ensure that
/// their instances remain thread-local.
#[lang="no_send_bound"]
#[deriving(Eq,Clone)]
pub struct NoSend;

/// A type which is considered "not POD", meaning that it is not
/// implicitly copyable. This is typically embedded in other types to
/// ensure that they are never copied, even if they lack a destructor.
#[lang="no_pod_bound"]
#[deriving(Eq,Clone)]
pub struct NoPod;

/// A type which is considered managed by the GC. This is typically
/// embedded in other types.
#[lang="managed_bound"]
#[deriving(Eq,Clone)]
pub struct Managed;
}
42 changes: 42 additions & 0 deletions src/libprim/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a doc comment about this crate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Sorry ...

#[crate_id = "prim#0.10-pre"];
#[license = "MIT/ASL2"];
#[crate_type = "rlib"];
#[crate_type = "dylib"];
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://static.rust-lang.org/doc/master")];

#[no_std];
#[feature(globs)];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that we need globs here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They came with the tests!

#[feature(phase)];
#[feature(macro_rules)];
#[feature(managed_boxes)];

#[cfg(test)] #[phase(syntax)] extern mod std;

#[cfg(test)] extern mod realprim = "prim";
#[cfg(test)] extern mod std;
#[cfg(test)] extern mod rustuv;
#[cfg(test)] extern mod green;
#[cfg(test)] extern mod native;

#[cfg(test)] pub use kinds = realprim::kinds;

pub mod cast;
pub mod intrinsics;
#[cfg(not(test))] pub mod kinds;
pub mod mem;
pub mod ptr;
pub mod raw;
pub mod util;
pub mod tuple;
2 changes: 1 addition & 1 deletion src/libstd/mem.rs → src/libprim/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

//! Functions relating to memory layout

use unstable::intrinsics;
use intrinsics;

/// Returns the size of a type
#[inline]
Expand Down
Loading