]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #49558 - Zoxc:sync-misc, r=michaelwoerister
authorbors <bors@rust-lang.org>
Thu, 12 Apr 2018 16:22:36 +0000 (16:22 +0000)
committerbors <bors@rust-lang.org>
Thu, 12 Apr 2018 16:22:36 +0000 (16:22 +0000)
Even more thread-safety changes

r? @michaelwoerister

1  2 
src/librustc/ty/context.rs
src/librustc/ty/layout.rs
src/librustc/ty/maps/plumbing.rs
src/librustc_metadata/encoder.rs
src/librustc_trans/base.rs
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/llvm_util.rs
src/librustc_trans_utils/lib.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/lib.rs

index 2713b2d11e0679e67ce3fd93cb8121862ddfe4b3,83d9aa6dd86ac23e7b6115f282247e132b856607..1e5d0753e6932f463ac0ee1c5b631d58f225768f
@@@ -50,7 -50,7 +50,7 @@@ use ty::maps
  use ty::steal::Steal;
  use ty::BindingMode;
  use ty::CanonicalTy;
- use util::nodemap::{NodeMap, DefIdSet, ItemLocalMap};
+ use util::nodemap::{DefIdSet, ItemLocalMap};
  use util::nodemap::{FxHashMap, FxHashSet};
  use rustc_data_structures::accumulate_vec::AccumulateVec;
  use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
@@@ -71,11 -71,11 +71,11 @@@ use std::iter
  use std::sync::mpsc;
  use std::sync::Arc;
  use syntax::abi;
 -use syntax::ast::{self, Name, NodeId};
 +use syntax::ast::{self, NodeId};
  use syntax::attr;
  use syntax::codemap::MultiSpan;
  use syntax::feature_gate;
 -use syntax::symbol::{Symbol, keywords};
 +use syntax::symbol::{Symbol, keywords, InternedString};
  use syntax_pos::Span;
  
  use hir;
@@@ -888,22 -888,12 +888,12 @@@ pub struct GlobalCtxt<'tcx> 
      /// Used to prevent layout from recursing too deeply.
      pub layout_depth: Cell<usize>,
  
-     /// Map from function to the `#[derive]` mode that it's defining. Only used
-     /// by `proc-macro` crates.
-     pub derive_macros: RefCell<NodeMap<Symbol>>,
      stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
  
      pub interpret_interner: InterpretInterner<'tcx>,
  
      layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
  
-     /// A vector of every trait accessible in the whole crate
-     /// (i.e. including those from subcrates). This is used only for
-     /// error reporting, and so is lazily initialized and generally
-     /// shouldn't taint the common path (hence the RefCell).
-     pub all_traits: RefCell<Option<Vec<DefId>>>,
      /// A general purpose channel to throw data out the back towards LLVM worker
      /// threads.
      ///
@@@ -1280,10 -1270,8 +1270,8 @@@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, '
              data_layout,
              layout_interner: Lock::new(FxHashSet()),
              layout_depth: Cell::new(0),
-             derive_macros: RefCell::new(NodeMap()),
              stability_interner: Lock::new(FxHashSet()),
              interpret_interner: Default::default(),
-             all_traits: RefCell::new(None),
              tx_to_llvm_workers: Lock::new(tx),
              output_filenames: Arc::new(output_filenames.clone()),
          };
@@@ -2430,12 -2418,12 +2418,12 @@@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, '
  
      pub fn mk_param(self,
                      index: u32,
 -                    name: Name) -> Ty<'tcx> {
 +                    name: InternedString) -> Ty<'tcx> {
          self.mk_ty(TyParam(ParamTy { idx: index, name: name }))
      }
  
      pub fn mk_self_type(self) -> Ty<'tcx> {
 -        self.mk_param(0, keywords::SelfType.name())
 +        self.mk_param(0, keywords::SelfType.name().as_str())
      }
  
      pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
index 5c522cbc31516dcba149643fe9f48e418d978560,91c616224071eac58910e3290e14c5a682214d73..35ada4a7227e7d1c16a7bd44fae4ced3dbbc3c67
@@@ -12,7 -12,7 +12,7 @@@ pub use self::Integer::*
  pub use self::Primitive::*;
  
  use session::{self, DataTypeKind, Session};
 -use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions, ReprFlags};
 +use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
  
  use syntax::ast::{self, FloatTy, IntTy, UintTy};
  use syntax::attr;
@@@ -344,8 -344,8 +344,8 @@@ impl AddAssign for Size 
  /// a maximum capacity of 2<sup>31</sup> - 1 or 2147483647.
  #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
  pub struct Align {
 -    abi: u8,
 -    pref: u8,
 +    abi_pow2: u8,
 +    pref_pow2: u8,
  }
  
  impl Align {
          };
  
          Ok(Align {
 -            abi: log2(abi)?,
 -            pref: log2(pref)?,
 +            abi_pow2: log2(abi)?,
 +            pref_pow2: log2(pref)?,
          })
      }
  
      pub fn abi(self) -> u64 {
 -        1 << self.abi
 +        1 << self.abi_pow2
      }
  
      pub fn pref(self) -> u64 {
 -        1 << self.pref
 +        1 << self.pref_pow2
      }
  
      pub fn abi_bits(self) -> u64 {
  
      pub fn min(self, other: Align) -> Align {
          Align {
 -            abi: cmp::min(self.abi, other.abi),
 -            pref: cmp::min(self.pref, other.pref),
 +            abi_pow2: cmp::min(self.abi_pow2, other.abi_pow2),
 +            pref_pow2: cmp::min(self.pref_pow2, other.pref_pow2),
          }
      }
  
      pub fn max(self, other: Align) -> Align {
          Align {
 -            abi: cmp::max(self.abi, other.abi),
 -            pref: cmp::max(self.pref, other.pref),
 +            abi_pow2: cmp::max(self.abi_pow2, other.abi_pow2),
 +            pref_pow2: cmp::max(self.pref_pow2, other.pref_pow2),
          }
      }
  }
@@@ -898,7 -898,7 +898,7 @@@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a
  {
      let (param_env, ty) = query.into_parts();
  
-     let rec_limit = tcx.sess.recursion_limit.get();
+     let rec_limit = *tcx.sess.recursion_limit.get();
      let depth = tcx.layout_depth.get();
      if depth > rec_limit {
          tcx.sess.fatal(
@@@ -974,11 -974,6 +974,11 @@@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a
                  bug!("struct cannot be packed and aligned");
              }
  
 +            let pack = {
 +                let pack = repr.pack as u64;
 +                Align::from_bytes(pack, pack).unwrap()
 +            };
 +
              let mut align = if packed {
                  dl.i8_align
              } else {
              let mut offsets = vec![Size::from_bytes(0); fields.len()];
              let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
  
 -            // Anything with repr(C) or repr(packed) doesn't optimize.
 -            let mut optimize = (repr.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty();
 +            let mut optimize = !repr.inhibit_struct_field_reordering_opt();
              if let StructKind::Prefixed(_, align) = kind {
                  optimize &= align.abi() == 1;
              }
                      fields.len()
                  };
                  let optimizing = &mut inverse_memory_index[..end];
 +                let field_align = |f: &TyLayout| {
 +                    if packed { f.align.min(pack).abi() } else { f.align.abi() }
 +                };
                  match kind {
                      StructKind::AlwaysSized |
                      StructKind::MaybeUnsized => {
                              // Place ZSTs first to avoid "interesting offsets",
                              // especially with only one or two non-ZST fields.
                              let f = &fields[x as usize];
 -                            (!f.is_zst(), cmp::Reverse(f.align.abi()))
 -                        })
 +                            (!f.is_zst(), cmp::Reverse(field_align(f)))
 +                        });
                      }
                      StructKind::Prefixed(..) => {
 -                        optimizing.sort_by_key(|&x| fields[x as usize].align.abi());
 +                        optimizing.sort_by_key(|&x| field_align(&fields[x as usize]));
                      }
                  }
              }
              let mut offset = Size::from_bytes(0);
  
              if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
 -                if !packed {
 +                if packed {
 +                    let prefix_align = prefix_align.min(pack);
 +                    align = align.max(prefix_align);
 +                } else {
                      align = align.max(prefix_align);
                  }
                  offset = prefix_size.abi_align(prefix_align);
                  }
  
                  // Invariant: offset < dl.obj_size_bound() <= 1<<61
 -                if !packed {
 +                if packed {
 +                    let field_pack = field.align.min(pack);
 +                    offset = offset.abi_align(field_pack);
 +                    align = align.max(field_pack);
 +                }
 +                else {
                      offset = offset.abi_align(field.align);
                      align = align.max(field.align);
                  }
                          bug!("Union cannot be packed and aligned");
                      }
  
 -                    let mut align = if def.repr.packed() {
 +                    let pack = {
 +                        let pack = def.repr.pack as u64;
 +                        Align::from_bytes(pack, pack).unwrap()
 +                    };
 +
 +                    let mut align = if packed {
                          dl.i8_align
                      } else {
                          dl.aggregate_align
                      for field in &variants[0] {
                          assert!(!field.is_unsized());
  
 -                        if !packed {
 +                        if packed {
 +                            let field_pack = field.align.min(pack);
 +                            align = align.max(field_pack);
 +                        } else {
                              align = align.max(field.align);
                          }
                          size = cmp::max(size, field.size);
  
                      // Find one non-ZST variant.
                      'variants: for (v, fields) in variants.iter().enumerate() {
 +                        if fields.iter().any(|f| f.abi == Abi::Uninhabited) {
 +                            continue 'variants;
 +                        }
                          for f in fields {
 -                            if f.abi == Abi::Uninhabited {
 -                                continue 'variants;
 -                            }
                              if !f.is_zst() {
                                  if dataful_variant.is_none() {
                                      dataful_variant = Some(v);
  
      fn record_layout_for_printing_outlined(self, layout: TyLayout<'tcx>) {
          // (delay format until we actually need it)
 -        let record = |kind, opt_discr_size, variants| {
 +        let record = |kind, packed, opt_discr_size, variants| {
              let type_desc = format!("{:?}", layout.ty);
              self.tcx.sess.code_stats.borrow_mut().record_type_size(kind,
                                                                     type_desc,
                                                                     layout.align,
                                                                     layout.size,
 +                                                                   packed,
                                                                     opt_discr_size,
                                                                     variants);
          };
  
              ty::TyClosure(..) => {
                  debug!("print-type-size t: `{:?}` record closure", layout.ty);
 -                record(DataTypeKind::Closure, None, vec![]);
 +                record(DataTypeKind::Closure, false, None, vec![]);
                  return;
              }
  
          };
  
          let adt_kind = adt_def.adt_kind();
 +        let adt_packed = adt_def.repr.packed();
  
          let build_variant_info = |n: Option<ast::Name>,
                                    flds: &[ast::Name],
                      let fields: Vec<_> =
                          variant_def.fields.iter().map(|f| f.name).collect();
                      record(adt_kind.into(),
 +                           adt_packed,
                             None,
                             vec![build_variant_info(Some(variant_def.name),
                                                     &fields,
                  } else {
                      // (This case arises for *empty* enums; so give it
                      // zero variants.)
 -                    record(adt_kind.into(), None, vec![]);
 +                    record(adt_kind.into(), adt_packed, None, vec![]);
                  }
              }
  
                                              layout.for_variant(self, i))
                      })
                      .collect();
 -                record(adt_kind.into(), match layout.variants {
 +                record(adt_kind.into(), adt_packed, match layout.variants {
                      Variants::Tagged { ref discr, .. } => Some(discr.value.size(self)),
                      _ => None
                  }, variant_infos);
@@@ -2544,8 -2518,8 +2544,8 @@@ impl_stable_hash_for!(enum ::ty::layout
  });
  
  impl_stable_hash_for!(struct ::ty::layout::Align {
 -    abi,
 -    pref
 +    abi_pow2,
 +    pref_pow2
  });
  
  impl_stable_hash_for!(struct ::ty::layout::Size {
index c04e580a33dedaa1c6f840b3c2cc5f33df9bfd7d,e812dd2d6c442a4d6de5feaa1e484137a356a65f..7323407bab95d444c2da98b4aef98f5650bd362c
@@@ -671,16 -671,7 +671,16 @@@ macro_rules! define_maps 
                                 map: LockGuard<'_, QueryMap<$tcx, Self>>,
                                 dep_node: DepNode)
                                 -> Result<($V, DepNodeIndex), CycleError<$tcx>> {
 -                debug_assert!(!tcx.dep_graph.dep_node_exists(&dep_node));
 +                // If the following assertion triggers, it can have two reasons:
 +                // 1. Something is wrong with DepNode creation, either here or
 +                //    in DepGraph::try_mark_green()
 +                // 2. Two distinct query keys get mapped to the same DepNode
 +                //    (see for example #48923)
 +                assert!(!tcx.dep_graph.dep_node_exists(&dep_node),
 +                        "Forcing query with already existing DepNode.\n\
 +                          - query-key: {:?}\n\
 +                          - dep-node: {:?}",
 +                        key, dep_node);
  
                  profq_msg!(tcx, ProfileQueriesMsg::ProviderBegin);
                  let res = Self::start_job(tcx,
@@@ -1124,6 -1115,7 +1124,7 @@@ pub fn force_from_dep_node<'a, 'gcx, 'l
          }
          DepKind::MaybeUnusedExternCrates => { force!(maybe_unused_extern_crates, LOCAL_CRATE); }
          DepKind::StabilityIndex => { force!(stability_index, LOCAL_CRATE); }
+         DepKind::AllTraits => { force!(all_traits, LOCAL_CRATE); }
          DepKind::AllCrateNums => { force!(all_crate_nums, LOCAL_CRATE); }
          DepKind::ExportedSymbols => { force!(exported_symbols, krate!()); }
          DepKind::CollectAndPartitionTranslationItems => {
index e40a3057a95cf903d218b941a3edbd2a0d50d5a7,66071f242fb951ff31bf514dedc06e24fb332374..22b440eea60efec9e5ffa5606e9a4266f8d69d57
@@@ -459,7 -459,7 +459,7 @@@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> 
          let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
          let has_default_lib_allocator =
              attr::contains_name(tcx.hir.krate_attrs(), "default_lib_allocator");
-         let has_global_allocator = tcx.sess.has_global_allocator.get();
+         let has_global_allocator = *tcx.sess.has_global_allocator.get();
          let root = self.lazy(&CrateRoot {
              name: tcx.crate_name(LOCAL_CRATE),
              extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
@@@ -1414,7 -1414,7 +1414,7 @@@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEnco
          let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
  
          // Bring everything into deterministic order for hashing
 -        all_impls.sort_unstable_by_key(|&(trait_def_id, _)| {
 +        all_impls.sort_by_cached_key(|&(trait_def_id, _)| {
              tcx.def_path_hash(trait_def_id)
          });
  
              .into_iter()
              .map(|(trait_def_id, mut impls)| {
                  // Bring everything into deterministic order for hashing
 -                impls.sort_unstable_by_key(|&def_index| {
 +                impls.sort_by_cached_key(|&def_index| {
                      tcx.hir.definitions().def_path_hash(def_index)
                  });
  
index 09aba830d050de149bb21d02830a51d910a49495,f181275326c7133a141ca57144f7d0493b36aa79..1da6f25fd639a0506daac80ef52e1e0d04359e30
@@@ -82,8 -82,7 +82,8 @@@ use std::ffi::CString
  use std::str;
  use std::sync::Arc;
  use std::time::{Instant, Duration};
 -use std::{i32, usize};
 +use std::i32;
 +use std::cmp;
  use std::sync::mpsc;
  use syntax_pos::Span;
  use syntax_pos::symbol::InternedString;
@@@ -518,7 -517,7 +518,7 @@@ pub fn set_link_section(cx: &CodegenCx
  /// users main function.
  fn maybe_create_entry_wrapper(cx: &CodegenCx) {
      let (main_def_id, span) = match *cx.sess().entry_fn.borrow() {
-         Some((id, span)) => {
+         Some((id, span, _)) => {
              (cx.tcx.hir.local_def_id(id), span)
          }
          None => return,
  
      let main_llfn = callee::get_fn(cx, instance);
  
-     let et = cx.sess().entry_type.get().unwrap();
+     let et = cx.sess().entry_fn.get().map(|e| e.2);
      match et {
-         config::EntryMain => create_entry_fn(cx, span, main_llfn, main_def_id, true),
-         config::EntryStart => create_entry_fn(cx, span, main_llfn, main_def_id, false),
-         config::EntryNone => {}    // Do nothing.
+         Some(config::EntryMain) => create_entry_fn(cx, span, main_llfn, main_def_id, true),
+         Some(config::EntryStart) => create_entry_fn(cx, span, main_llfn, main_def_id, false),
+         None => {}    // Do nothing.
      }
  
      fn create_entry_fn<'cx>(cx: &'cx CodegenCx,
@@@ -738,7 -737,7 +738,7 @@@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtx
          source: ModuleSource::Translated(ModuleLlvm {
              llcx: metadata_llcx,
              llmod: metadata_llmod,
-             tm: create_target_machine(tcx.sess),
+             tm: create_target_machine(tcx.sess, false),
          }),
          kind: ModuleKind::Metadata,
      };
          codegen_units.len());
  
      // Translate an allocator shim, if any
-     let allocator_module = if let Some(kind) = tcx.sess.allocator_kind.get() {
+     let allocator_module = if let Some(kind) = *tcx.sess.allocator_kind.get() {
          unsafe {
              let llmod_id = "allocator";
              let (llcx, llmod) =
              let modules = ModuleLlvm {
                  llmod,
                  llcx,
-                 tm: create_target_machine(tcx.sess),
+                 tm: create_target_machine(tcx.sess, false),
              };
              time(tcx.sess, "write allocator module", || {
                  allocator::trans(tcx, &modules, kind)
      // a bit more efficiently.
      let codegen_units = {
          let mut codegen_units = codegen_units;
 -        codegen_units.sort_by_key(|cgu| usize::MAX - cgu.size_estimate());
 +        codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
          codegen_units
      };
  
@@@ -1261,7 -1260,7 +1261,7 @@@ fn compile_codegen_unit<'a, 'tcx>(tcx: 
              let llvm_module = ModuleLlvm {
                  llcx: cx.llcx,
                  llmod: cx.llmod,
-                 tm: create_target_machine(cx.sess()),
+                 tm: create_target_machine(cx.sess(), false),
              };
  
              ModuleTranslation {
index 87d9623e4003849ae98f67628a40d12090fe155d,0ba11a1785baf320e6817b77ce228a3a64740927..28311018ee7d7d3e3ecbed32d7042d5239c12fda
@@@ -42,7 -42,7 +42,7 @@@ use std::ptr
  
  use syntax_pos::{self, Span, Pos};
  use syntax::ast;
 -use syntax::symbol::Symbol;
 +use syntax::symbol::{Symbol, InternedString};
  use rustc::ty::layout::{self, LayoutOf};
  
  pub mod gdb;
@@@ -263,7 -263,7 +263,7 @@@ pub fn create_function_debug_context<'a
  
      let local_id = cx.tcx.hir.as_local_node_id(def_id);
      match *cx.sess().entry_fn.borrow() {
-         Some((id, _)) => {
+         Some((id, _, _)) => {
              if local_id == Some(id) {
                  flags = flags | DIFlags::FlagMainSubprogram;
              }
              substs.types().zip(names).map(|(ty, name)| {
                  let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
                  let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
 -                let name = CString::new(name.as_str().as_bytes()).unwrap();
 +                let name = CString::new(name.as_bytes()).unwrap();
                  unsafe {
                      llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
                          DIB(cx),
          return create_DIArray(DIB(cx), &template_params[..]);
      }
  
 -    fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec<ast::Name> {
 +    fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec<InternedString> {
          let mut names = generics.parent.map_or(vec![], |def_id| {
              get_type_parameter_names(cx, cx.tcx.generics_of(def_id))
          });
index ad128516a3af3f69ad9fd2cc6f48109c541cc1c1,85952ea7796907a797682b176bd6d46fa32ea06e..fa3ecb1cc1199810fe3093a488ba908c3b4b34d5
@@@ -134,14 -134,13 +134,14 @@@ pub fn to_llvm_feature<'a>(sess: &Sessi
          ("x86", "pclmulqdq") => "pclmul",
          ("x86", "rdrand") => "rdrnd",
          ("x86", "bmi1") => "bmi",
 +        ("aarch64", "fp") => "fp-armv8",
          ("aarch64", "fp16") => "fullfp16",
          (_, s) => s,
      }
  }
  
  pub fn target_features(sess: &Session) -> Vec<Symbol> {
-     let target_machine = create_target_machine(sess);
+     let target_machine = create_target_machine(sess, true);
      target_feature_whitelist(sess)
          .iter()
          .filter(|feature| {
@@@ -179,7 -178,7 +179,7 @@@ pub fn print_passes() 
  
  pub(crate) fn print(req: PrintRequest, sess: &Session) {
      require_inited();
-     let tm = create_target_machine(sess);
+     let tm = create_target_machine(sess, true);
      unsafe {
          match req {
              PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
index b297fd9986501946f99efd2e29979133332406fd,a33978eeb62f56fa38800269bf22d19448ec4286..0c6bc9e246bcec79b07f42ecacf7f8412427b642
@@@ -15,6 -15,7 +15,6 @@@
  #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
 -#![deny(warnings)]
  
  #![feature(box_patterns)]
  #![feature(box_syntax)]
@@@ -51,7 -52,7 +51,7 @@@ pub mod symbol_names_test
  /// that actually test that compilation succeeds without
  /// reporting an error.
  pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
-     if let Some((id, span)) = *tcx.sess.entry_fn.borrow() {
+     if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
          let main_def_id = tcx.hir.local_def_id(id);
  
          if tcx.has_attr(main_def_id, "rustc_error") {
index a60ba4c6d16669cfb0805d494dd8754b5a5f51ea,fc60e984ea1466af8dfb929b90f6990afe83d905..da0b616b17373ff1377d89bce3a51ceabede676a
@@@ -730,6 -730,7 +730,7 @@@ fn check_impl_item_well_formed<'a, 'tcx
  }
  
  pub fn provide(providers: &mut Providers) {
+     method::provide(providers);
      *providers = Providers {
          typeck_item_bodies,
          typeck_tables_of,
@@@ -1127,10 -1128,10 +1128,10 @@@ fn check_fn<'a, 'gcx, 'tcx>(inherited: 
  
      // Check that the main return type implements the termination trait.
      if let Some(term_id) = fcx.tcx.lang_items().termination() {
-         if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() {
+         if let Some((id, _, entry_type)) = *fcx.tcx.sess.entry_fn.borrow() {
              if id == fn_id {
-                 match fcx.sess().entry_type.get() {
-                     Some(config::EntryMain) => {
+                 match entry_type {
+                     config::EntryMain => {
                          let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty)));
                          let trait_ref = ty::TraitRef::new(term_id, substs);
                          let return_ty_span = decl.output.span();
                              traits::Obligation::new(
                                  cause, param_env, trait_ref.to_predicate()));
                      },
-                     _ => {},
+                     config::EntryStart => {},
                  }
              }
          }
@@@ -1553,19 -1554,8 +1554,19 @@@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt
  }
  
  fn check_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) {
 -    if tcx.adt_def(def_id).repr.packed() {
 -        if tcx.adt_def(def_id).repr.align > 0 {
 +    let repr = tcx.adt_def(def_id).repr;
 +    if repr.packed() {
 +        for attr in tcx.get_attrs(def_id).iter() {
 +            for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) {
 +                if let attr::ReprPacked(pack) = r {
 +                    if pack != repr.pack {
 +                        struct_span_err!(tcx.sess, sp, E0634,
 +                                         "type has conflicting packed representation hints").emit();
 +                    }
 +                }
 +            }
 +        }
 +        if repr.align > 0 {
              struct_span_err!(tcx.sess, sp, E0587,
                               "type has conflicting packed and align representation hints").emit();
          }
index 3a48e1806af2cad25b83d5037b35b192576b4673,7891cc4471ff96e966a0d4c66c3b772205e7eb81..4b66939963ed0a37add319284a78a58ae130fb4e
@@@ -68,6 -68,7 +68,6 @@@ This API is completely unstable and sub
  #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
 -#![deny(warnings)]
  
  #![allow(non_camel_case_types)]
  
  #![feature(crate_visibility_modifier)]
  #![feature(from_ref)]
  #![feature(exhaustive_patterns)]
 -#![feature(option_filter)]
  #![feature(quote)]
  #![feature(refcell_replace_swap)]
  #![feature(rustc_diagnostic_macros)]
  #![feature(slice_patterns)]
 +#![feature(slice_sort_by_cached_key)]
  #![feature(dyn_trait)]
  
  #[macro_use] extern crate log;
@@@ -288,12 -289,10 +288,10 @@@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyC
  }
  
  fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-     if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() {
-         match tcx.sess.entry_type.get() {
-             Some(config::EntryMain) => check_main_fn_ty(tcx, id, sp),
-             Some(config::EntryStart) => check_start_fn_ty(tcx, id, sp),
-             Some(config::EntryNone) => {}
-             None => bug!("entry function without a type")
+     if let Some((id, sp, entry_type)) = *tcx.sess.entry_fn.borrow() {
+         match entry_type {
+             config::EntryMain => check_main_fn_ty(tcx, id, sp),
+             config::EntryStart => check_start_fn_ty(tcx, id, sp),
          }
      }
  }