diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index a18d91196e0..6da74eee8a3 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -532,7 +532,7 @@ fn with_lint_attrs(&mut self, } } - fn visit_ids(&self, f: |&mut ast_util::IdVisitor|) { + fn visit_ids(&mut self, f: |&mut ast_util::IdVisitor|) { let mut v = ast_util::IdVisitor { operation: self, pass_through_items: false, @@ -749,7 +749,7 @@ fn visit_attribute(&mut self, attr: &ast::Attribute) { // 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) => { diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index bc58097b860..a04f94c31bf 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -148,7 +148,7 @@ impl astencode_tag { pub fn from_uint(value : uint) -> Option { 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::(value) }) } } } @@ -247,4 +247,3 @@ pub struct LinkMeta { pub const tag_item_generics: uint = 0xa6; pub const tag_method_ty_generics: uint = 0xa7; - diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index a5d3cc1f12c..fd389c1f314 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -29,7 +29,6 @@ use std::cell::RefCell; use std::hash::Hash; use std::hash; -use std::mem; use std::collections::HashMap; use syntax::abi; use syntax::ast::*; @@ -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>) { - 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); }); } fn my_visit_foreign_item(ni: &ForeignItem, rbml_w: &mut Encoder, - ecx_ptr:*const int, + ecx: &EncodeContext, index: &mut Vec>) { - // 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>, } -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); @@ -1554,14 +1545,14 @@ fn visit_item(&mut self, i: &Item) { 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); } } @@ -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); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 7b67def4051..738eeaae6a5 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -231,7 +231,6 @@ use std::cmp; use std::io::fs::PathExtensions; use std::io; -use std::mem; use std::ptr; use std::slice; use std::string; @@ -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 { @@ -709,33 +708,21 @@ pub fn note_crate_name(diag: &SpanHandler, name: &str) { impl ArchiveMetadata { fn new(ar: ArchiveRO) -> Option { - 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. @@ -798,7 +785,7 @@ fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result { - 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) } } @@ -1150,18 +1136,9 @@ 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(); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a11d5f6604e..b5847a94b8d 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -118,7 +118,6 @@ use std::fmt; use std::io; -use std::mem::transmute; use std::rc::Rc; use std::str; use std::uint; @@ -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, diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index b986d4dd591..bec02c736ad 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -16,66 +16,10 @@ 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 { - 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 HomogeneousTuple3 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 - } -} - /////////////////////////////////////////////////////////////////////////// /** diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index d8424c9f316..1746f785311 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -27,6 +27,7 @@ use libc::c_uint; #[deriving(Clone, PartialEq, Show)] +#[repr(C)] pub struct Type { rf: TypeRef } @@ -283,9 +284,10 @@ pub fn field_types(&self) -> Vec { 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 } } @@ -296,9 +298,10 @@ pub fn return_type(&self) -> Type { pub fn func_params(&self) -> Vec { 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 } } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 06456a91e03..48e1e590058 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -547,7 +547,7 @@ pub fn LLVMFunctionType(ReturnType: TypeRef, 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, @@ -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; - diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a2c859cf9fd..1edcb35289a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -119,7 +119,7 @@ impl Name { pub fn as_str<'a>(&'a self) -> &'a str { unsafe { // FIXME #12938: can't use copy_lifetime since &str isn't a &T - ::std::mem::transmute(token::get_name(*self).get()) + ::std::mem::transmute::<&str,&str>(token::get_name(*self).get()) } } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 8b0e1f32fd4..863f53be798 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -21,7 +21,6 @@ use visit::Visitor; use visit; -use std::cell::Cell; use std::cmp; use std::u32; @@ -333,20 +332,20 @@ pub fn add(&mut self, id: NodeId) { } pub trait IdVisitingOperation { - fn visit_id(&self, node_id: NodeId); + fn visit_id(&mut self, node_id: NodeId); } /// A visitor that applies its operation to all of the node IDs /// in a visitable thing. pub struct IdVisitor<'a, O:'a> { - pub operation: &'a O, + pub operation: &'a mut O, pub pass_through_items: bool, pub visited_outermost: bool, } impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> { - fn visit_generics_helper(&self, generics: &Generics) { + fn visit_generics_helper(&mut self, generics: &Generics) { for type_parameter in generics.ty_params.iter() { self.operation.visit_id(type_parameter.id) } @@ -540,7 +539,7 @@ fn visit_lifetime_decl(&mut self, def: &'v LifetimeDef) { } pub fn visit_ids_for_inlined_item(item: &InlinedItem, - operation: &O) { + operation: &mut O) { let mut id_visitor = IdVisitor { operation: operation, pass_through_items: true, @@ -551,23 +550,21 @@ pub fn visit_ids_for_inlined_item(item: &InlinedItem, } struct IdRangeComputingVisitor { - result: Cell, + result: IdRange, } impl IdVisitingOperation for IdRangeComputingVisitor { - fn visit_id(&self, id: NodeId) { - let mut id_range = self.result.get(); - id_range.add(id); - self.result.set(id_range) + fn visit_id(&mut self, id: NodeId) { + self.result.add(id); } } pub fn compute_id_range_for_inlined_item(item: &InlinedItem) -> IdRange { - let visitor = IdRangeComputingVisitor { - result: Cell::new(IdRange::max()) + let mut visitor = IdRangeComputingVisitor { + result: IdRange::max() }; - visit_ids_for_inlined_item(item, &visitor); - visitor.result.get() + visit_ids_for_inlined_item(item, &mut visitor); + visitor.result } pub fn compute_id_range_for_fn_body(fk: visit::FnKind, @@ -582,16 +579,16 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind, * ignoring nested items. */ - let visitor = IdRangeComputingVisitor { - result: Cell::new(IdRange::max()) + let mut visitor = IdRangeComputingVisitor { + result: IdRange::max() }; let mut id_visitor = IdVisitor { - operation: &visitor, + operation: &mut visitor, pass_through_items: false, visited_outermost: false, }; id_visitor.visit_fn(fk, decl, body, sp, id); - visitor.result.get() + id_visitor.operation.result } pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index d56aa8da72a..615cd34ca14 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -668,12 +668,12 @@ pub fn get<'a>(&'a self) -> &'a str { impl BytesContainer for InternedString { fn container_as_bytes<'a>(&'a self) -> &'a [u8] { - // FIXME(pcwalton): This is a workaround for the incorrect signature + // FIXME #12938: This is a workaround for the incorrect signature // of `BytesContainer`, which is itself a workaround for the lack of // DST. unsafe { let this = self.get(); - mem::transmute(this.container_as_bytes()) + mem::transmute::<&[u8],&[u8]>(this.container_as_bytes()) } } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 386fd8ae5a6..4cfc95d4c3f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -169,17 +169,14 @@ pub fn to_string(f: |&mut State| -> IoResult<()>) -> String { let mut s = rust_printer(box MemWriter::new()); f(&mut s).unwrap(); eof(&mut s.s).unwrap(); - unsafe { + let wr = unsafe { // FIXME(pcwalton): A nasty function to extract the string from an `io::Writer` // that we "know" to be a `MemWriter` that works around the lack of checked // downcasts. - let obj: TraitObject = mem::transmute_copy(&s.s.out); - let wr: Box = mem::transmute(obj.data); - let result = - String::from_utf8(wr.get_ref().as_slice().to_vec()).unwrap(); - mem::forget(wr); - result.to_string() - } + let obj: &TraitObject = mem::transmute(&s.s.out); + mem::transmute::<*mut (), &MemWriter>(obj.data) + }; + String::from_utf8(wr.get_ref().to_vec()).unwrap() } pub fn binop_to_string(op: BinOpToken) -> &'static str {