diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 8b82196187b0..02bcabbf3e63 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -295,7 +295,7 @@ pub fn phase_3_run_analysis_passes(sess: Session, middle::liveness::check_crate(ty_cx, method_map, capture_map, crate)); - let (root_map, write_guard_map) = + let root_map = time(time_passes, "borrow checking", (), |_| middle::borrowck::check_crate(ty_cx, method_map, moves_map, moved_variables_set, @@ -330,7 +330,6 @@ pub fn phase_3_run_analysis_passes(sess: Session, root_map: root_map, method_map: method_map, vtable_map: vtable_map, - write_guard_map: write_guard_map, capture_map: capture_map }, reachable: reachable_map diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 22fc7f4b3ea6..f0cb45339688 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -342,7 +342,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { let did = parse_def(st, TypeParameter, |x,y| conv(x,y)); return ty::mk_self(st.tcx, did); } - '@' => return ty::mk_box(st.tcx, parse_mt(st, |x,y| conv(x,y))), + '@' => return ty::mk_box(st.tcx, parse_ty(st, |x,y| conv(x,y))), '~' => return ty::mk_uniq(st.tcx, parse_mt(st, |x,y| conv(x,y))), '*' => return ty::mk_ptr(st.tcx, parse_mt(st, |x,y| conv(x,y))), '&' => { diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 1f4d54ad4bbf..2ba4038e5b44 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -292,7 +292,7 @@ fn enc_sty(w: &mut MemWriter, cx: @ctxt, st: &ty::sty) { for t in ts.iter() { enc_ty(w, cx, *t); } mywrite!(w, "]"); } - ty::ty_box(mt) => { mywrite!(w, "@"); enc_mt(w, cx, mt); } + ty::ty_box(typ) => { mywrite!(w, "@"); enc_ty(w, cx, typ); } ty::ty_uniq(mt) => { mywrite!(w, "~"); enc_mt(w, cx, mt); } ty::ty_ptr(mt) => { mywrite!(w, "*"); enc_mt(w, cx, mt); } ty::ty_rptr(r, mt) => { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index d03c73a81a0e..2e18b9a72448 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -55,7 +55,6 @@ pub struct Maps { root_map: middle::borrowck::root_map, method_map: middle::typeck::method_map, vtable_map: middle::typeck::vtable_map, - write_guard_map: middle::borrowck::write_guard_map, capture_map: middle::moves::CaptureMap, } diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 6176f5601c14..c26efbcb4989 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -368,11 +368,15 @@ impl<'a> CheckLoanCtxt<'a> { cmt = b; } + mc::cat_deref(_, _, mc::gc_ptr) => { + assert_eq!(cmt.mutbl, mc::McImmutable); + return; + } + mc::cat_rvalue(..) | mc::cat_static_item | mc::cat_copied_upvar(..) | mc::cat_deref(_, _, mc::unsafe_ptr(..)) | - mc::cat_deref(_, _, mc::gc_ptr(..)) | mc::cat_deref(_, _, mc::region_ptr(..)) => { assert_eq!(cmt.mutbl, mc::McDeclared); return; @@ -411,20 +415,6 @@ impl<'a> CheckLoanCtxt<'a> { check_for_aliasability_violation(this, expr, b); } - mc::cat_deref(_, deref_count, mc::gc_ptr(ast::MutMutable)) => { - // Dynamically check writes to `@mut` - - let key = root_map_key { - id: guarantor.id, - derefs: deref_count - }; - debug!("Inserting write guard at {:?}", key); - let mut write_guard_map = this.bccx - .write_guard_map - .borrow_mut(); - write_guard_map.get().insert(key); - } - _ => {} } @@ -455,7 +445,7 @@ impl<'a> CheckLoanCtxt<'a> { mc::cat_self(..) | mc::cat_deref(_, _, mc::unsafe_ptr(..)) | mc::cat_static_item(..) | - mc::cat_deref(_, _, mc::gc_ptr(_)) | + mc::cat_deref(_, _, mc::gc_ptr) | mc::cat_deref(_, _, mc::region_ptr(MutImmutable, _)) => { // Aliasability is independent of base cmt match cmt.freely_aliasable() { diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index 907a8e8fdd97..3b16d7e7e1c6 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -102,7 +102,7 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt, cmt: mc::cmt) -> bool { match cmt.cat { mc::cat_deref(_, _, mc::region_ptr(..)) | - mc::cat_deref(_, _, mc::gc_ptr(..)) | + mc::cat_deref(_, _, mc::gc_ptr) | mc::cat_deref(_, _, mc::unsafe_ptr(..)) | mc::cat_stack_upvar(..) | mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => { diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index 38598e8b78fc..9a56ec52cce2 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -16,10 +16,8 @@ use middle::borrowck::*; use mc = middle::mem_categorization; use middle::ty; -use syntax::ast::{MutImmutable, MutMutable}; use syntax::ast; use syntax::codemap::Span; -use util::ppaux::{note_and_explain_region}; type R = Result<(),()>; @@ -89,12 +87,11 @@ impl<'a> GuaranteeLifetimeContext<'a> { Ok(()) } - mc::cat_deref(base, derefs, mc::gc_ptr(ptr_mutbl)) => { + mc::cat_deref(base, derefs, mc::gc_ptr) => { let base_scope = self.scope(base); // L-Deref-Managed-Imm-User-Root let omit_root = ( - ptr_mutbl == MutImmutable && self.bccx.is_subregion_of(self.loan_region, base_scope) && self.is_rvalue_or_immutable(base) && !self.is_moved(base) @@ -103,7 +100,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { if !omit_root { // L-Deref-Managed-Imm-Compiler-Root // L-Deref-Managed-Mut-Compiler-Root - self.check_root(cmt, base, derefs, ptr_mutbl, discr_scope) + self.check_root(cmt, base, derefs, discr_scope) } else { debug!("omitting root, base={}, base_scope={:?}", base.repr(self.tcx()), base_scope); @@ -192,14 +189,12 @@ impl<'a> GuaranteeLifetimeContext<'a> { cmt_deref: mc::cmt, cmt_base: mc::cmt, derefs: uint, - ptr_mutbl: ast::Mutability, discr_scope: Option) -> R { - debug!("check_root(cmt_deref={}, cmt_base={}, derefs={:?}, ptr_mutbl={:?}, \ + debug!("check_root(cmt_deref={}, cmt_base={}, derefs={:?}, \ discr_scope={:?})", cmt_deref.repr(self.tcx()), cmt_base.repr(self.tcx()), derefs, - ptr_mutbl, discr_scope); // Make sure that the loan does not exceed the maximum time @@ -235,19 +230,6 @@ impl<'a> GuaranteeLifetimeContext<'a> { } }; - // If we are borrowing the inside of an `@mut` box, - // we need to dynamically mark it to prevent incompatible - // borrows from happening later. - let opt_dyna = match ptr_mutbl { - MutImmutable => None, - MutMutable => { - match self.loan_mutbl { - MutableMutability => Some(DynaMut), - ImmutableMutability | ConstMutability => Some(DynaImm) - } - } - }; - // FIXME(#3511) grow to the nearest cleanup scope---this can // cause observable errors if freezing! if !self.bccx.tcx.region_maps.is_cleanup_scope(root_scope) { @@ -256,29 +238,12 @@ impl<'a> GuaranteeLifetimeContext<'a> { let cleanup_scope = self.bccx.tcx.region_maps.cleanup_scope(root_scope); - if opt_dyna.is_some() { - self.tcx().sess.span_warn( - self.span, - format!("Dynamic freeze scope artifically extended \ - (see Issue \\#6248)")); - note_and_explain_region( - self.bccx.tcx, - "managed value only needs to be frozen for ", - ty::ReScope(root_scope), - "..."); - note_and_explain_region( - self.bccx.tcx, - "...but due to Issue #6248, it will be frozen for ", - ty::ReScope(cleanup_scope), - ""); - } - root_scope = cleanup_scope; } // Add a record of what is required let rm_key = root_map_key {id: cmt_deref.id, derefs: derefs}; - let root_info = RootInfo {scope: root_scope, freeze: opt_dyna}; + let root_info = RootInfo {scope: root_scope}; let mut root_map = self.bccx.root_map.borrow_mut(); root_map.get().insert(rm_key, root_info); @@ -357,7 +322,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { } mc::cat_downcast(cmt) | mc::cat_deref(cmt, _, mc::uniq_ptr) | - mc::cat_deref(cmt, _, mc::gc_ptr(..)) | + mc::cat_deref(cmt, _, mc::gc_ptr) | mc::cat_interior(cmt, _) | mc::cat_stack_upvar(cmt) | mc::cat_discr(cmt, _) => { diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index ae6b828ecaaa..50b437e95d5d 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -132,59 +132,11 @@ impl<'a> RestrictionsContext<'a> { Safe } - mc::cat_deref(_, _, mc::gc_ptr(MutImmutable)) => { + mc::cat_deref(_, _, mc::gc_ptr) => { // R-Deref-Imm-Managed Safe } - mc::cat_deref(cmt_base, _, pk @ mc::gc_ptr(MutMutable)) => { - // R-Deref-Managed-Borrowed - // - // Technically, no restrictions are *necessary* here. - // The validity of the borrow is guaranteed - // dynamically. However, nonetheless we add a - // restriction to make a "best effort" to report - // static errors. For example, if there is code like - // - // let v = @mut ~[1, 2, 3]; - // for e in v.iter() { - // v.push(e + 1); - // } - // - // Then the code below would add restrictions on `*v`, - // which means that an error would be reported - // here. This of course is not perfect. For example, - // a function like the following would not report an error - // at compile-time but would fail dynamically: - // - // let v = @mut ~[1, 2, 3]; - // let w = v; - // for e in v.iter() { - // w.push(e + 1); - // } - // - // In addition, we only add a restriction for those cases - // where we can construct a sensible loan path, so an - // example like the following will fail dynamically: - // - // impl V { - // fn get_list(&self) -> @mut ~[int]; - // } - // ... - // let v: &V = ...; - // for e in v.get_list().iter() { - // v.get_list().push(e + 1); - // } - match opt_loan_path(cmt_base) { - None => Safe, - Some(lp_base) => { - let lp = @LpExtend(lp_base, cmt.mutbl, LpDeref(pk)); - SafeIf(lp, ~[Restriction {loan_path: lp, - set: restrictions}]) - } - } - } - mc::cat_deref(cmt_base, _, pk @ mc::region_ptr(MutMutable, lt)) => { // R-Deref-Mut-Borrowed if !self.bccx.is_subregion_of(self.loan_region, lt) { diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 44b967aade67..6193c6fc8988 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -20,7 +20,7 @@ use middle::dataflow::DataFlowOperator; use util::ppaux::{note_and_explain_region, Repr, UserString}; use std::cell::{Cell, RefCell}; -use std::hashmap::{HashSet, HashMap}; +use std::hashmap::HashMap; use std::ops::{BitOr, BitAnd}; use std::result::{Result}; use syntax::ast; @@ -67,14 +67,13 @@ impl Visitor<()> for BorrowckCtxt { } } -pub fn check_crate( - tcx: ty::ctxt, - method_map: typeck::method_map, - moves_map: moves::MovesMap, - moved_variables_set: moves::MovedVariablesSet, - capture_map: moves::CaptureMap, - crate: &ast::Crate) -> (root_map, write_guard_map) -{ +pub fn check_crate(tcx: ty::ctxt, + method_map: typeck::method_map, + moves_map: moves::MovesMap, + moved_variables_set: moves::MovedVariablesSet, + capture_map: moves::CaptureMap, + crate: &ast::Crate) + -> root_map { let mut bccx = BorrowckCtxt { tcx: tcx, method_map: method_map, @@ -82,7 +81,6 @@ pub fn check_crate( moved_variables_set: moved_variables_set, capture_map: capture_map, root_map: root_map(), - write_guard_map: @RefCell::new(HashSet::new()), stats: @BorrowStats { loaned_paths_same: Cell::new(0), loaned_paths_imm: Cell::new(0), @@ -106,7 +104,7 @@ pub fn check_crate( make_stat(bccx, bccx.stats.stable_paths.get())); } - return (bccx.root_map, bccx.write_guard_map); + return bccx.root_map; fn make_stat(bccx: &mut BorrowckCtxt, stat: uint) -> ~str { let stat_f = stat as f64; @@ -171,7 +169,6 @@ pub struct BorrowckCtxt { moved_variables_set: moves::MovedVariablesSet, capture_map: moves::CaptureMap, root_map: root_map, - write_guard_map: write_guard_map, // Statistics: stats: @BorrowStats @@ -213,10 +210,6 @@ pub struct root_map_key { derefs: uint } -// A set containing IDs of expressions of gc'd type that need to have a write -// guard. -pub type write_guard_map = @RefCell>; - pub type BckResult = Result; #[deriving(Eq)] @@ -402,7 +395,6 @@ impl BitAnd for RestrictionSet { pub struct RootInfo { scope: ast::NodeId, - freeze: Option // Some() if we should freeze box at runtime } pub type root_map = @RefCell>; @@ -411,20 +403,6 @@ pub fn root_map() -> root_map { return @RefCell::new(HashMap::new()); } -pub enum DynaFreezeKind { - DynaImm, - DynaMut -} - -impl ToStr for DynaFreezeKind { - fn to_str(&self) -> ~str { - match *self { - DynaMut => ~"mutable", - DynaImm => ~"immutable" - } - } -} - /////////////////////////////////////////////////////////////////////////// // Errors @@ -691,20 +669,9 @@ impl BorrowckCtxt { span, format!("{} in an aliasable location", prefix)); } - mc::AliasableManaged(ast::MutMutable) => { - // FIXME(#6269) reborrow @mut to &mut - self.tcx.sess.span_err( - span, - format!("{} in a `@mut` pointer; \ - try borrowing as `&mut` first", prefix)); - } - mc::AliasableManaged(m) => { - self.tcx.sess.span_err( - span, - format!("{} in a `@{}` pointer; \ - try an `@mut` instead", - prefix, - self.mut_to_keyword(m))); + mc::AliasableManaged => { + self.tcx.sess.span_err(span, format!("{} in a `@` pointer", + prefix)) } mc::AliasableBorrowed(m) => { self.tcx.sess.span_err( diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index b9b0b807e6ed..e7dddd18aeef 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -20,7 +20,7 @@ use syntax::visit::Visitor; use syntax::ast::*; use std::cell::RefCell; -use std::hashmap::{HashMap, HashSet}; +use std::hashmap::HashMap; // // This pass classifies expressions by their constant-ness. @@ -132,7 +132,6 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt, root_map: @RefCell::new(HashMap::new()), method_map: @RefCell::new(HashMap::new()), vtable_map: @RefCell::new(HashMap::new()), - write_guard_map: @RefCell::new(HashSet::new()), capture_map: @RefCell::new(HashMap::new()) }; let e = match csearch::maybe_get_item_ast(tcx, enum_def, @@ -186,7 +185,6 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::DefId) root_map: @RefCell::new(HashMap::new()), method_map: @RefCell::new(HashMap::new()), vtable_map: @RefCell::new(HashMap::new()), - write_guard_map: @RefCell::new(HashSet::new()), capture_map: @RefCell::new(HashMap::new()) }; let e = match csearch::maybe_get_item_ast(tcx, def_id, diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 87ae74321a17..8e86fa4611f2 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -207,7 +207,7 @@ pub fn collect_language_items(crate: &ast::Crate, } lets_do_this! { - There are 43 lang items. + There are 37 lang items. // ID, Variant name, Name, Method name; 0, FreezeTraitLangItem, "freeze", freeze_trait; @@ -243,24 +243,18 @@ lets_do_this! { 26, ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn; 27, MallocFnLangItem, "malloc", malloc_fn; 28, FreeFnLangItem, "free", free_fn; - 29, BorrowAsImmFnLangItem, "borrow_as_imm", borrow_as_imm_fn; - 30, BorrowAsMutFnLangItem, "borrow_as_mut", borrow_as_mut_fn; - 31, ReturnToMutFnLangItem, "return_to_mut", return_to_mut_fn; - 32, CheckNotBorrowedFnLangItem, "check_not_borrowed", check_not_borrowed_fn; - 33, StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn; - 34, RecordBorrowFnLangItem, "record_borrow", record_borrow_fn; - 35, UnrecordBorrowFnLangItem, "unrecord_borrow", unrecord_borrow_fn; + 29, StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn; - 36, StartFnLangItem, "start", start_fn; + 30, StartFnLangItem, "start", start_fn; - 37, TyDescStructLangItem, "ty_desc", ty_desc; - 38, TyVisitorTraitLangItem, "ty_visitor", ty_visitor; - 39, OpaqueStructLangItem, "opaque", opaque; + 31, TyDescStructLangItem, "ty_desc", ty_desc; + 32, TyVisitorTraitLangItem, "ty_visitor", ty_visitor; + 33, OpaqueStructLangItem, "opaque", opaque; - 40, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory; + 34, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory; - 41, TypeIdLangItem, "type_id", type_id; + 35, TypeIdLangItem, "type_id", type_id; - 42, EhPersonalityLangItem, "eh_personality", eh_personality_fn; + 36, EhPersonalityLangItem, "eh_personality", eh_personality_fn; } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 2349b5f4dd3f..8459581dba49 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -85,7 +85,7 @@ pub struct CopiedUpvar { #[deriving(Eq, IterBytes)] pub enum PointerKind { uniq_ptr, - gc_ptr(ast::Mutability), + gc_ptr, region_ptr(ast::Mutability, ty::Region), unsafe_ptr(ast::Mutability) } @@ -178,17 +178,11 @@ pub fn opt_deref_kind(t: ty::t) -> Option { Some(deref_ptr(region_ptr(ast::MutImmutable, r))) } - ty::ty_box(ref mt) | - ty::ty_evec(ref mt, ty::vstore_box) => { - Some(deref_ptr(gc_ptr(mt.mutbl))) - } - - ty::ty_trait(_, _, ty::BoxTraitStore, m, _) => { - Some(deref_ptr(gc_ptr(m))) - } - + ty::ty_box(_) | + ty::ty_evec(_, ty::vstore_box) | + ty::ty_trait(_, _, ty::BoxTraitStore, _, _) | ty::ty_estr(ty::vstore_box) => { - Some(deref_ptr(gc_ptr(ast::MutImmutable))) + Some(deref_ptr(gc_ptr)) } ty::ty_ptr(ref mt) => { @@ -681,7 +675,10 @@ impl mem_categorization_ctxt { uniq_ptr => { base_cmt.mutbl.inherit() } - gc_ptr(m) | region_ptr(m, _) | unsafe_ptr(m) => { + gc_ptr => { + McImmutable + } + region_ptr(m, _) | unsafe_ptr(m) => { MutabilityCategory::from_mutbl(m) } }; @@ -759,12 +756,15 @@ impl mem_categorization_ctxt { // for unique ptrs, we inherit mutability from the // owning reference. let m = match ptr { - uniq_ptr => { - base_cmt.mutbl.inherit() - } - gc_ptr(m) | region_ptr(m, _) | unsafe_ptr(m) => { - MutabilityCategory::from_mutbl(m) - } + uniq_ptr => { + base_cmt.mutbl.inherit() + } + gc_ptr => { + McImmutable + } + region_ptr(m, _) | unsafe_ptr(m) => { + MutabilityCategory::from_mutbl(m) + } }; // the deref is explicit in the resulting cmt @@ -1103,7 +1103,7 @@ pub fn field_mutbl(tcx: ty::ctxt, } pub enum AliasableReason { - AliasableManaged(ast::Mutability), + AliasableManaged, AliasableBorrowed(ast::Mutability), AliasableOther } @@ -1122,7 +1122,7 @@ impl cmt_ { cat_self(..) | cat_arg(..) | cat_deref(_, _, unsafe_ptr(..)) | - cat_deref(_, _, gc_ptr(..)) | + cat_deref(_, _, gc_ptr) | cat_deref(_, _, region_ptr(..)) => { self } @@ -1166,8 +1166,8 @@ impl cmt_ { Some(AliasableOther) } - cat_deref(_, _, gc_ptr(m)) => { - Some(AliasableManaged(m)) + cat_deref(_, _, gc_ptr) => { + Some(AliasableManaged) } cat_deref(_, _, region_ptr(m @ MutImmutable, _)) => { @@ -1229,7 +1229,7 @@ impl Repr for categorization { pub fn ptr_sigil(ptr: PointerKind) -> ~str { match ptr { uniq_ptr => ~"~", - gc_ptr(_) => ~"@", + gc_ptr => ~"@", region_ptr(_, _) => ~"&", unsafe_ptr(_) => ~"*" } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 0fadcbe53be0..973d2003ecb9 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -22,12 +22,10 @@ use middle::trans::base; use middle::trans::build; use middle::trans::datum; use middle::trans::glue; -use middle::trans::write_guard; use middle::trans::debuginfo; use middle::ty::substs; use middle::ty; use middle::typeck; -use middle::borrowck::root_map_key; use util::ppaux::Repr; use middle::trans::type_::Type; @@ -363,27 +361,6 @@ impl CleanupFunction for ImmediateTypeDroppingCleanupFunction { } } -/// A cleanup function that releases a write guard, returning a value to -/// mutable status. -pub struct WriteGuardReleasingCleanupFunction { - root_key: root_map_key, - frozen_val_ref: ValueRef, - bits_val_ref: ValueRef, - filename_val: ValueRef, - line_val: ValueRef, -} - -impl CleanupFunction for WriteGuardReleasingCleanupFunction { - fn clean(&self, bcx: @Block) -> @Block { - write_guard::return_to_mut(bcx, - self.root_key, - self.frozen_val_ref, - self.bits_val_ref, - self.filename_val, - self.line_val) - } -} - /// A cleanup function that frees some memory in the garbage-collected heap. pub struct GCHeapFreeingCleanupFunction { ptr: ValueRef, @@ -527,42 +504,7 @@ pub fn add_clean_temp_mem_in_scope_(bcx: @Block, scope_id: Option, grow_scope_clean(scope_info); }) } -pub fn add_clean_return_to_mut(bcx: @Block, - scope_id: ast::NodeId, - root_key: root_map_key, - frozen_val_ref: ValueRef, - bits_val_ref: ValueRef, - filename_val: ValueRef, - line_val: ValueRef) { - //! When an `@mut` has been frozen, we have to - //! call the lang-item `return_to_mut` when the - //! freeze goes out of scope. We need to pass - //! in both the value which was frozen (`frozen_val`) and - //! the value (`bits_val_ref`) which was returned when the - //! box was frozen initially. Here, both `frozen_val_ref` and - //! `bits_val_ref` are in fact pointers to stack slots. - debug!("add_clean_return_to_mut({}, {}, {})", - bcx.to_str(), - bcx.val_to_str(frozen_val_ref), - bcx.val_to_str(bits_val_ref)); - in_scope_cx(bcx, Some(scope_id), |scope_info| { - { - let mut cleanups = scope_info.cleanups.borrow_mut(); - cleanups.get().push(clean_temp( - frozen_val_ref, - @WriteGuardReleasingCleanupFunction { - root_key: root_key, - frozen_val_ref: frozen_val_ref, - bits_val_ref: bits_val_ref, - filename_val: filename_val, - line_val: line_val, - } as @CleanupFunction, - normal_exit_only)); - } - grow_scope_clean(scope_info); - }) -} pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) { let free_fn = match heap { heap_managed | heap_managed_unique => { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 6b8ff815a836..f57f31a56f45 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -552,7 +552,7 @@ impl Datum { * by-ref datum of type T, pointing at the contents. */ let (content_ty, header) = match ty::get(self.ty).sty { - ty::ty_box(mt) => (mt.ty, true), + ty::ty_box(typ) => (typ, true), ty::ty_uniq(mt) => (mt.ty, false), ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { let unit_ty = ty::sequence_element_type(bcx.tcx(), self.ty); diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 3170a290a41f..49577a139539 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -2142,8 +2142,8 @@ fn type_metadata(cx: &CrateContext, ty::ty_enum(def_id, _) => { prepare_enum_metadata(cx, t, def_id, usage_site_span).finalize(cx) }, - ty::ty_box(ref mt) => { - create_pointer_to_box_metadata(cx, t, mt.ty) + ty::ty_box(typ) => { + create_pointer_to_box_metadata(cx, t, typ) }, ty::ty_evec(ref mt, ref vstore) => { match *vstore { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 9fcd0f458b3b..6cece563a825 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -378,18 +378,12 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { let source_data = Load(bcx, source_data_ptr); // always a ptr let target_data = match source_store { ty::BoxTraitStore(..) => { - // For deref of @T or @mut T, create a dummy datum and - // use the datum's deref method. This is more work - // than just calling GEPi ourselves, but it ensures - // that any write guards will be appropriate - // processed. Note that we don't know the type T, so + // For deref of @T, create a dummy datum and use the datum's + // deref method. This is more work than just calling GEPi + // ourselves. Note that we don't know the type T, so // just substitute `i8`-- it doesn't really matter for // our purposes right now. - let source_ty = - ty::mk_box(tcx, - ty::mt { - ty: ty::mk_i8(), - mutbl: source_mutbl}); + let source_ty = ty::mk_box(tcx, ty::mk_i8()); let source_datum = Datum {val: source_data, ty: source_ty, diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index cff0f5b316c3..85efd2d40d04 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -157,7 +157,10 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { if (field == abi::tydesc_field_free_glue || field == abi::tydesc_field_drop_glue) { match ty::get(t).sty { - ty::ty_box(mt) | + ty::ty_box(typ) + if ! ty::type_needs_drop(tcx, typ) => + return ty::mk_imm_box(tcx, ty::mk_u32()), + ty::ty_evec(mt, ty::vstore_box) if ! ty::type_needs_drop(tcx, mt.ty) => return ty::mk_imm_box(tcx, ty::mk_u32()), @@ -356,10 +359,10 @@ pub fn make_free_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { // NB: v0 is an *alias* of type t here, not a direct value. let _icx = push_ctxt("make_free_glue"); match ty::get(t).sty { - ty::ty_box(body_mt) => { + ty::ty_box(body_ty) => { let v = Load(bcx, v); let body = GEPi(bcx, v, [0u, abi::box_field_body]); - let bcx = drop_ty(bcx, body, body_mt.ty); + let bcx = drop_ty(bcx, body, body_ty); trans_free(bcx, v) } ty::ty_opaque_box => { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index c30f421c9e54..f0ec7fb75dd8 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -189,8 +189,11 @@ impl Reflector { self.visit(~"evec_" + name, extra) } } - ty::ty_box(ref mt) => { - let extra = self.c_mt(mt); + ty::ty_box(typ) => { + let extra = self.c_mt(&ty::mt { + ty: typ, + mutbl: ast::MutImmutable, + }); self.visit("box", extra) } ty::ty_uniq(ref mt) => { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index c1e6e4667618..e5f946213f32 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -236,8 +236,8 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty); Type::smart_ptr(cx, &v_ty).ptr_to() } - ty::ty_box(ref mt) => { - let ty = type_of(cx, mt.ty); + ty::ty_box(typ) => { + let ty = type_of(cx, typ); Type::smart_ptr(cx, &ty).ptr_to() } ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(), diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 3b60dc3dd378..d7c952a38f68 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -15,26 +15,15 @@ //! `RUST_LOG=rustc::middle::trans::write_guard`). -use lib::llvm::ValueRef; -use middle::borrowck::{RootInfo, root_map_key, DynaImm, DynaMut}; -use middle::lang_items::CheckNotBorrowedFnLangItem; -use middle::lang_items::{BorrowAsImmFnLangItem, BorrowAsMutFnLangItem}; -use middle::lang_items::{RecordBorrowFnLangItem, UnrecordBorrowFnLangItem}; -use middle::lang_items::ReturnToMutFnLangItem; +use middle::borrowck::{RootInfo, root_map_key}; use middle::trans::base::*; -use middle::trans::build::*; -use middle::trans::callee; use middle::trans::common::*; use middle::trans::datum::*; -use middle::trans::expr; -use middle::ty; use syntax::codemap::Span; use syntax::ast; -use middle::trans::type_::Type; - pub fn root_and_write_guard(datum: &Datum, - mut bcx: @Block, + bcx: @Block, span: Span, expr_id: ast::NodeId, derefs: uint) -> @Block { @@ -45,69 +34,16 @@ pub fn root_and_write_guard(datum: &Datum, // // (Note: root'd values are always boxes) let ccx = bcx.ccx(); - bcx = { - let root_map = ccx.maps.root_map.borrow(); - match root_map.get().find(&key) { - None => bcx, - Some(&root_info) => root(datum, bcx, span, key, root_info) - } - }; - - // Perform the write guard, if necessary. - // - // (Note: write-guarded values are always boxes) - let write_guard_map = ccx.maps.write_guard_map.borrow(); - if write_guard_map.get().contains(&key) { - perform_write_guard(datum, bcx, span) - } else { - bcx + let root_map = ccx.maps.root_map.borrow(); + match root_map.get().find(&key) { + None => bcx, + Some(&root_info) => root(datum, bcx, span, key, root_info) } } -pub fn return_to_mut(mut bcx: @Block, - root_key: root_map_key, - frozen_val_ref: ValueRef, - bits_val_ref: ValueRef, - filename_val: ValueRef, - line_val: ValueRef) -> @Block { - debug!("write_guard::return_to_mut(root_key={:?}, {}, {}, {})", - root_key, - bcx.to_str(), - bcx.val_to_str(frozen_val_ref), - bcx.val_to_str(bits_val_ref)); - - let box_ptr = Load(bcx, PointerCast(bcx, frozen_val_ref, Type::i8p().ptr_to())); - - let bits_val = Load(bcx, bits_val_ref); - - if bcx.tcx().sess.debug_borrows() { - bcx = callee::trans_lang_call( bcx, - langcall(bcx, None, "unborrow", UnrecordBorrowFnLangItem), - [ - box_ptr, - bits_val, - filename_val, - line_val - ], - Some(expr::Ignore)).bcx; - } - - callee::trans_lang_call( - bcx, - langcall(bcx, None, "unborrow", ReturnToMutFnLangItem), - [ - box_ptr, - bits_val, - filename_val, - line_val - ], - Some(expr::Ignore) - ).bcx -} - fn root(datum: &Datum, - mut bcx: @Block, - span: Span, + bcx: @Block, + _: Span, root_key: root_map_key, root_info: RootInfo) -> @Block { //! In some cases, borrowck will decide that an @T/@[]/@str @@ -129,73 +65,6 @@ fn root(datum: &Datum, scratch.val, scratch.ty); - // Now, consider also freezing it. - match root_info.freeze { - None => {} - Some(freeze_kind) => { - let (filename, line) = filename_and_line_num_from_span(bcx, span); - - // in this case, we don't have to zero, because - // scratch.val will be NULL should the cleanup get - // called without the freezing actually occurring, and - // return_to_mut checks for this condition. - let scratch_bits = scratch_datum(bcx, ty::mk_uint(), - "__write_guard_bits", false); - - let freeze_item = match freeze_kind { - DynaImm => BorrowAsImmFnLangItem, - DynaMut => BorrowAsMutFnLangItem, - }; - - let box_ptr = Load(bcx, PointerCast(bcx, scratch.val, Type::i8p().ptr_to())); - - let llresult = unpack_result!(bcx, callee::trans_lang_call( - bcx, - langcall(bcx, Some(span), "freeze", freeze_item), - [ - box_ptr, - filename, - line - ], - Some(expr::SaveIn(scratch_bits.val)))); - - if bcx.tcx().sess.debug_borrows() { - bcx = callee::trans_lang_call( - bcx, - langcall(bcx, Some(span), "freeze", RecordBorrowFnLangItem), - [ - box_ptr, - llresult, - filename, - line - ], - Some(expr::Ignore)).bcx; - } - - add_clean_return_to_mut(cleanup_bcx, - root_info.scope, - root_key, - scratch.val, - scratch_bits.val, - filename, - line); - } - } - bcx } -fn perform_write_guard(datum: &Datum, - bcx: @Block, - span: Span) -> @Block { - debug!("perform_write_guard"); - - let llval = datum.to_value_llval(bcx); - let (filename, line) = filename_and_line_num_from_span(bcx, span); - - callee::trans_lang_call( - bcx, - langcall(bcx, Some(span), "write guard", CheckNotBorrowedFnLangItem), - [PointerCast(bcx, llval, Type::i8p()), filename, line], - Some(expr::Ignore)).bcx -} diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 7abc2a34a1f7..79eb26091dcb 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -637,7 +637,7 @@ pub enum sty { ty_float(ast::float_ty), ty_estr(vstore), ty_enum(DefId, substs), - ty_box(mt), + ty_box(t), ty_uniq(mt), ty_evec(mt, vstore), ty_ptr(mt), @@ -1102,8 +1102,9 @@ pub fn mk_t(cx: ctxt, st: sty) -> t { _ => {} } } - &ty_box(ref m) | &ty_uniq(ref m) | &ty_evec(ref m, _) | - &ty_ptr(ref m) | &ty_unboxed_vec(ref m) => { + &ty_box(ref tt) => flags |= get(*tt).flags, + &ty_uniq(ref m) | &ty_evec(ref m, _) | &ty_ptr(ref m) | + &ty_unboxed_vec(ref m) => { flags |= get(m.ty).flags; } &ty_rptr(r, ref m) => { @@ -1242,10 +1243,10 @@ pub fn mk_enum(cx: ctxt, did: ast::DefId, substs: substs) -> t { mk_t(cx, ty_enum(did, substs)) } -pub fn mk_box(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_box(tm)) } +pub fn mk_box(cx: ctxt, ty: t) -> t { mk_t(cx, ty_box(ty)) } pub fn mk_imm_box(cx: ctxt, ty: t) -> t { - mk_box(cx, mt {ty: ty, mutbl: ast::MutImmutable}) + mk_box(cx, ty) } pub fn mk_uniq(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_uniq(tm)) } @@ -1368,8 +1369,11 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) { ty_estr(_) | ty_type | ty_opaque_box | ty_self(_) | ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => { } - ty_box(ref tm) | ty_evec(ref tm, _) | ty_unboxed_vec(ref tm) | - ty_ptr(ref tm) | ty_rptr(_, ref tm) | ty_uniq(ref tm) => { + ty_box(ref ty) => { + maybe_walk_ty(*ty, f); + } + ty_evec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) | + ty_rptr(_, ref tm) | ty_uniq(ref tm) => { maybe_walk_ty(tm.ty, f); } ty_enum(_, ref substs) | ty_struct(_, ref substs) | @@ -2035,8 +2039,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { closure_contents(cx, c) } - ty_box(mt) => { - tc_mt(cx, mt, cache).managed_pointer() + ty_box(typ) => { + tc_ty(cx, typ, cache).managed_pointer() } ty_trait(_, _, store, mutbl, bounds) => { @@ -2334,7 +2338,9 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ty_unboxed_vec(_) => { false } - ty_box(ref mt) | + ty_box(typ) => { + type_requires(cx, seen, r_ty, typ) + } ty_uniq(ref mt) | ty_rptr(_, ref mt) => { type_requires(cx, seen, r_ty, mt.ty) @@ -2610,7 +2616,14 @@ pub fn deref(cx: ctxt, t: t, explicit: bool) -> Option { pub fn deref_sty(cx: ctxt, sty: &sty, explicit: bool) -> Option { match *sty { - ty_rptr(_, mt) | ty_box(mt) | ty_uniq(mt) => { + ty_box(typ) => { + Some(mt { + ty: typ, + mutbl: ast::MutImmutable, + }) + } + + ty_rptr(_, mt) | ty_uniq(mt) => { Some(mt) } @@ -4818,9 +4831,8 @@ pub fn hash_crate_independent(tcx: ctxt, t: t, local_hash: @str) -> u64 { hash.input([8]); did(&mut hash, d); } - ty_box(m) => { + ty_box(_) => { hash.input([9]); - mt(&mut hash, m); } ty_uniq(m) => { hash.input([10]); diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 2d39352ebc4f..06a3152056fb 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -140,8 +140,8 @@ pub fn super_fold_mt(this: &mut T, pub fn super_fold_sty(this: &mut T, sty: &ty::sty) -> ty::sty { match *sty { - ty::ty_box(ref tm) => { - ty::ty_box(this.fold_mt(tm)) + ty::ty_box(typ) => { + ty::ty_box(this.fold_ty(typ)) } ty::ty_uniq(ref tm) => { ty::ty_uniq(this.fold_mt(tm)) diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 0da9db5d5c2e..24c4b3399bcc 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -402,8 +402,9 @@ pub fn ast_ty_to_ty( ast::ty_nil => ty::mk_nil(), ast::ty_bot => ty::mk_bot(), ast::ty_box(ref mt) => { - mk_pointer(this, rscope, mt, ty::vstore_box, - |tmt| ty::mk_box(tcx, tmt)) + let mt = ast::mt { ty: mt.ty, mutbl: ast::MutImmutable }; + mk_pointer(this, rscope, &mt, ty::vstore_box, + |tmt| ty::mk_box(tcx, tmt.ty)) } ast::ty_uniq(ty) => { let mt = ast::mt { ty: ty, mutbl: ast::MutImmutable }; @@ -689,10 +690,8 @@ fn ty_of_method_or_bare_fn( ty::mt {ty: self_info.untransformed_self_ty, mutbl: mutability})) } - ast::sty_box(mutability) => { - Some(ty::mk_box(this.tcx(), - ty::mt {ty: self_info.untransformed_self_ty, - mutbl: mutability})) + ast::sty_box(_) => { + Some(ty::mk_box(this.tcx(), self_info.untransformed_self_ty)) } ast::sty_uniq(_) => { Some(ty::mk_uniq(this.tcx(), diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 739437d278d9..a7f83a41da67 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -667,8 +667,8 @@ pub fn check_pointer_pat(pcx: &pat_ctxt, span: Span, expected: ty::t) { let fcx = pcx.fcx; - let check_inner: |ty::mt| = |e_inner| { - check_pat(pcx, inner, e_inner.ty); + let check_inner: |ty::t| = |e_inner| { + check_pat(pcx, inner, e_inner); fcx.write_ty(pat_id, expected); }; match *structure_of(fcx, span, expected) { @@ -676,10 +676,10 @@ pub fn check_pointer_pat(pcx: &pat_ctxt, check_inner(e_inner); } ty::ty_uniq(e_inner) if pointer_kind == Send => { - check_inner(e_inner); + check_inner(e_inner.ty); } ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => { - check_inner(e_inner); + check_inner(e_inner.ty); } _ => { check_pat(pcx, inner, ty::mk_err()); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 6e2afb1d2e7f..e1ecd919da81 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -1092,9 +1092,9 @@ impl<'a> LookupContext<'a> { substs, RegionTraitStore(r), mt.mutbl, ty::EmptyBuiltinBounds()) } - ty::ty_box(mt) => { // must be sty_box + ty::ty_box(_) => { // must be sty_box ty::mk_trait(self.tcx(), trait_def_id, - substs, BoxTraitStore, mt.mutbl, + substs, BoxTraitStore, ast::MutImmutable, ty::EmptyBuiltinBounds()) } ty::ty_uniq(mt) => { // must be sty_uniq @@ -1224,9 +1224,8 @@ impl<'a> LookupContext<'a> { sty_box(m) => { debug!("(is relevant?) explicit self is a box"); match ty::get(rcvr_ty).sty { - ty::ty_box(mt) => { - mutability_matches(mt.mutbl, m) && - rcvr_matches_ty(self.fcx, mt.ty, candidate) + ty::ty_box(typ) => { + rcvr_matches_ty(self.fcx, typ, candidate) } ty::ty_trait(self_did, _, BoxTraitStore, self_m, _) => { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 9bdcd191360b..dde55f320bc2 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1330,8 +1330,7 @@ pub fn do_autoderef(fcx: @FnCtxt, sp: Span, t: ty::t) -> (ty::t, uint) { // Some extra checks to detect weird cycles and so forth: match *sty { - ty::ty_box(inner) | ty::ty_uniq(inner) | - ty::ty_rptr(_, inner) => { + ty::ty_box(inner) => { match ty::get(t1).sty { ty::ty_infer(ty::TyVar(v1)) => { ty::occurs_check(fcx.ccx.tcx, sp, v1, @@ -1340,6 +1339,15 @@ pub fn do_autoderef(fcx: @FnCtxt, sp: Span, t: ty::t) -> (ty::t, uint) { _ => () } } + ty::ty_uniq(inner) | ty::ty_rptr(_, inner) => { + match ty::get(t1).sty { + ty::ty_infer(ty::TyVar(v1)) => { + ty::occurs_check(fcx.ccx.tcx, sp, v1, + ty::mk_box(fcx.ccx.tcx, inner.ty)); + } + _ => () + } + } ty::ty_enum(ref did, _) => { // Watch out for a type like `enum t = @t`. Such a // type would otherwise infinitely auto-deref. Only @@ -2734,7 +2742,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, let exp_inner = unpack_expected(fcx, expected, |sty| { match unop { ast::UnBox(_) | ast::UnUniq => match *sty { - ty::ty_box(ref mt) | ty::ty_uniq(ref mt) => Some(mt.ty), + ty::ty_box(ty) => Some(ty), + ty::ty_uniq(ref mt) => Some(mt.ty), _ => None }, ast::UnNot | ast::UnNeg => expected, @@ -2746,9 +2755,8 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt, if !ty::type_is_error(oprnd_t) && !ty::type_is_bot(oprnd_t) { match unop { - ast::UnBox(mutbl) => { - oprnd_t = ty::mk_box(tcx, - ty::mt {ty: oprnd_t, mutbl: mutbl}); + ast::UnBox(_) => { + oprnd_t = ty::mk_box(tcx, oprnd_t) } ast::UnUniq => { oprnd_t = ty::mk_uniq(tcx, diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 35501e5d5ebf..fcf219323e1c 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -582,7 +582,13 @@ pub fn early_resolve_expr(ex: @ast::Expr, let ty = structurally_resolved_type(fcx, ex.span, fcx.expr_ty(src)); match (&ty::get(ty).sty, store) { - (&ty::ty_box(mt), ty::BoxTraitStore) | + (&ty::ty_box(..), ty::BoxTraitStore) + if !mutability_allowed(ast::MutImmutable, + target_mutbl) => { + fcx.tcx().sess.span_err(ex.span, + format!("types differ in mutability")); + } + (&ty::ty_uniq(mt), ty::UniqTraitStore) | (&ty::ty_rptr(_, mt), ty::RegionTraitStore(..)) if !mutability_allowed(mt.mutbl, target_mutbl) => { @@ -590,9 +596,15 @@ pub fn early_resolve_expr(ex: @ast::Expr, format!("types differ in mutability")); } - (&ty::ty_box(mt), ty::BoxTraitStore) | - (&ty::ty_uniq(mt), ty::UniqTraitStore) | - (&ty::ty_rptr(_, mt), ty::RegionTraitStore(..)) => { + (&ty::ty_box(..), ty::BoxTraitStore) | + (&ty::ty_uniq(..), ty::UniqTraitStore) | + (&ty::ty_rptr(..), ty::RegionTraitStore(..)) => { + let typ = match (&ty::get(ty).sty) { + &ty::ty_box(typ) => typ, + &ty::ty_uniq(mt) | &ty::ty_rptr(_, mt) => mt.ty, + _ => fail!("shouldn't get here"), + }; + let location_info = &location_info_for_expr(ex); let vcx = fcx.vtable_context(); @@ -601,7 +613,7 @@ pub fn early_resolve_expr(ex: @ast::Expr, substs: ty::substs { tps: target_substs.tps.clone(), regions: target_substs.regions.clone(), - self_ty: Some(mt.ty) + self_ty: Some(typ) } }; @@ -614,7 +626,7 @@ pub fn early_resolve_expr(ex: @ast::Expr, location_info, None, ¶m_bounds, - mt.ty, + typ, is_early); if !is_early { diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 0d4c3ef52d3d..6e82456e95db 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -241,7 +241,7 @@ impl Coerce { let r_borrow = self.infcx.next_region_var(Coercion(self.trace)); let inner_ty = match *sty_a { - ty::ty_box(mt_a) => mt_a.ty, + ty::ty_box(typ) => typ, ty::ty_uniq(mt_a) => mt_a.ty, ty::ty_rptr(_, mt_a) => mt_a.ty, _ => { diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index c35852d37c97..8d949cc1bc90 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -515,8 +515,8 @@ pub fn super_tys(this: &C, a: ty::t, b: ty::t) -> cres { Ok(ty::mk_struct(tcx, a_id, substs)) } - (&ty::ty_box(ref a_mt), &ty::ty_box(ref b_mt)) => { - this.mts(a_mt, b_mt).and_then(|mt| Ok(ty::mk_box(tcx, mt))) + (&ty::ty_box(a_inner), &ty::ty_box(b_inner)) => { + this.tys(a_inner, b_inner).and_then(|typ| Ok(ty::mk_box(tcx, typ))) } (&ty::ty_uniq(ref a_mt), &ty::ty_uniq(ref b_mt)) => { diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index 3ae43d606617..7be5791c0740 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -637,7 +637,10 @@ impl<'a> ConstraintContext<'a> { self.add_constraints_from_mt(mt, variance); } - ty::ty_box(ref mt) | + ty::ty_box(typ) => { + self.add_constraints_from_ty(typ, variance); + } + ty::ty_uniq(ref mt) | ty::ty_ptr(ref mt) => { self.add_constraints_from_mt(mt, variance); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index ee77685cf5a1..6a346eac425b 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -454,7 +454,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { ty_uint(ast::ty_u) => ~"uint", ty_uint(t) => ast_util::uint_ty_to_str(t), ty_float(t) => ast_util::float_ty_to_str(t), - ty_box(ref tm) => ~"@" + mt_to_str(cx, tm), + ty_box(typ) => ~"@" + ty_to_str(cx, typ), ty_uniq(ref tm) => ~"~" + mt_to_str(cx, tm), ty_ptr(ref tm) => ~"*" + mt_to_str(cx, tm), ty_rptr(r, ref tm) => { diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index fd34091cc51f..8a5a1d2426cb 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -95,7 +95,7 @@ pub fn path_elt_to_str(pe: path_elt, itr: @ident_interner) -> ~str { fn pretty_ty(ty: &Ty, itr: @ident_interner, out: &mut ~str) { let (prefix, subty) = match ty.node { ty_uniq(ty) => ("$UP$", &*ty), - ty_box(mt { ty, .. }) => ("$SP$", &*ty), + ty_box(ty) => ("$SP$", &*ty), ty_ptr(mt { ty, mutbl }) => (if mutbl == MutMutable {"$RPmut$"} else {"$RP$"}, &*ty), ty_rptr(_, mt { ty, mutbl }) => (if mutbl == MutMutable {"$BPmut$"} else {"$BP$"},