diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/mem.rs | 78 | ||||
| -rw-r--r-- | src/librustc/middle/region.rs | 4 | ||||
| -rw-r--r-- | src/librustc_mir/util/pretty.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 10 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/type-path-err-node-types.rs | 25 |
6 files changed, 106 insertions, 17 deletions
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index c869054cee8..e085d427b8c 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -209,6 +209,35 @@ pub fn forget<T>(t: T) { /// The mutability of a pointer does not change its size. As such, `&T` and `&mut T` /// have the same size. Likewise for `*const T` and `*mut T`. /// +/// # Size of `#[repr(C)]` items +/// +/// The `C` representation for items has a defined layout. With this layout, +/// the size of items is also stable as long as all fields have a stable size. +/// +/// ## Size of Structs +/// +/// For `structs`, the size is determined by the following algorithm. +/// +/// For each field in the struct ordered by declaration order: +/// +/// 1. Add the size of the field. +/// 2. Round up the current size to the nearest multiple of the next field's [alignment]. +/// +/// Finally, round the size of the struct to the nearest multiple of its [alignment]. +/// +/// Unlike `C`, zero sized structs are not rounded up to one byte in size. +/// +/// ## Size of Enums +/// +/// Enums that carry no data other than the descriminant have the same size as C enums +/// on the platform they are compiled for. +/// +/// ## Size of Unions +/// +/// The size of a union is the size of its largest field. +/// +/// Unlike `C`, zero sized unions are not rounded up to one byte in size. +/// /// # Examples /// /// ``` @@ -231,6 +260,55 @@ pub fn forget<T>(t: T) { /// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>()); /// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>()); /// ``` +/// +/// Using `#[repr(C)]`. +/// +/// ``` +/// use std::mem; +/// +/// #[repr(C)] +/// struct FieldStruct { +/// first: u8, +/// second: u16, +/// third: u8 +/// } +/// +/// // The size of the first field is 1, so add 1 to the size. Size is 1. +/// // The alignment of the second field is 2, so add 1 to the size for padding. Size is 2. +/// // The size of the second field is 2, so add 2 to the size. Size is 4. +/// // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4. +/// // The size of the third field is 1, so add 1 to the size. Size is 5. +/// // Finally, the alignment of the struct is 2, so add 1 to the size for padding. Size is 6. +/// assert_eq!(6, mem::size_of::<FieldStruct>()); +/// +/// #[repr(C)] +/// struct TupleStruct(u8, u16, u8); +/// +/// // Tuple structs follow the same rules. +/// assert_eq!(6, mem::size_of::<TupleStruct>()); +/// +/// // Note that reordering the fields can lower the size. We can remove both padding bytes +/// // by putting `third` before `second`. +/// #[repr(C)] +/// struct FieldStructOptimized { +/// first: u8, +/// third: u8, +/// second: u16 +/// } +/// +/// assert_eq!(4, mem::size_of::<FieldStructOptimized>()); +/// +/// // Union size is the size of the largest field. +/// #[repr(C)] +/// union ExampleUnion { +/// smaller: u8, +/// larger: u16 +/// } +/// +/// assert_eq!(2, mem::size_of::<ExampleUnion>()); +/// ``` +/// +/// [alignment]: ./fn.align_of.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_size_of"))] diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 59c9e8b4c43..b909ee9f93b 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -413,7 +413,7 @@ pub struct ScopeTree { /// The number of visit_expr and visit_pat calls done in the body. /// Used to sanity check visit_expr/visit_pat call count when - /// calculating geneartor interiors. + /// calculating generator interiors. body_expr_count: FxHashMap<hir::BodyId, usize>, } @@ -785,7 +785,7 @@ impl<'tcx> ScopeTree { /// Gives the number of expressions visited in a body. /// Used to sanity check visit_expr call count when - /// calculating geneartor interiors. + /// calculating generator interiors. pub fn body_expr_count(&self, body_id: hir::BodyId) -> Option<usize> { self.body_expr_count.get(&body_id).map(|r| *r) } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 0811783a9e5..9e1f05f6d2f 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -188,7 +188,9 @@ pub fn write_basic_block(tcx: TyCtxt, let data = &mir[block]; // Basic block label at the top. - writeln!(w, "{}{:?}: {{", INDENT, block)?; + let cleanup_text = if data.is_cleanup { " // cleanup" } else { "" }; + let lbl = format!("{}{:?}: {{", INDENT, block); + writeln!(w, "{0:1$}{2}", lbl, ALIGN, cleanup_text)?; // List of statements in the middle. let mut current_location = Location { block: block, statement_index: 0 }; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 54fd070e93c..22001d00896 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -988,16 +988,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } Def::Err => { - for segment in &path.segments { - segment.with_parameters(|parameters| { - for ty in ¶meters.types { - self.ast_ty_to_ty(ty); - } - for binding in ¶meters.bindings { - self.ast_ty_to_ty(&binding.ty); - } - }); - } self.set_tainted_by_errors(); return self.tcx().types.err; } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a0099a48c89..09294332a4f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2009,7 +2009,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { match self.tables.borrow().node_types().get(id) { Some(&t) => t, - None if self.err_count_since_creation() != 0 => self.tcx.types.err, + None if self.is_tainted_by_errors() => self.tcx.types.err, None => { let node_id = self.tcx.hir.definitions().find_node_for_hir_id(id); bug!("no type for node {}: {} in fcx {}", diff --git a/src/test/compile-fail/type-path-err-node-types.rs b/src/test/compile-fail/type-path-err-node-types.rs index 8f26777b441..7ef099d0410 100644 --- a/src/test/compile-fail/type-path-err-node-types.rs +++ b/src/test/compile-fail/type-path-err-node-types.rs @@ -8,10 +8,29 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Type arguments of unresolved types should have their types recorded +// Type arguments in unresolved entities (reporting errors before type checking) +// should have their types recorded. -fn main() { +trait Tr<T> {} + +fn local_type() { let _: Nonexistent<u8, Assoc = u16>; //~ ERROR cannot find type `Nonexistent` in this scope +} - let _ = |a, b: _| -> _ { 0 }; +fn ufcs_trait() { + <u8 as Tr<u8>>::nonexistent(); //~ ERROR cannot find method or associated constant `nonexistent` } + +fn ufcs_item() { + NonExistent::Assoc::<u8>; //~ ERROR undeclared type or module `NonExistent` +} + +fn method() { + nonexistent.nonexistent::<u8>(); //~ ERROR cannot find value `nonexistent` +} + +fn closure() { + let _ = |a, b: _| -> _ { 0 }; // OK +} + +fn main() {} |
