]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #54487 - RalfJung:ctfe-backtrace, r=oli-obk
authorbors <bors@rust-lang.org>
Sun, 28 Oct 2018 18:49:46 +0000 (18:49 +0000)
committerbors <bors@rust-lang.org>
Sun, 28 Oct 2018 18:49:46 +0000 (18:49 +0000)
Delayed CTFE backtraces

This renames the env var that controls CTFE backtraces from `MIRI_BACKTRACE` to `RUST_CTFE_BACKTRACE` so that we can use `MIRI_BACKTRACE` in the miri tool to only show backtraces of the main miri execution.

It also makes `RUST_CTFE_BACKTRACE` only show backtraces that actually get rendered as errors, instead of showing them eagerly when the `Err` happens. The current behavior is near useless in miri because it shows about one gazillion backtraces for errors that we later catch and do not care about. However, @oli-obk likes the current behavior for rustc CTFE work so it is still available via `RUST_CTFE_BACKTRACE=immediate`.

NOTE: This is based on top of https://github.com/rust-lang/rust/pull/53821. Only [the last three commits](https://github.com/oli-obk/rust/compare/sanity_query...RalfJung:ctfe-backtrace) are new.

Fixes https://github.com/rust-lang/rust/issues/53355

41 files changed:
src/liballoc/string.rs
src/libcore/iter/iterator.rs
src/libcore/lib.rs
src/libcore/mem.rs
src/librustc/mir/mod.rs
src/librustc/util/ppaux.rs
src/librustc_mir/const_eval.rs
src/librustc_mir/dataflow/impls/borrows.rs
src/librustc_mir/dataflow/mod.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/qualify_min_const_fn.rs
src/librustc_resolve/error_reporting.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_typeck/check/wfcheck.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/html/static/rustdoc.css
src/libstd/path.rs
src/libsyntax/parse/parser.rs
src/test/mir-opt/end_region_4.rs
src/test/mir-opt/end_region_5.rs
src/test/mir-opt/end_region_6.rs
src/test/mir-opt/end_region_7.rs
src/test/mir-opt/end_region_8.rs
src/test/mir-opt/end_region_destruction_extents_1.rs
src/test/mir-opt/packed-struct-drop-aligned.rs
src/test/ui/consts/single_variant_match_ice.rs [new file with mode: 0644]
src/test/ui/consts/single_variant_match_ice.stderr [new file with mode: 0644]
src/test/ui/issues/issue-21554.stderr
src/test/ui/issues/issue-35241.stderr
src/test/ui/issues/issue-50411.rs [new file with mode: 0644]
src/test/ui/namespace/namespace-mix.stderr
src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs [new file with mode: 0644]
src/test/ui/non_modrs_mods_and_inline_mods/x.rs [new file with mode: 0644]
src/test/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs [new file with mode: 0644]
src/test/ui/privacy/private-inferred-type-3.rs
src/test/ui/privacy/private-inferred-type-3.stderr
src/test/ui/privacy/private-inferred-type.rs
src/test/ui/privacy/private-inferred-type.stderr
src/test/ui/rust-2018/local-path-suggestions-2018.stderr
src/test/ui/static/static-extern-type.rs [new file with mode: 0644]

index ab3f8fc27072071c754c842094d57b295e441dbc..ff3587d5d87306af60550c20f71c5d24325ba626 100644 (file)
@@ -413,7 +413,7 @@ pub const fn new() -> String {
     ///
     /// // These are all done without reallocating...
     /// let cap = s.capacity();
-    /// for i in 0..10 {
+    /// for _ in 0..10 {
     ///     s.push('a');
     /// }
     ///
index 5b6d9e2033caa74078f804e2dbdf70d24414fb37..2903c370df898e3d107f6946d14268dd69f09693 100644 (file)
@@ -1857,7 +1857,7 @@ fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
     /// ```
     /// let a = ["lol", "NaN", "2", "5"];
     ///
-    /// let mut first_number = a.iter().find_map(|s| s.parse().ok());
+    /// let first_number = a.iter().find_map(|s| s.parse().ok());
     ///
     /// assert_eq!(first_number, Some(2));
     /// ```
index 4156b1bec92a09dc1a9bb7ffcd5a0e1db9db6aed..06727d8292d367e422f89d87542a82413d80cc0e 100644 (file)
@@ -82,6 +82,7 @@
 #![feature(const_fn)]
 #![feature(const_int_ops)]
 #![feature(const_fn_union)]
+#![feature(const_manually_drop_new)]
 #![feature(custom_attribute)]
 #![feature(doc_cfg)]
 #![feature(doc_spotlight)]
index 27ee9556bd0895dbe2ccd6e903812a57d3e721df..22016e8cf41742612d1a1e62665ac03f93aec27f 100644 (file)
@@ -973,6 +973,26 @@ pub const fn new(value: T) -> ManuallyDrop<T> {
     pub fn into_inner(slot: ManuallyDrop<T>) -> T {
         slot.value
     }
+
+    /// Takes the contained value out.
+    ///
+    /// This method is primarily intended for moving out values in drop.
+    /// Instead of using [`ManuallyDrop::drop`] to manually drop the value,
+    /// you can use this method to take the value and use it however desired.
+    /// `Drop` will be invoked on the returned value following normal end-of-scope rules.
+    ///
+    /// If you have ownership of the container, you can use [`ManuallyDrop::into_inner`] instead.
+    ///
+    /// # Safety
+    ///
+    /// This function semantically moves out the contained value without preventing further usage.
+    /// It is up to the user of this method to ensure that this container is not used again.
+    #[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
+    #[unstable(feature = "manually_drop_take", issue = "55422")]
+    #[inline]
+    pub unsafe fn take(slot: &mut ManuallyDrop<T>) -> T {
+        ManuallyDrop::into_inner(ptr::read(slot))
+    }
 }
 
 impl<T: ?Sized> ManuallyDrop<T> {
@@ -1021,6 +1041,15 @@ pub union MaybeUninit<T> {
 }
 
 impl<T> MaybeUninit<T> {
+    /// Create a new `MaybeUninit` initialized with the given value.
+    ///
+    /// Note that dropping a `MaybeUninit` will never call `T`'s drop code.
+    /// It is your responsibility to make sure `T` gets dropped if it got initialized.
+    #[unstable(feature = "maybe_uninit", issue = "53491")]
+    pub const fn new(val: T) -> MaybeUninit<T> {
+        MaybeUninit { value: ManuallyDrop::new(val) }
+    }
+
     /// Create a new `MaybeUninit` in an uninitialized state.
     ///
     /// Note that dropping a `MaybeUninit` will never call `T`'s drop code.
index 952783a91b2ed9d8b94fca79af742126c6b46c72..4fea07011ccfbb65268e7d443d4e7174732a602c 100644 (file)
@@ -69,6 +69,24 @@ fn local_decls(&self) -> &LocalDecls<'tcx> {
     }
 }
 
+/// The various "big phases" that MIR goes through.
+///
+/// Warning: ordering of variants is significant
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub enum MirPhase {
+    Build = 0,
+    Const = 1,
+    Validated = 2,
+    Optimized = 3,
+}
+
+impl MirPhase {
+    /// Gets the index of the current MirPhase within the set of all MirPhases.
+    pub fn phase_index(&self) -> usize {
+        *self as usize
+    }
+}
+
 /// Lowered representation of a single function.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Mir<'tcx> {
@@ -76,6 +94,13 @@ pub struct Mir<'tcx> {
     /// that indexes into this vector.
     basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
 
+    /// Records how far through the "desugaring and optimization" process this particular
+    /// MIR has traversed. This is particularly useful when inlining, since in that context
+    /// we instantiate the promoted constants and add them to our promoted vector -- but those
+    /// promoted items have already been optimized, whereas ours have not. This field allows
+    /// us to see the difference and forego optimization on the inlined promoted items.
+    pub phase: MirPhase,
+
     /// List of source scopes; these are referenced by statements
     /// and used for debuginfo. Indexed by a `SourceScope`.
     pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
@@ -151,6 +176,7 @@ pub fn new(
         );
 
         Mir {
+            phase: MirPhase::Build,
             basic_blocks,
             source_scopes,
             source_scope_local_data,
@@ -368,6 +394,7 @@ pub enum Safety {
 }
 
 impl_stable_hash_for!(struct Mir<'tcx> {
+    phase,
     basic_blocks,
     source_scopes,
     source_scope_local_data,
@@ -616,6 +643,13 @@ pub enum ImplicitSelfKind {
     None
 });
 
+impl_stable_hash_for!(enum self::MirPhase {
+    Build,
+    Const,
+    Validated,
+    Optimized,
+});
+
 mod binding_form_impl {
     use ich::StableHashingContext;
     use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
@@ -2905,6 +2939,7 @@ pub enum ClosureOutlivesSubject<'tcx> {
 
 CloneTypeFoldableAndLiftImpls! {
     BlockTailInfo,
+    MirPhase,
     Mutability,
     SourceInfo,
     UpvarDecl,
@@ -2917,6 +2952,7 @@ pub enum ClosureOutlivesSubject<'tcx> {
 
 BraceStructTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
+        phase,
         basic_blocks,
         source_scopes,
         source_scope_local_data,
index 709b844526529dbbcf4fe6c6e9f196481d986075..abdd7fd8d40bf0d220ad2022d1fa47d6f12eb243 100644 (file)
@@ -251,25 +251,17 @@ fn fn_sig<F: fmt::Write>(&mut self,
     fn parameterized<F: fmt::Write>(&mut self,
                                     f: &mut F,
                                     substs: &subst::Substs<'_>,
-                                    mut did: DefId,
+                                    did: DefId,
                                     projections: &[ty::ProjectionPredicate<'_>])
                                     -> fmt::Result {
         let key = ty::tls::with(|tcx| tcx.def_key(did));
-        let mut item_name = if let Some(name) = key.disambiguated_data.data.get_opt_name() {
-            Some(name)
-        } else {
-            did.index = key.parent.unwrap_or_else(
-                || bug!("finding type for {:?}, encountered def-id {:?} with no parent",
-                        did, did));
-            self.parameterized(f, substs, did, projections)?;
-            return write!(f, "::{}", key.disambiguated_data.data.as_interned_str());
-        };
 
         let verbose = self.is_verbose;
         let mut num_supplied_defaults = 0;
         let mut has_self = false;
         let mut own_counts: GenericParamCount = Default::default();
         let mut is_value_path = false;
+        let mut item_name = Some(key.disambiguated_data.data.as_interned_str());
         let fn_trait_kind = ty::tls::with(|tcx| {
             // Unfortunately, some kinds of items (e.g., closures) don't have
             // generics. So walk back up the find the closest parent that DOES
@@ -282,6 +274,7 @@ fn parameterized<F: fmt::Write>(&mut self,
                     DefPathData::AssocTypeInImpl(_) |
                     DefPathData::AssocExistentialInImpl(_) |
                     DefPathData::Trait(_) |
+                    DefPathData::Impl |
                     DefPathData::TypeNs(_) => {
                         break;
                     }
@@ -292,7 +285,6 @@ fn parameterized<F: fmt::Write>(&mut self,
                     }
                     DefPathData::CrateRoot |
                     DefPathData::Misc |
-                    DefPathData::Impl |
                     DefPathData::Module(_) |
                     DefPathData::MacroDef(_) |
                     DefPathData::ClosureExpr |
index ee610d213e7c79e939654622752aab8ac9799258..73cb203809419a3d313d384285a010508ba4ff6e 100644 (file)
@@ -619,6 +619,13 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
             other => return other,
         }
     }
+    // the first trace is for replicating an ice
+    // There's no tracking issue, but the next two lines concatenated link to the discussion on
+    // zulip. It's not really possible to test this, because it doesn't show up in diagnostics
+    // or MIR.
+    // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
+    // subject/anon_const_instance_printing/near/135980032
+    trace!("const eval: {}", key.value.instance);
     trace!("const eval: {:?}", key);
 
     let cid = key.value;
index f7043487c51a6d8ac95450835c38c3de7c3eeed8..cfccb950e8276a64a8a1c998b76f06fae68b9561 100644 (file)
@@ -184,7 +184,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
     }
 
     crate fn borrows(&self) -> &IndexVec<BorrowIndex, BorrowData<'tcx>> { &self.borrow_set.borrows }
-    pub fn scope_tree(&self) -> &Lrc<region::ScopeTree> { &self.scope_tree }
 
     pub fn location(&self, idx: BorrowIndex) -> &Location {
         &self.borrow_set.borrows[idx].reserve_location
index da4bd780eb4faa9b78eb2ad4ca5102eb9e943184..c19145636e6da101b7580299e3fee13c6c7eacb1 100644 (file)
@@ -724,20 +724,6 @@ pub fn new(mir: &'a Mir<'tcx>,
             }
         }
     }
-
-    pub fn new_from_sets(mir: &'a Mir<'tcx>,
-                         dead_unwinds: &'a BitSet<mir::BasicBlock>,
-                         sets: AllSets<D::Idx>,
-                         denotation: D) -> Self {
-        DataflowAnalysis {
-            mir,
-            dead_unwinds,
-            flow_state: DataflowState {
-                sets: sets,
-                operator: denotation,
-            }
-        }
-    }
 }
 
 impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
index d18836999dccfe7629c1c8221274c6a161571443..46c73c27fe10d547548bef204d4217cf2f08fcf6 100644 (file)
@@ -11,7 +11,7 @@
 use borrow_check::nll::type_check;
 use build;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc::mir::{Mir, Promoted};
+use rustc::mir::{Mir, MirPhase, Promoted};
 use rustc::ty::TyCtxt;
 use rustc::ty::query::Providers;
 use rustc::ty::steal::Steal;
@@ -155,53 +155,69 @@ fn run_pass<'a, 'tcx>(&self,
                           mir: &mut Mir<'tcx>);
 }
 
-pub macro run_passes($tcx:ident, $mir:ident, $def_id:ident, $suite_index:expr; $($pass:expr,)*) {{
-    let suite_index: usize = $suite_index;
-    let run_passes = |mir: &mut _, promoted| {
+pub fn run_passes(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    mir: &mut Mir<'tcx>,
+    def_id: DefId,
+    mir_phase: MirPhase,
+    passes: &[&dyn MirPass],
+) {
+    let phase_index = mir_phase.phase_index();
+
+    let run_passes = |mir: &mut Mir<'tcx>, promoted| {
+        if mir.phase >= mir_phase {
+            return;
+        }
+
         let source = MirSource {
-            def_id: $def_id,
-            promoted
+            def_id,
+            promoted,
         };
         let mut index = 0;
         let mut run_pass = |pass: &dyn MirPass| {
             let run_hooks = |mir: &_, index, is_after| {
-                dump_mir::on_mir_pass($tcx, &format_args!("{:03}-{:03}", suite_index, index),
+                dump_mir::on_mir_pass(tcx, &format_args!("{:03}-{:03}", phase_index, index),
                                       &pass.name(), source, mir, is_after);
             };
             run_hooks(mir, index, false);
-            pass.run_pass($tcx, source, mir);
+            pass.run_pass(tcx, source, mir);
             run_hooks(mir, index, true);
 
             index += 1;
         };
-        $(run_pass(&$pass);)*
+
+        for pass in passes {
+            run_pass(*pass);
+        }
+
+        mir.phase = mir_phase;
     };
 
-    run_passes(&mut $mir, None);
+    run_passes(mir, None);
 
-    for (index, promoted_mir) in $mir.promoted.iter_enumerated_mut() {
+    for (index, promoted_mir) in mir.promoted.iter_enumerated_mut() {
         run_passes(promoted_mir, Some(index));
 
-        // Let's make sure we don't miss any nested instances
-        assert!(promoted_mir.promoted.is_empty());
+        //Let's make sure we don't miss any nested instances
+        assert!(promoted_mir.promoted.is_empty())
     }
-}}
+}
 
 fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
     // Unsafety check uses the raw mir, so make sure it is run
     let _ = tcx.unsafety_check_result(def_id);
 
     let mut mir = tcx.mir_built(def_id).steal();
-    run_passes![tcx, mir, def_id, 0;
+    run_passes(tcx, &mut mir, def_id, MirPhase::Const, &[
         // Remove all `EndRegion` statements that are not involved in borrows.
-        cleanup_post_borrowck::CleanEndRegions,
+        &cleanup_post_borrowck::CleanEndRegions,
 
         // What we need to do constant evaluation.
-        simplify::SimplifyCfg::new("initial"),
-        type_check::TypeckMir,
-        rustc_peek::SanityCheck,
-        uniform_array_move_out::UniformArrayMoveOut,
-    ];
+        &simplify::SimplifyCfg::new("initial"),
+        &type_check::TypeckMir,
+        &rustc_peek::SanityCheck,
+        &uniform_array_move_out::UniformArrayMoveOut,
+    ]);
     tcx.alloc_steal_mir(mir)
 }
 
@@ -214,11 +230,11 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
     }
 
     let mut mir = tcx.mir_const(def_id).steal();
-    run_passes![tcx, mir, def_id, 1;
+    run_passes(tcx, &mut mir, def_id, MirPhase::Validated, &[
         // What we need to run borrowck etc.
-        qualify_consts::QualifyAndPromoteConstants,
-        simplify::SimplifyCfg::new("qualify-consts"),
-    ];
+        &qualify_consts::QualifyAndPromoteConstants,
+        &simplify::SimplifyCfg::new("qualify-consts"),
+    ]);
     tcx.alloc_steal_mir(mir)
 }
 
@@ -232,59 +248,59 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
     }
 
     let mut mir = tcx.mir_validated(def_id).steal();
-    run_passes![tcx, mir, def_id, 2;
+    run_passes(tcx, &mut mir, def_id, MirPhase::Optimized, &[
         // Remove all things not needed by analysis
-        no_landing_pads::NoLandingPads,
-        simplify_branches::SimplifyBranches::new("initial"),
-        remove_noop_landing_pads::RemoveNoopLandingPads,
+        &no_landing_pads::NoLandingPads,
+        &simplify_branches::SimplifyBranches::new("initial"),
+        &remove_noop_landing_pads::RemoveNoopLandingPads,
         // Remove all `AscribeUserType` statements.
-        cleanup_post_borrowck::CleanAscribeUserType,
+        &cleanup_post_borrowck::CleanAscribeUserType,
         // Remove all `FakeRead` statements and the borrows that are only
         // used for checking matches
-        cleanup_post_borrowck::CleanFakeReadsAndBorrows,
-        simplify::SimplifyCfg::new("early-opt"),
+        &cleanup_post_borrowck::CleanFakeReadsAndBorrows,
+        &simplify::SimplifyCfg::new("early-opt"),
 
         // These next passes must be executed together
-        add_call_guards::CriticalCallEdges,
-        elaborate_drops::ElaborateDrops,
-        no_landing_pads::NoLandingPads,
+        &add_call_guards::CriticalCallEdges,
+        &elaborate_drops::ElaborateDrops,
+        &no_landing_pads::NoLandingPads,
         // AddValidation needs to run after ElaborateDrops and before EraseRegions, and it needs
         // an AllCallEdges pass right before it.
-        add_call_guards::AllCallEdges,
-        add_validation::AddValidation,
+        &add_call_guards::AllCallEdges,
+        &add_validation::AddValidation,
         // AddMovesForPackedDrops needs to run after drop
         // elaboration.
-        add_moves_for_packed_drops::AddMovesForPackedDrops,
+        &add_moves_for_packed_drops::AddMovesForPackedDrops,
 
-        simplify::SimplifyCfg::new("elaborate-drops"),
+        &simplify::SimplifyCfg::new("elaborate-drops"),
 
         // No lifetime analysis based on borrowing can be done from here on out.
 
         // From here on out, regions are gone.
-        erase_regions::EraseRegions,
+        &erase_regions::EraseRegions,
 
-        lower_128bit::Lower128Bit,
+        &lower_128bit::Lower128Bit,
 
 
         // Optimizations begin.
-        uniform_array_move_out::RestoreSubsliceArrayMoveOut,
-        inline::Inline,
+        &uniform_array_move_out::RestoreSubsliceArrayMoveOut,
+        &inline::Inline,
 
         // Lowering generator control-flow and variables
         // has to happen before we do anything else to them.
-        generator::StateTransform,
-
-        instcombine::InstCombine,
-        const_prop::ConstProp,
-        simplify_branches::SimplifyBranches::new("after-const-prop"),
-        deaggregator::Deaggregator,
-        copy_prop::CopyPropagation,
-        remove_noop_landing_pads::RemoveNoopLandingPads,
-        simplify::SimplifyCfg::new("final"),
-        simplify::SimplifyLocals,
-
-        add_call_guards::CriticalCallEdges,
-        dump_mir::Marker("PreCodegen"),
-    ];
+        &generator::StateTransform,
+
+        &instcombine::InstCombine,
+        &const_prop::ConstProp,
+        &simplify_branches::SimplifyBranches::new("after-const-prop"),
+        &deaggregator::Deaggregator,
+        &copy_prop::CopyPropagation,
+        &remove_noop_landing_pads::RemoveNoopLandingPads,
+        &simplify::SimplifyCfg::new("final"),
+        &simplify::SimplifyLocals,
+
+        &add_call_guards::CriticalCallEdges,
+        &dump_mir::Marker("PreCodegen"),
+    ]);
     tcx.alloc_mir(mir)
 }
index 52c557b83d5916979301d743b5f8aa2b4a6091bf..6ab68789c027ba7bbdeb1a1aea580d676979b47d 100644 (file)
@@ -317,7 +317,8 @@ fn check_terminator(
             check_place(tcx, mir, location, span, PlaceMode::Read)?;
             check_operand(tcx, mir, value, span)
         },
-        TerminatorKind::SwitchInt { .. } => Err((
+
+        TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } => Err((
             span,
             "`if`, `match`, `&&` and `||` are not stable in const fn".into(),
         )),
@@ -363,7 +364,7 @@ fn check_terminator(
             cleanup: _,
         } => check_operand(tcx, mir, cond, span),
 
-        | TerminatorKind::FalseEdges { .. } | TerminatorKind::FalseUnwind { .. } => span_bug!(
+        | TerminatorKind::FalseUnwind { .. } => span_bug!(
             terminator.source_info.span,
             "min_const_fn encountered `{:#?}`",
             terminator
index def67923322aaabdd06f5809c8394d63627276f6..50ab8ef9c7be7cfaa543466579af248d96beaa5a 100644 (file)
@@ -26,7 +26,7 @@ pub(crate) fn make_path_suggestion(
         span: Span,
         path: Vec<Segment>,
         parent_scope: &ParentScope<'b>,
-    ) -> Option<Vec<Segment>> {
+    ) -> Option<(Vec<Segment>, Option<String>)> {
         debug!("make_path_suggestion: span={:?} path={:?}", span, path);
         // If we don't have a path to suggest changes to, then return.
         if path.is_empty() {
@@ -65,13 +65,13 @@ fn make_missing_self_suggestion(
         span: Span,
         mut path: Vec<Segment>,
         parent_scope: &ParentScope<'b>,
-    ) -> Option<Vec<Segment>> {
+    ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `self` and check if that is valid.
         path[0].ident.name = keywords::SelfValue.name();
         let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
-            Some(path)
+            Some((path, None))
         } else {
             None
         }
@@ -89,13 +89,20 @@ fn make_missing_crate_suggestion(
         span: Span,
         mut path: Vec<Segment>,
         parent_scope: &ParentScope<'b>,
-    ) -> Option<Vec<Segment>> {
+    ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = keywords::Crate.name();
         let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_crate_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
-            Some(path)
+            Some((
+                path,
+                Some(
+                    "`use` statements changed in Rust 2018; read more at \
+                     <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-\
+                     clarity.html>".to_string()
+                ),
+            ))
         } else {
             None
         }
@@ -113,13 +120,13 @@ fn make_missing_super_suggestion(
         span: Span,
         mut path: Vec<Segment>,
         parent_scope: &ParentScope<'b>,
-    ) -> Option<Vec<Segment>> {
+    ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = keywords::Super.name();
         let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_super_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
-            Some(path)
+            Some((path, None))
         } else {
             None
         }
@@ -140,7 +147,7 @@ fn make_external_crate_suggestion(
         span: Span,
         mut path: Vec<Segment>,
         parent_scope: &ParentScope<'b>,
-    ) -> Option<Vec<Segment>> {
+    ) -> Option<(Vec<Segment>, Option<String>)> {
         // Need to clone else we can't call `resolve_path` without a borrow error. We also store
         // into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic)
         // each time.
@@ -162,7 +169,7 @@ fn make_external_crate_suggestion(
             debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}",
                     name, path, result);
             if let PathResult::Module(..) = result {
-                return Some(path)
+                return Some((path, None));
             }
         }
 
index 3ca0a9f7f1b973bd16bdcbdeeb440b9b790845ea..359640ccda2b1eb6360e868f45c0dd69c42df2b6 100644 (file)
@@ -707,7 +707,7 @@ struct UniformPathsCanaryResults<'a> {
                         }
                     }
                 });
-            } else if let Some((span, err)) = error {
+            } else if let Some((span, err, note)) = error {
                 errors = true;
 
                 if let SingleImport { source, ref result, .. } = import.subclass {
@@ -737,7 +737,7 @@ struct UniformPathsCanaryResults<'a> {
                         &import.subclass,
                         span,
                     );
-                    error_vec.push((span, path, err));
+                    error_vec.push((span, path, err, note));
                     seen_spans.insert(span);
                     prev_root_id = import.root_id;
                 }
@@ -829,27 +829,45 @@ struct UniformPathsCanaryResults<'a> {
         }
     }
 
-    fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>,
-                                     span: Option<MultiSpan>) {
+    fn throw_unresolved_import_error(
+        &self,
+        error_vec: Vec<(Span, String, String, Option<String>)>,
+        span: Option<MultiSpan>,
+    ) {
         let max_span_label_msg_count = 10;  // upper limit on number of span_label message.
-        let (span, msg) = if error_vec.is_empty() {
-            (span.unwrap(), "unresolved import".to_string())
+        let (span, msg, note) = if error_vec.is_empty() {
+            (span.unwrap(), "unresolved import".to_string(), None)
         } else {
-            let span = MultiSpan::from_spans(error_vec.clone().into_iter()
-                .map(|elem: (Span, String, String)| { elem.0 })
-                .collect());
+            let span = MultiSpan::from_spans(
+                error_vec.clone().into_iter()
+                .map(|elem: (Span, String, String, Option<String>)| elem.0)
+                .collect()
+            );
+
+            let note: Option<String> = error_vec.clone().into_iter()
+                .filter_map(|elem: (Span, String, String, Option<String>)| elem.3)
+                .last();
+
             let path_vec: Vec<String> = error_vec.clone().into_iter()
-                .map(|elem: (Span, String, String)| { format!("`{}`", elem.1) })
+                .map(|elem: (Span, String, String, Option<String>)| format!("`{}`", elem.1))
                 .collect();
             let path = path_vec.join(", ");
-            let msg = format!("unresolved import{} {}",
-                if path_vec.len() > 1 { "s" } else { "" }, path);
-            (span, msg)
+            let msg = format!(
+                "unresolved import{} {}",
+                if path_vec.len() > 1 { "s" } else { "" },
+                path
+            );
+
+            (span, msg, note)
         };
+
         let mut err = struct_span_err!(self.resolver.session, span, E0432, "{}", &msg);
         for span_error in error_vec.into_iter().take(max_span_label_msg_count) {
             err.span_label(span_error.0, span_error.2);
         }
+        if let Some(note) = note {
+            err.note(&note);
+        }
         err.emit();
     }
 
@@ -945,7 +963,10 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
     }
 
     // If appropriate, returns an error to report.
-    fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> {
+    fn finalize_import(
+        &mut self,
+        directive: &'b ImportDirective<'b>
+    ) -> Option<(Span, String, Option<String>)> {
         self.current_module = directive.parent_scope.module;
         let ImportDirective { ref module_path, span, .. } = *directive;
 
@@ -969,15 +990,16 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
                 return None;
             }
             PathResult::Failed(span, msg, true) => {
-                return if let Some(suggested_path) = self.make_path_suggestion(
+                return if let Some((suggested_path, note)) = self.make_path_suggestion(
                     span, module_path.clone(), &directive.parent_scope
                 ) {
                     Some((
                         span,
-                        format!("Did you mean `{}`?", Segment::names_to_string(&suggested_path))
+                        format!("Did you mean `{}`?", Segment::names_to_string(&suggested_path)),
+                        note,
                     ))
                 } else {
-                    Some((span, msg))
+                    Some((span, msg, None))
                 };
             },
             _ => return None,
@@ -1002,8 +1024,11 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
                 if let ModuleOrUniformRoot::Module(module) = module {
                     if module.def_id() == directive.parent_scope.module.def_id() {
                         // Importing a module into itself is not allowed.
-                        return Some((directive.span,
-                            "Cannot glob-import a module into itself.".to_string()));
+                        return Some((
+                            directive.span,
+                            "Cannot glob-import a module into itself.".to_string(),
+                            None,
+                        ));
                     }
                 }
                 if !is_prelude &&
@@ -1101,7 +1126,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa
                         }
                     }
                 };
-                Some((span, msg))
+                Some((span, msg, None))
             } else {
                 // `resolve_ident_in_module` reported a privacy error.
                 self.import_dummy_binding(directive);
index 9990d2ee2b6769d386f3e0b6a32ffc7ba69806c5..ea84e874b1a5b3b9dc6abb2a7f5bad9ff37f3bc5 100644 (file)
@@ -13,7 +13,7 @@
 
 use hir::def_id::DefId;
 use rustc::traits::{self, ObligationCauseCode};
-use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
+use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::util::ExplicitSelf;
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
@@ -119,14 +119,14 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def
             check_item_fn(tcx, item);
         }
         hir::ItemKind::Static(ref ty, ..) => {
-            check_item_type(tcx, item.id, ty.span);
+            check_item_type(tcx, item.id, ty.span, false);
         }
         hir::ItemKind::Const(ref ty, ..) => {
-            check_item_type(tcx, item.id, ty.span);
+            check_item_type(tcx, item.id, ty.span, false);
         }
         hir::ItemKind::ForeignMod(ref module) => for it in module.items.iter() {
             if let hir::ForeignItemKind::Static(ref ty, ..) = it.node {
-                check_item_type(tcx, it.id, ty.span);
+                check_item_type(tcx, it.id, ty.span, true);
             }
         },
         hir::ItemKind::Struct(ref struct_def, ref ast_generics) => {
@@ -340,23 +340,33 @@ fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
     })
 }
 
-fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId, ty_span: Span) {
+fn check_item_type<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    item_id: ast::NodeId,
+    ty_span: Span,
+    allow_foreign_ty: bool,
+) {
     debug!("check_item_type: {:?}", item_id);
 
     for_id(tcx, item_id, ty_span).with_fcx(|fcx, _this| {
         let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item_id));
         let item_ty = fcx.normalize_associated_types_in(ty_span, &ty);
 
+        let mut forbid_unsized = true;
+        if allow_foreign_ty {
+            if let TyKind::Foreign(_) = tcx.struct_tail(item_ty).sty {
+                forbid_unsized = false;
+            }
+        }
+
         fcx.register_wf_obligation(item_ty, ty_span, ObligationCauseCode::MiscObligation);
-        fcx.register_bound(
-            item_ty,
-            fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
-            traits::ObligationCause::new(
-                ty_span,
-                fcx.body_id,
-                traits::MiscObligation,
-            ),
-        );
+        if forbid_unsized {
+            fcx.register_bound(
+                item_ty,
+                fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
+                traits::ObligationCause::new(ty_span, fcx.body_id, traits::MiscObligation),
+            );
+        }
 
         vec![] // no implied bounds in a const etc
     });
index 8b35ede4a02c07ec86552e138f7b26ba31c7e802..0fc2473725a16c95db172dd25d4c5217d223cf41 100644 (file)
@@ -3379,10 +3379,10 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                 let variant_id = cx.derive_id(format!("{}.{}.fields",
                                                    ItemType::Variant,
                                                    variant.name.as_ref().unwrap()));
-                write!(w, "<span class='docblock autohide sub-variant' id='{id}'>",
+                write!(w, "<span class='autohide sub-variant' id='{id}'>",
                        id = variant_id)?;
-                write!(w, "<h3 class='fields'>Fields of <code>{name}</code></h3>\n
-                           <table>", name = variant.name.as_ref().unwrap())?;
+                write!(w, "<h3>Fields of <b>{name}</b></h3><div>",
+                       name = variant.name.as_ref().unwrap())?;
                 for field in &s.fields {
                     use clean::StructFieldItem;
                     if let StructFieldItem(ref ty) = field.inner {
@@ -3394,19 +3394,18 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                                                       ItemType::Variant.name_space(),
                                                       field.name.as_ref().unwrap(),
                                                       ItemType::StructField.name_space()));
-                        write!(w, "<tr><td \
-                                   id='{id}'>\
-                                   <span id='{ns_id}' class='invisible'>\
-                                   <code>{f}:&nbsp;{t}</code></span></td><td>",
+                        write!(w, "<span id=\"{id}\" class=\"variant small-section-header\">\
+                                   <a href=\"#{id}\" class=\"anchor field\"></a>\
+                                   <span id='{ns_id}' class='invisible'><code>{f}:&nbsp;{t}\
+                                   </code></span></span>",
                                id = id,
                                ns_id = ns_id,
                                f = field.name.as_ref().unwrap(),
                                t = *ty)?;
                         document(w, cx, field)?;
-                        write!(w, "</td></tr>")?;
                     }
                 }
-                write!(w, "</table></span>")?;
+                write!(w, "</div></span>")?;
             }
             render_stability_since(w, variant, it)?;
         }
index 9d1a5c38378308f6a6ca4c1ccb096b003d2e70ab..02229b82b8ac3e76a7a022f99c47a1f4a78137fb 100644 (file)
             if (hasClass(relatedDoc, "stability")) {
                 relatedDoc = relatedDoc.nextElementSibling;
             }
-            if (hasClass(relatedDoc, "docblock")) {
+            if (hasClass(relatedDoc, "docblock") || hasClass(relatedDoc, "sub-variant")) {
                 var action = mode;
                 if (action === "toggle") {
                     if (hasClass(relatedDoc, "hidden-by-usual-hider")) {
     }
 
     var hideItemDeclarations = getCurrentValue('rustdoc-item-declarations') === "false";
-    onEach(document.getElementsByClassName('docblock'), function(e) {
+    function buildToggleWrapper(e) {
         if (hasClass(e, 'autohide')) {
             var wrap = e.previousElementSibling;
             if (wrap && hasClass(wrap, 'toggle-wrapper')) {
                 var toggle = wrap.childNodes[0];
-                var extra = false;
-                if (e.childNodes[0].tagName === 'H3') {
-                    extra = true;
-                }
+                var extra = e.childNodes[0].tagName === 'H3';
+
                 e.style.display = 'none';
                 addClass(wrap, 'collapsed');
                 onEach(toggle.getElementsByClassName('inner'), function(e) {
                 if (hideItemDeclarations === false) {
                     extraClass = 'collapsed';
                 }
+            } else if (hasClass(e, "sub-variant")) {
+                otherMessage = '&nbsp;Show&nbsp;fields';
             } else if (hasClass(e, "non-exhaustive")) {
                 otherMessage = '&nbsp;This&nbsp;';
                 if (hasClass(e, "non-exhaustive-struct")) {
                 collapseDocs(e.previousSibling.childNodes[0], "toggle");
             }
         }
-    });
+    }
+
+    onEach(document.getElementsByClassName('docblock'), buildToggleWrapper);
+    onEach(document.getElementsByClassName('sub-variant'), buildToggleWrapper);
 
     function createToggleWrapper(tog) {
         var span = document.createElement('span');
index c0951d9f8401e45a94db9a00d813a6bb213863e9..8bcb828a5ade1e22f961bf5d68fb3ac1ed1eec5d 100644 (file)
@@ -517,6 +517,10 @@ h4 > code, h3 > code, .invisible > code {
        margin-top: -13px;
 }
 
+.sub-variant > div > .stability {
+       margin-top: initial;
+}
+
 .content .stability::before {
        content: '˪';
        font-size: 30px;
@@ -866,7 +870,23 @@ span.since {
 }
 
 .sub-variant, .sub-variant > h3 {
-       margin-top: 0 !important;
+       margin-top: 1px !important;
+}
+
+#main > .sub-variant > h3 {
+       font-size: 15px;
+       margin-left: 25px;
+       margin-bottom: 5px;
+}
+
+.sub-variant > div {
+       margin-left: 20px;
+       margin-bottom: 10px;
+}
+
+.sub-variant > div > span {
+       display: block;
+       position: relative;
 }
 
 .toggle-label {
index ca8be75fab5beee3a11841b3b79870c23c615a1a..a153456370c6f45cbf50c3632b34467d5b3edaf7 100644 (file)
@@ -87,6 +87,8 @@
 use iter::{self, FusedIterator};
 use ops::{self, Deref};
 use rc::Rc;
+use str::FromStr;
+use string::ParseError;
 use sync::Arc;
 
 use ffi::{OsStr, OsString};
@@ -1443,6 +1445,15 @@ fn from(s: String) -> PathBuf {
     }
 }
 
+#[stable(feature = "path_from_str", since = "1.26.0")]
+impl FromStr for PathBuf {
+    type Err = ParseError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(PathBuf::from(s))
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<P: AsRef<Path>> iter::FromIterator<P> for PathBuf {
     fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
index 589b3e30fcfbc41bbd24a258f4f70bd969e5a60a..be448f960df3fd105310cbe657195a0bb7b5fe70 100644 (file)
@@ -6426,6 +6426,17 @@ fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
             self.directory.path.to_mut().push(&path.as_str());
             self.directory.ownership = DirectoryOwnership::Owned { relative: None };
         } else {
+            // We have to push on the current module name in the case of relative
+            // paths in order to ensure that any additional module paths from inline
+            // `mod x { ... }` come after the relative extension.
+            //
+            // For example, a `mod z { ... }` inside `x/y.rs` should set the current
+            // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
+            if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
+                if let Some(ident) = relative.take() { // remove the relative offset
+                    self.directory.path.to_mut().push(ident.as_str());
+                }
+            }
             self.directory.path.to_mut().push(&id.as_str());
         }
     }
index 359ed07a9c0953466257eb38bfef40fd4818f624..3d15f20bd05f33bd4098e9918242108897926c1e 100644 (file)
@@ -44,7 +44,7 @@ fn foo(i: i32) {
 //     let mut _5: i32;
 //     bb0: {
 //         StorageLive(_1);
-//         _1 = D::{{constructor}}(const 0i32,);
+//         _1 = D(const 0i32,);
 //         FakeRead(ForLet, _1);
 //         StorageLive(_2);
 //         _2 = const 0i32;
index 3b632e198cd669dbef85b63062c888eee7a31b9d..06d1fbabe16167863d1428bc1c65c37b3f7df22c 100644 (file)
@@ -37,7 +37,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //     let mut _4: &'18s D;
 //     bb0: {
 //         StorageLive(_1);
-//         _1 = D::{{constructor}}(const 0i32,);
+//         _1 = D(const 0i32,);
 //         FakeRead(ForLet, _1);
 //         StorageLive(_3);
 //         StorageLive(_4);
index 03c7de02ec11166236399cd1626c60b6329c5103..d0db23e6de0ee177095cc7f390cdf645502d37d9 100644 (file)
@@ -37,7 +37,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //     let mut _4: &'24s D;
 //     bb0: {
 //         StorageLive(_1);
-//         _1 = D::{{constructor}}(const 0i32,);
+//         _1 = D(const 0i32,);
 //         FakeRead(ForLet, _1);
 //         StorageLive(_3);
 //         StorageLive(_4);
index 56e3e0aa6f7a9a6ff195389ecb53682035817d3b..c7df440ebe2f31ef212edc28f24cb4fa67a6f442 100644 (file)
@@ -36,7 +36,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //     let mut _3: [closure@NodeId(33) d:D];
 //     bb0: {
 //         StorageLive(_1);
-//         _1 = D::{{constructor}}(const 0i32,);
+//         _1 = D(const 0i32,);
 //         FakeRead(ForLet, _1);
 //         StorageLive(_3);
 //         _3 = [closure@NodeId(33)] { d: move _1 };
index 0a54dcaa0d33fa31f574df55d0f02868b4c69119..9f2a9c3b72e8b6d685acd37f7b03ddfc12a001ff 100644 (file)
@@ -39,7 +39,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
 //    let mut _4: [closure@NodeId(33) r:&'24s D];
 //    bb0: {
 //        StorageLive(_1);
-//        _1 = D::{{constructor}}(const 0i32,);
+//        _1 = D(const 0i32,);
 //        FakeRead(ForLet, _1);
 //        StorageLive(_2);
 //        _2 = &'26_1rs _1;
index a5107d304386f6b56b0caeaa1edfd4f9ce588982..eb381dfc5521fb53a7175fe081e4882cdb1c110d 100644 (file)
@@ -79,16 +79,16 @@ fn drop(&mut self) {
 //         StorageLive(_3);
 //         StorageLive(_4);
 //         StorageLive(_5);
-//         _5 = S1::{{constructor}}(const "ex1",);
+//         _5 = S1(const "ex1",);
 //         _4 = &'15ds _5;
 //         _3 = &'15ds (*_4);
 //         StorageLive(_6);
 //         StorageLive(_7);
 //         StorageLive(_8);
-//         _8 = S1::{{constructor}}(const "dang1",);
+//         _8 = S1(const "dang1",);
 //         _7 = &'13s _8;
 //         _6 = &'13s (*_7);
-//         _2 = D1<'15ds, '13s>::{{constructor}}(move _3, move _6);
+//         _2 = D1<'15ds, '13s>(move _3, move _6);
 //         EndRegion('13s);
 //         StorageDead(_6);
 //         StorageDead(_3);
@@ -132,7 +132,7 @@ fn drop(&mut self) {
 //         StorageLive(_7);
 //         _7 = &'13s (promoted[0]: S1);
 //         _6 = &'13s (*_7);
-//         _2 = D1<'15ds, '13s>::{{constructor}}(move _3, move _6);
+//         _2 = D1<'15ds, '13s>(move _3, move _6);
 //         EndRegion('13s);
 //         StorageDead(_6);
 //         StorageDead(_3);
index 9441c6f4085a2d9bc3bfbbf75618219f2d4caeb1..1fe29a29e23181521886faa6d8e782b1d9fd1041 100644 (file)
@@ -42,7 +42,7 @@ fn drop(&mut self) {}
 //     bb0: {
 //         StorageLive(_1);
 //         ...
-//         _1 = Packed::{{constructor}}(move _2,);
+//         _1 = Packed(move _2,);
 //         ...
 //         StorageLive(_6);
 //         _6 = move (_1.0: Aligned);
diff --git a/src/test/ui/consts/single_variant_match_ice.rs b/src/test/ui/consts/single_variant_match_ice.rs
new file mode 100644 (file)
index 0000000..67a41bc
--- /dev/null
@@ -0,0 +1,15 @@
+enum Foo {
+    Prob,
+}
+
+impl Foo {
+    pub const fn as_val(&self) -> u8 {
+        use self::Foo::*;
+
+        match *self {
+            Prob => 0x1, //~ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/single_variant_match_ice.stderr b/src/test/ui/consts/single_variant_match_ice.stderr
new file mode 100644 (file)
index 0000000..a0222b0
--- /dev/null
@@ -0,0 +1,8 @@
+error: `if`, `match`, `&&` and `||` are not stable in const fn
+  --> $DIR/single_variant_match_ice.rs:10:13
+   |
+LL |             Prob => 0x1, //~ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
+   |             ^^^^
+
+error: aborting due to previous error
+
index be7762f1aa245c2633f489f44958eb963b0fdde5..104970ea448aa4d0cfef1a88016b341875d926da 100644 (file)
@@ -1,4 +1,4 @@
-error[E0606]: casting `fn(i32) -> Inches {Inches::{{constructor}}}` as `f32` is invalid
+error[E0606]: casting `fn(i32) -> Inches {Inches}` as `f32` is invalid
   --> $DIR/issue-21554.rs:14:5
    |
 LL |     Inches as f32;
index 42bf0aae5b12ce0bb6e6d5fbd1f71c8aa4d2bb24..4404f88de311b483655fd414b5afada045a410be 100644 (file)
@@ -9,7 +9,7 @@ LL | fn test() -> Foo { Foo } //~ ERROR mismatched types
    |              expected `Foo` because of return type
    |
    = note: expected type `Foo`
-              found type `fn(u32) -> Foo {Foo::{{constructor}}}`
+              found type `fn(u32) -> Foo {Foo}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50411.rs b/src/test/ui/issues/issue-50411.rs
new file mode 100644 (file)
index 0000000..1ba47d3
--- /dev/null
@@ -0,0 +1,11 @@
+// Regression test for #50411: the MIR inliner was causing problems
+// here because it would inline promoted code (which had already had
+// elaborate-drops invoked on it) and then try to elaboate drops a
+// second time. Uncool.
+
+// compile-flags:-Zmir-opt-level=3
+// compile-pass
+
+fn main() {
+    let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count();
+}
index 6d72b6044aebea9f2901d668a425025fe3b1f4ba..0a297e58574f7a742ac6a7952ad725fa4cb58e0a 100644 (file)
@@ -144,11 +144,11 @@ note: required by `check`
 LL | fn check<T: Impossible>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `fn() -> c::TS {c::TS::{{constructor}}}: Impossible` is not satisfied
+error[E0277]: the trait bound `fn() -> c::TS {c::TS}: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:66:5
    |
 LL |     check(m3::TS); //~ ERROR c::TS
-   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS::{{constructor}}}`
+   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
    |
 note: required by `check`
   --> $DIR/namespace-mix.rs:31:1
@@ -192,11 +192,11 @@ note: required by `check`
 LL | fn check<T: Impossible>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `fn() -> namespace_mix::c::TS {namespace_mix::c::TS::{{constructor}}}: Impossible` is not satisfied
+error[E0277]: the trait bound `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:72:5
    |
 LL |     check(xm3::TS); //~ ERROR c::TS
-   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS::{{constructor}}}`
+   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
    |
 note: required by `check`
   --> $DIR/namespace-mix.rs:31:1
diff --git a/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs b/src/test/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs
new file mode 100644 (file)
index 0000000..25a9c2e
--- /dev/null
@@ -0,0 +1,5 @@
+// compile-pass
+
+mod x;
+
+fn main() {}
diff --git a/src/test/ui/non_modrs_mods_and_inline_mods/x.rs b/src/test/ui/non_modrs_mods_and_inline_mods/x.rs
new file mode 100644 (file)
index 0000000..a39a7c6
--- /dev/null
@@ -0,0 +1,5 @@
+// ignore-test: not a test
+
+pub mod y {
+    pub mod z;
+}
diff --git a/src/test/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs b/src/test/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs
new file mode 100644 (file)
index 0000000..e8442a4
--- /dev/null
@@ -0,0 +1 @@
+// ignore-test: not a test
index 0c393f02323ec04a3757f16aa641798c773227bb..5151f624b8d98b033532cd95df0ce17e744650a1 100644 (file)
@@ -14,8 +14,8 @@
 // error-pattern:static `PRIV_STATIC` is private
 // error-pattern:type `ext::PrivEnum` is private
 // error-pattern:type `fn() {<u8 as ext::PrivTrait>::method}` is private
-// error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct::{{constructor}}}` is pr
-// error-pattern:type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct::{{constructor}}}` is priv
+// error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private
+// error-pattern:type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private
 // error-pattern:type `for<'r> fn(&'r ext::Pub<u8>) {<ext::Pub<u8>>::priv_method}` is private
 
 #![feature(decl_macro)]
index 3c37a7ee1e8d244705215e94f94ee771b2c07cc8..590ff76b375f23090768106c79e14c7750dc136a 100644 (file)
@@ -30,7 +30,7 @@ LL |     ext::m!();
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
-error: type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct::{{constructor}}}` is private
+error: type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private
   --> $DIR/private-inferred-type-3.rs:26:5
    |
 LL |     ext::m!();
@@ -38,7 +38,7 @@ LL |     ext::m!();
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
-error: type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct::{{constructor}}}` is private
+error: type `fn(u8) -> ext::PubTupleStruct {ext::PubTupleStruct}` is private
   --> $DIR/private-inferred-type-3.rs:26:5
    |
 LL |     ext::m!();
index 3ca8b1eb2ed3a3d61b36484b2deb13d96a512d41..58e17b24394a1cae4fcc7ff58e38d6af25ccbfc7 100644 (file)
@@ -53,9 +53,9 @@ impl TraitWithAssocConst for Priv {}
         <u8 as PrivTrait>::method; //~ ERROR type `fn() {<u8 as m::PrivTrait>::method}` is private
         <u8 as PubTrait>::method; // OK
         PrivTupleStruct;
-        //~^ ERROR type `fn(u8) -> m::PrivTupleStruct {m::PrivTupleStruct::{{constructor}}}` is priv
+        //~^ ERROR type `fn(u8) -> m::PrivTupleStruct {m::PrivTupleStruct}` is private
         PubTupleStruct;
-        //~^ ERROR type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct::{{constructor}}}` is privat
+        //~^ ERROR type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct}` is private
         Pub(0u8).priv_method();
         //~^ ERROR type `for<'r> fn(&'r m::Pub<u8>) {<m::Pub<u8>>::priv_method}` is private
     }
index abbe43fe384cbacb7ee77b416bc098ea92a2a61e..1ab281cfc251537a599060fa41d470bf8b937edb 100644 (file)
@@ -115,7 +115,7 @@ LL |         <u8 as PrivTrait>::method; //~ ERROR type `fn() {<u8 as m::PrivTrai
 LL |     m::m!();
    |     -------- in this macro invocation
 
-error: type `fn(u8) -> m::PrivTupleStruct {m::PrivTupleStruct::{{constructor}}}` is private
+error: type `fn(u8) -> m::PrivTupleStruct {m::PrivTupleStruct}` is private
   --> $DIR/private-inferred-type.rs:55:9
    |
 LL |         PrivTupleStruct;
@@ -124,7 +124,7 @@ LL |         PrivTupleStruct;
 LL |     m::m!();
    |     -------- in this macro invocation
 
-error: type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct::{{constructor}}}` is private
+error: type `fn(u8) -> m::PubTupleStruct {m::PubTupleStruct}` is private
   --> $DIR/private-inferred-type.rs:57:9
    |
 LL |         PubTupleStruct;
index 97bf748881f29907490b26b2f3da80f2814cc72f..2293f4b001749cc45642dad5ae6fd1c840edd75d 100644 (file)
@@ -3,6 +3,8 @@ error[E0432]: unresolved import `foo`
    |
 LL |     use foo::Bar;
    |         ^^^ Did you mean `crate::foo`?
+   |
+   = note: `use` statements changed in Rust 2018; read more at <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html>
 
 error[E0432]: unresolved import `foo`
   --> $DIR/local-path-suggestions-2018.rs:27:5
diff --git a/src/test/ui/static/static-extern-type.rs b/src/test/ui/static/static-extern-type.rs
new file mode 100644 (file)
index 0000000..72e2853
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+#![feature(extern_types)]
+
+pub mod a {
+    extern "C" {
+        pub type StartFn;
+        pub static start: StartFn;
+    }
+}
+
+pub mod b {
+    #[repr(transparent)]
+    pub struct TransparentType(::a::StartFn);
+    extern "C" {
+        pub static start: TransparentType;
+    }
+}
+
+pub mod c {
+    #[repr(C)]
+    pub struct CType(u32, ::b::TransparentType);
+    extern "C" {
+        pub static start: CType;
+    }
+}
+
+fn main() {}