diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index ab3f8fc270720..ff3587d5d8730 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -413,7 +413,7 @@ impl String { /// /// // These are all done without reallocating... /// let cap = s.capacity(); - /// for i in 0..10 { + /// for _ in 0..10 { /// s.push('a'); /// } /// diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 5b6d9e2033caa..2903c370df898 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1857,7 +1857,7 @@ pub trait Iterator { /// ``` /// 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)); /// ``` diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4156b1bec92a0..06727d8292d36 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -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)] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 27ee9556bd089..22016e8cf4174 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -973,6 +973,26 @@ impl ManuallyDrop { pub fn into_inner(slot: ManuallyDrop) -> 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 { + ManuallyDrop::into_inner(ptr::read(slot)) + } } impl ManuallyDrop { @@ -1021,6 +1041,15 @@ pub union MaybeUninit { } impl MaybeUninit { + /// 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 { + 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. diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 952783a91b2ed..4fea07011ccfb 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -69,6 +69,24 @@ impl<'tcx> HasLocalDecls<'tcx> for Mir<'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>, + /// 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, @@ -151,6 +176,7 @@ impl<'tcx> Mir<'tcx> { ); 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 @@ impl_stable_hash_for!(enum self::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 @@ CloneTypeFoldableAndLiftImpls! { BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> { + phase, basic_blocks, source_scopes, source_scope_local_data, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 709b844526529..abdd7fd8d40bf 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -251,25 +251,17 @@ impl PrintContext { fn parameterized(&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 @@ impl PrintContext { DefPathData::AssocTypeInImpl(_) | DefPathData::AssocExistentialInImpl(_) | DefPathData::Trait(_) | + DefPathData::Impl | DefPathData::TypeNs(_) => { break; } @@ -292,7 +285,6 @@ impl PrintContext { } DefPathData::CrateRoot | DefPathData::Misc | - DefPathData::Impl | DefPathData::Module(_) | DefPathData::MacroDef(_) | DefPathData::ClosureExpr | diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 362fbc4b1355b..d92001704285a 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -612,6 +612,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; diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index f7043487c51a6..cfccb950e8276 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -184,7 +184,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { } crate fn borrows(&self) -> &IndexVec> { &self.borrow_set.borrows } - pub fn scope_tree(&self) -> &Lrc { &self.scope_tree } pub fn location(&self, idx: BorrowIndex) -> &Location { &self.borrow_set.borrows[idx].reserve_location diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index da4bd780eb4fa..c19145636e6da 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -724,20 +724,6 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation } } } - - pub fn new_from_sets(mir: &'a Mir<'tcx>, - dead_unwinds: &'a BitSet, - sets: AllSets, - 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 diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index d18836999dccf..46c73c27fe10d 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -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 @@ pub trait MirPass { 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> { // 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, + ©_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) } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 52c557b83d591..6ab68789c027b 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -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 diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index def67923322aa..50ab8ef9c7be7 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -26,7 +26,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { span: Span, path: Vec, parent_scope: &ParentScope<'b>, - ) -> Option> { + ) -> Option<(Vec, Option)> { 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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { span: Span, mut path: Vec, parent_scope: &ParentScope<'b>, - ) -> Option> { + ) -> Option<(Vec, Option)> { // 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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { span: Span, mut path: Vec, parent_scope: &ParentScope<'b>, - ) -> Option> { + ) -> Option<(Vec, Option)> { // 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 \ + ".to_string() + ), + )) } else { None } @@ -113,13 +120,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { span: Span, mut path: Vec, parent_scope: &ParentScope<'b>, - ) -> Option> { + ) -> Option<(Vec, Option)> { // 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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { span: Span, mut path: Vec, parent_scope: &ParentScope<'b>, - ) -> Option> { + ) -> Option<(Vec, Option)> { // 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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}", name, path, result); if let PathResult::Module(..) = result { - return Some(path) + return Some((path, None)); } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 3ca0a9f7f1b97..359640ccda2b1 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -707,7 +707,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } }); - } 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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { &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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } - fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>, - span: Option) { + fn throw_unresolved_import_error( + &self, + error_vec: Vec<(Span, String, String, Option)>, + span: Option, + ) { 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)| elem.0) + .collect() + ); + + let note: Option = error_vec.clone().into_iter() + .filter_map(|elem: (Span, String, String, Option)| elem.3) + .last(); + let path_vec: Vec = error_vec.clone().into_iter() - .map(|elem: (Span, String, String)| { format!("`{}`", elem.1) }) + .map(|elem: (Span, String, String, Option)| 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(¬e); + } err.emit(); } @@ -945,7 +963,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } // 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)> { self.current_module = directive.parent_scope.module; let ImportDirective { ref module_path, span, .. } = *directive; @@ -969,15 +990,16 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { 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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { 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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } }; - Some((span, msg)) + Some((span, msg, None)) } else { // `resolve_ident_in_module` reported a privacy error. self.import_dummy_binding(directive); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 9990d2ee2b676..ea84e874b1a5b 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -13,7 +13,7 @@ use constrained_type_params::{identify_constrained_type_params, Parameter}; 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 }); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 8b35ede4a02c0..0fc2473725a16 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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, "", + write!(w, "", id = variant_id)?; - write!(w, "

Fields of {name}

\n - ", name = variant.name.as_ref().unwrap())?; + write!(w, "

Fields of {name}

", + 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, "
")?; } } - write!(w, "
\ - ", + write!(w, "\ + \ + ", id = id, ns_id = ns_id, f = field.name.as_ref().unwrap(), t = *ty)?; document(w, cx, field)?; - write!(w, "
")?; + write!(w, "
")?; } render_stability_since(w, variant, it)?; } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 9d1a5c3837830..02229b82b8ac3 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1886,7 +1886,7 @@ 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")) { @@ -2094,15 +2094,13 @@ } 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) { @@ -2127,6 +2125,8 @@ if (hideItemDeclarations === false) { extraClass = 'collapsed'; } + } else if (hasClass(e, "sub-variant")) { + otherMessage = ' Show fields'; } else if (hasClass(e, "non-exhaustive")) { otherMessage = ' This '; if (hasClass(e, "non-exhaustive-struct")) { @@ -2150,7 +2150,10 @@ 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'); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index c0951d9f8401e..8bcb828a5ade1 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -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 { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index ca8be75fab5be..a153456370c6f 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -87,6 +87,8 @@ use io; 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 @@ impl From for PathBuf { } } +#[stable(feature = "path_from_str", since = "1.26.0")] +impl FromStr for PathBuf { + type Err = ParseError; + + fn from_str(s: &str) -> Result { + Ok(PathBuf::from(s)) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl> iter::FromIterator

for PathBuf { fn from_iter>(iter: I) -> PathBuf { diff --git a/src/test/mir-opt/end_region_4.rs b/src/test/mir-opt/end_region_4.rs index 359ed07a9c095..3d15f20bd05f3 100644 --- a/src/test/mir-opt/end_region_4.rs +++ b/src/test/mir-opt/end_region_4.rs @@ -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; diff --git a/src/test/mir-opt/end_region_5.rs b/src/test/mir-opt/end_region_5.rs index 3b632e198cd66..06d1fbabe1616 100644 --- a/src/test/mir-opt/end_region_5.rs +++ b/src/test/mir-opt/end_region_5.rs @@ -37,7 +37,7 @@ fn foo(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); diff --git a/src/test/mir-opt/end_region_6.rs b/src/test/mir-opt/end_region_6.rs index 03c7de02ec111..d0db23e6de0ee 100644 --- a/src/test/mir-opt/end_region_6.rs +++ b/src/test/mir-opt/end_region_6.rs @@ -37,7 +37,7 @@ fn foo(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); diff --git a/src/test/mir-opt/end_region_7.rs b/src/test/mir-opt/end_region_7.rs index 56e3e0aa6f7a9..c7df440ebe2f3 100644 --- a/src/test/mir-opt/end_region_7.rs +++ b/src/test/mir-opt/end_region_7.rs @@ -36,7 +36,7 @@ fn foo(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 }; diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs index 0a54dcaa0d33f..9f2a9c3b72e8b 100644 --- a/src/test/mir-opt/end_region_8.rs +++ b/src/test/mir-opt/end_region_8.rs @@ -39,7 +39,7 @@ fn foo(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; diff --git a/src/test/mir-opt/end_region_destruction_extents_1.rs b/src/test/mir-opt/end_region_destruction_extents_1.rs index a5107d304386f..eb381dfc5521f 100644 --- a/src/test/mir-opt/end_region_destruction_extents_1.rs +++ b/src/test/mir-opt/end_region_destruction_extents_1.rs @@ -79,16 +79,16 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // 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 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // 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); diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs index 9441c6f4085a2..1fe29a29e2318 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned.rs +++ b/src/test/mir-opt/packed-struct-drop-aligned.rs @@ -42,7 +42,7 @@ impl Drop for Droppy { // 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 index 0000000000000..67a41bc5dc4ad --- /dev/null +++ b/src/test/ui/consts/single_variant_match_ice.rs @@ -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 index 0000000000000..a0222b0d489a4 --- /dev/null +++ b/src/test/ui/consts/single_variant_match_ice.stderr @@ -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 + diff --git a/src/test/ui/issues/issue-21554.stderr b/src/test/ui/issues/issue-21554.stderr index be7762f1aa245..104970ea448aa 100644 --- a/src/test/ui/issues/issue-21554.stderr +++ b/src/test/ui/issues/issue-21554.stderr @@ -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; diff --git a/src/test/ui/issues/issue-35241.stderr b/src/test/ui/issues/issue-35241.stderr index 42bf0aae5b12c..4404f88de311b 100644 --- a/src/test/ui/issues/issue-35241.stderr +++ b/src/test/ui/issues/issue-35241.stderr @@ -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 index 0000000000000..1ba47d3b932ef --- /dev/null +++ b/src/test/ui/issues/issue-50411.rs @@ -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(); +} diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index 6d72b6044aebe..0a297e58574f7 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -144,11 +144,11 @@ note: required by `check` LL | fn check(_: 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) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -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/privacy/private-inferred-type-3.rs b/src/test/ui/privacy/private-inferred-type-3.rs index 0c393f02323ec..5151f624b8d98 100644 --- a/src/test/ui/privacy/private-inferred-type-3.rs +++ b/src/test/ui/privacy/private-inferred-type-3.rs @@ -14,8 +14,8 @@ // error-pattern:static `PRIV_STATIC` is private // error-pattern:type `ext::PrivEnum` is private // error-pattern:type `fn() {::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) {>::priv_method}` is private #![feature(decl_macro)] diff --git a/src/test/ui/privacy/private-inferred-type-3.stderr b/src/test/ui/privacy/private-inferred-type-3.stderr index 3c37a7ee1e8d2..590ff76b375f2 100644 --- a/src/test/ui/privacy/private-inferred-type-3.stderr +++ b/src/test/ui/privacy/private-inferred-type-3.stderr @@ -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!(); diff --git a/src/test/ui/privacy/private-inferred-type.rs b/src/test/ui/privacy/private-inferred-type.rs index 3ca8b1eb2ed3a..58e17b24394a1 100644 --- a/src/test/ui/privacy/private-inferred-type.rs +++ b/src/test/ui/privacy/private-inferred-type.rs @@ -53,9 +53,9 @@ mod m { ::method; //~ ERROR type `fn() {::method}` is private ::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) {>::priv_method}` is private } diff --git a/src/test/ui/privacy/private-inferred-type.stderr b/src/test/ui/privacy/private-inferred-type.stderr index abbe43fe384cb..1ab281cfc2515 100644 --- a/src/test/ui/privacy/private-inferred-type.stderr +++ b/src/test/ui/privacy/private-inferred-type.stderr @@ -115,7 +115,7 @@ LL | ::method; //~ ERROR type `fn() { 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; diff --git a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr index 97bf748881f29..2293f4b001749 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr @@ -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 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 index 0000000000000..72e2853b9f038 --- /dev/null +++ b/src/test/ui/static/static-extern-type.rs @@ -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 or the MIT license +// , 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() {}