Auto merge of #55433 - kennytm:rollup, r=kennytm
Rollup of 11 pull requests Successful merges: - #55148 (Implement FromStr for PathBuf) - #55185 (path suggestions in Rust 2018 should point out the change in semantics) - #55191 (Fix sub-variant doc display) - #55199 (Impl items have generics) - #55244 (Don't rerun MIR passes when inlining) - #55252 (Add MaybeUninit::new) - #55257 (Allow extern statics with an extern type) - #55389 (Remove unnecessary mut in iterator.find_map documentation example, R…) - #55406 (Update string.rs) - #55412 (Fix an ICE in the min_const_fn analysis) - #55421 (Add ManuallyDrop::take)
This commit is contained in:
commit
d492c6792c
37 changed files with 384 additions and 169 deletions
|
@ -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');
|
||||
/// }
|
||||
///
|
||||
|
|
|
@ -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));
|
||||
/// ```
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -973,6 +973,26 @@ impl<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.
|
||||
|
|
|
@ -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<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 @@ 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,
|
||||
|
|
|
@ -251,25 +251,17 @@ impl PrintContext {
|
|||
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 @@ 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 |
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<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
|
||||
|
|
|
@ -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<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,
|
||||
&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,
|
||||
&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"),
|
||||
];
|
||||
&add_call_guards::CriticalCallEdges,
|
||||
&dump_mir::Marker("PreCodegen"),
|
||||
]);
|
||||
tcx.alloc_mir(mir)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,7 +26,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
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 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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(¬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<String>)> {
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
});
|
||||
|
|
|
@ -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}: {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}: {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)?;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<String> for 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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
15
src/test/ui/consts/single_variant_match_ice.rs
Normal file
15
src/test/ui/consts/single_variant_match_ice.rs
Normal file
|
@ -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() {}
|
8
src/test/ui/consts/single_variant_match_ice.stderr
Normal file
8
src/test/ui/consts/single_variant_match_ice.stderr
Normal file
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
11
src/test/ui/issues/issue-50411.rs
Normal file
11
src/test/ui/issues/issue-50411.rs
Normal file
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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!();
|
||||
|
|
|
@ -53,9 +53,9 @@ mod m {
|
|||
<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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
37
src/test/ui/static/static-extern-type.rs
Normal file
37
src/test/ui/static/static-extern-type.rs
Normal file
|
@ -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() {}
|
Loading…
Add table
Add a link
Reference in a new issue