Skip to content

Transmute cleanup #18318

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

Merged
merged 2 commits into from
Nov 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
}
}

fn visit_ids(&self, f: |&mut ast_util::IdVisitor<Context>|) {
fn visit_ids(&mut self, f: |&mut ast_util::IdVisitor<Context>|) {
let mut v = ast_util::IdVisitor {
operation: self,
pass_through_items: false,
Expand Down Expand Up @@ -749,7 +749,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {

// Output any lints that were previously added to the session.
impl<'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> {
fn visit_id(&self, id: ast::NodeId) {
fn visit_id(&mut self, id: ast::NodeId) {
match self.tcx.sess.lints.borrow_mut().pop(&id) {
None => {}
Some(lints) => {
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl astencode_tag {
pub fn from_uint(value : uint) -> Option<astencode_tag> {
let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
if !is_a_tag { None } else {
Some(unsafe { mem::transmute(value) })
Some(unsafe { mem::transmute::<uint, astencode_tag>(value) })
}
}
}
Expand Down Expand Up @@ -247,4 +247,3 @@ pub const tag_type_param_def: uint = 0xa5;

pub const tag_item_generics: uint = 0xa6;
pub const tag_method_ty_generics: uint = 0xa7;

31 changes: 10 additions & 21 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use serialize::Encodable;
use std::cell::RefCell;
use std::hash::Hash;
use std::hash;
use std::mem;
use std::collections::HashMap;
use syntax::abi;
use syntax::ast::*;
Expand Down Expand Up @@ -1508,44 +1507,36 @@ fn my_visit_expr(_e: &Expr) { }

fn my_visit_item(i: &Item,
rbml_w: &mut Encoder,
ecx_ptr: *const int,
ecx: &EncodeContext,
index: &mut Vec<entry<i64>>) {
let mut rbml_w = unsafe { rbml_w.unsafe_clone() };
// See above
let ecx: &EncodeContext = unsafe { mem::transmute(ecx_ptr) };
ecx.tcx.map.with_path(i.id, |path| {
encode_info_for_item(ecx, &mut rbml_w, i, index, path, i.vis);
encode_info_for_item(ecx, rbml_w, i, index, path, i.vis);
});
}
Copy link
Member

Choose a reason for hiding this comment

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

Whoa, so glad to see this gone 😍


fn my_visit_foreign_item(ni: &ForeignItem,
rbml_w: &mut Encoder,
ecx_ptr:*const int,
ecx: &EncodeContext,
index: &mut Vec<entry<i64>>) {
// See above
let ecx: &EncodeContext = unsafe { mem::transmute(ecx_ptr) };
debug!("writing foreign item {}::{}",
ecx.tcx.map.path_to_string(ni.id),
token::get_ident(ni.ident));

let mut rbml_w = unsafe {
rbml_w.unsafe_clone()
};
let abi = ecx.tcx.map.get_foreign_abi(ni.id);
ecx.tcx.map.with_path(ni.id, |path| {
encode_info_for_foreign_item(ecx, &mut rbml_w,
encode_info_for_foreign_item(ecx, rbml_w,
ni, index,
path, abi);
});
}

struct EncodeVisitor<'a,'b:'a> {
struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
rbml_w_for_visit_item: &'a mut Encoder<'b>,
ecx_ptr:*const int,
ecx: &'a EncodeContext<'c,'tcx>,
index: &'a mut Vec<entry<i64>>,
}

impl<'a, 'b, 'v> Visitor<'v> for EncodeVisitor<'a, 'b> {
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
visit::walk_expr(self, ex);
my_visit_expr(ex);
Expand All @@ -1554,14 +1545,14 @@ impl<'a, 'b, 'v> Visitor<'v> for EncodeVisitor<'a, 'b> {
visit::walk_item(self, i);
my_visit_item(i,
self.rbml_w_for_visit_item,
self.ecx_ptr,
self.ecx,
self.index);
}
fn visit_foreign_item(&mut self, ni: &ForeignItem) {
visit::walk_foreign_item(self, ni);
my_visit_foreign_item(ni,
self.rbml_w_for_visit_item,
self.ecx_ptr,
self.ecx,
self.index);
}
}
Expand All @@ -1585,11 +1576,9 @@ fn encode_info_for_items(ecx: &EncodeContext,
syntax::parse::token::special_idents::invalid,
Public);

// See comment in `encode_side_tables_for_ii` in astencode
let ecx_ptr: *const int = unsafe { mem::transmute(ecx) };
visit::walk_crate(&mut EncodeVisitor {
index: &mut index,
ecx_ptr: ecx_ptr,
ecx: ecx,
rbml_w_for_visit_item: &mut *rbml_w,
}, krate);

Expand Down
35 changes: 11 additions & 24 deletions src/librustc/metadata/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ use std::c_str::ToCStr;
use std::cmp;
use std::io::fs::PathExtensions;
use std::io;
use std::mem;
use std::ptr;
use std::slice;
use std::string;
Expand Down Expand Up @@ -287,8 +286,8 @@ pub struct Library {

pub struct ArchiveMetadata {
_archive: ArchiveRO,
// See comments in ArchiveMetadata::new for why this is static
data: &'static [u8],
// points into self._archive
data: *const [u8],
}

pub struct CratePaths {
Expand Down Expand Up @@ -709,33 +708,21 @@ pub fn note_crate_name(diag: &SpanHandler, name: &str) {

impl ArchiveMetadata {
fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
let data: &'static [u8] = {
let data = match ar.read(METADATA_FILENAME) {
Some(data) => data,
None => {
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
return None;
}
};
// This data is actually a pointer inside of the archive itself, but
// we essentially want to cache it because the lookup inside the
// archive is a fairly expensive operation (and it's queried for
// *very* frequently). For this reason, we transmute it to the
// static lifetime to put into the struct. Note that the buffer is
// never actually handed out with a static lifetime, but rather the
// buffer is loaned with the lifetime of this containing object.
// Hence, we're guaranteed that the buffer will never be used after
// this object is dead, so this is a safe operation to transmute and
// store the data as a static buffer.
unsafe { mem::transmute(data) }
let data = match ar.read(METADATA_FILENAME) {
Some(data) => data as *const [u8],
None => {
debug!("didn't find '{}' in the archive", METADATA_FILENAME);
return None;
}
};

Some(ArchiveMetadata {
_archive: ar,
data: data,
})
}

pub fn as_slice<'a>(&'a self) -> &'a [u8] { self.data }
pub fn as_slice<'a>(&'a self) -> &'a [u8] { unsafe { &*self.data } }
}

// Just a small wrapper to time how long reading metadata takes.
Expand Down Expand Up @@ -798,7 +785,7 @@ fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result<MetadataBlob
let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
let mut found =
Err(format!("metadata not found: '{}'", filename.display()));
let cvbuf: *const u8 = mem::transmute(cbuf);
let cvbuf: *const u8 = cbuf as *const u8;
let vlen = encoder::metadata_encoding_version.len();
debug!("checking {} bytes of metadata-version stamp",
vlen);
Expand Down
43 changes: 10 additions & 33 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ use syntax::parse::token;
use syntax::ptr::P;
use syntax;

use libc;
use std::io::Seek;
use std::mem;
use std::rc::Rc;

use rbml::io::SeekableMemWriter;
Expand Down Expand Up @@ -1128,46 +1126,25 @@ impl<'a> write_tag_and_id for Encoder<'a> {
}
}

struct SideTableEncodingIdVisitor<'a,'b:'a> {
ecx_ptr: *const libc::c_void,
new_rbml_w: &'a mut Encoder<'b>,
struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
ecx: &'a e::EncodeContext<'c, 'tcx>,
rbml_w: &'a mut Encoder<'b>,
}

impl<'a,'b> ast_util::IdVisitingOperation for
SideTableEncodingIdVisitor<'a,'b> {
fn visit_id(&self, id: ast::NodeId) {
// Note: this will cause a copy of rbml_w, which is bad as
// it is mutable. But I believe it's harmless since we generate
// balanced EBML.
//
// FIXME(pcwalton): Don't copy this way.
let mut new_rbml_w = unsafe {
self.new_rbml_w.unsafe_clone()
};
// See above
let ecx: &e::EncodeContext = unsafe {
mem::transmute(self.ecx_ptr)
};
encode_side_tables_for_id(ecx, &mut new_rbml_w, id)
impl<'a, 'b, 'c, 'tcx> ast_util::IdVisitingOperation for
SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> {
fn visit_id(&mut self, id: ast::NodeId) {
encode_side_tables_for_id(self.ecx, self.rbml_w, id)
}
}

fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
rbml_w: &mut Encoder,
ii: &ast::InlinedItem) {
rbml_w.start_tag(c::tag_table as uint);
let mut new_rbml_w = unsafe {
rbml_w.unsafe_clone()
};

// Because the ast visitor uses @IdVisitingOperation, I can't pass in
// ecx directly, but /I/ know that it'll be fine since the lifetime is
// tied to the CrateContext that lives throughout this entire section.
ast_util::visit_ids_for_inlined_item(ii, &SideTableEncodingIdVisitor {
ecx_ptr: unsafe {
mem::transmute(ecx)
},
new_rbml_w: &mut new_rbml_w,
ast_util::visit_ids_for_inlined_item(ii, &mut SideTableEncodingIdVisitor {
ecx: ecx,
rbml_w: rbml_w
});
rbml_w.end_tag();
}
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ use util::nodemap::NodeMap;

use std::fmt;
use std::io;
use std::mem::transmute;
use std::rc::Rc;
use std::str;
use std::uint;
Expand Down Expand Up @@ -380,10 +379,7 @@ fn visit_fn(ir: &mut IrMaps,
// swap in a new set of IR maps for this function body:
let mut fn_maps = IrMaps::new(ir.tcx);

unsafe {
debug!("creating fn_maps: {}",
transmute::<&IrMaps, *const IrMaps>(&fn_maps));
}
debug!("creating fn_maps: {}", &fn_maps as *const IrMaps);

for arg in decl.inputs.iter() {
pat_util::pat_bindings(&ir.tcx.def_map,
Expand Down
58 changes: 1 addition & 57 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,66 +16,10 @@ use middle::ty_fold::{TypeFoldable, TypeFolder};
use util::ppaux::Repr;

use std::fmt;
use std::mem;
use std::raw;
use std::slice::{Items, MutItems};
use std::slice::Items;
use std::vec::Vec;
use syntax::codemap::{Span, DUMMY_SP};

///////////////////////////////////////////////////////////////////////////
// HomogeneousTuple3 trait
//
// This could be moved into standard library at some point.

trait HomogeneousTuple3<T> {
fn len(&self) -> uint;
fn as_slice<'a>(&'a self) -> &'a [T];
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T];
fn iter<'a>(&'a self) -> Items<'a, T>;
fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T>;
fn get<'a>(&'a self, index: uint) -> Option<&'a T>;
fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>;
}

impl<T> HomogeneousTuple3<T> for (T, T, T) {
fn len(&self) -> uint {
3
}

fn as_slice<'a>(&'a self) -> &'a [T] {
unsafe {
let ptr: *const T = mem::transmute(self);
let slice = raw::Slice { data: ptr, len: 3 };
mem::transmute(slice)
}
}

fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
unsafe {
let ptr: *const T = mem::transmute(self);
let slice = raw::Slice { data: ptr, len: 3 };
mem::transmute(slice)
}
}

fn iter<'a>(&'a self) -> Items<'a, T> {
let slice: &'a [T] = self.as_slice();
slice.iter()
}

fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
self.as_mut_slice().iter_mut()
}

fn get<'a>(&'a self, index: uint) -> Option<&'a T> {
self.as_slice().get(index)
}

fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T> {
Some(&mut self.as_mut_slice()[index]) // wrong: fallible
}
}

///////////////////////////////////////////////////////////////////////////

/**
Expand Down
15 changes: 9 additions & 6 deletions src/librustc/middle/trans/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use std::collections::HashMap;
use libc::c_uint;

#[deriving(Clone, PartialEq, Show)]
#[repr(C)]
pub struct Type {
rf: TypeRef
}
Expand Down Expand Up @@ -283,9 +284,10 @@ impl Type {
if n_elts == 0 {
return Vec::new();
}
let mut elts = Vec::from_elem(n_elts, 0 as TypeRef);
llvm::LLVMGetStructElementTypes(self.to_ref(), &mut elts[0]);
mem::transmute(elts)
let mut elts = Vec::from_elem(n_elts, Type { rf: 0 as TypeRef });
llvm::LLVMGetStructElementTypes(self.to_ref(),
elts.as_mut_ptr() as *mut TypeRef);
elts
}
}

Expand All @@ -296,9 +298,10 @@ impl Type {
pub fn func_params(&self) -> Vec<Type> {
unsafe {
let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as uint;
let args = Vec::from_elem(n_args, 0 as TypeRef);
llvm::LLVMGetParamTypes(self.to_ref(), args.as_ptr());
mem::transmute(args)
let mut args = Vec::from_elem(n_args, Type { rf: 0 as TypeRef });
llvm::LLVMGetParamTypes(self.to_ref(),
args.as_mut_ptr() as *mut TypeRef);
args
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ extern {
pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *const TypeRef);
pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef);

/* Operations on struct types */
pub fn LLVMStructTypeInContext(C: ContextRef,
Expand Down Expand Up @@ -2195,4 +2195,3 @@ pub unsafe fn static_link_hack_this_sucks() {
// Works to the above fix for #15460 to ensure LLVM dependencies that
// are only used by rustllvm don't get stripped by the linker.
mod llvmdeps;

Loading