Auto merge of #59397 - kennytm:rollup, r=kennytm
Rollup of 7 pull requests Successful merges: - #59213 (Track changes to robots.txt) - #59239 (Remove inline assembly from hint::spin_loop) - #59251 (Use a valid name for graphviz graphs) - #59296 (Do not encode gensymed imports in metadata) - #59328 (Implement specialized nth_back() for Box and Windows.) - #59355 (Fix ICE with const generic param in struct) - #59377 (Correct minimum system LLVM version in tests)
This commit is contained in:
commit
0576ac109b
37 changed files with 233 additions and 74 deletions
19
src/doc/robots.txt
Normal file
19
src/doc/robots.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# NB: This file is not automatically deployed. After changes, it needs to be uploaded manually to doc.rust-lang.org
|
||||||
|
User-agent: *
|
||||||
|
Disallow: /0.3/
|
||||||
|
Disallow: /0.4/
|
||||||
|
Disallow: /0.5/
|
||||||
|
Disallow: /0.6/
|
||||||
|
Disallow: /0.7/
|
||||||
|
Disallow: /0.8/
|
||||||
|
Disallow: /0.9/
|
||||||
|
Disallow: /0.10/
|
||||||
|
Disallow: /0.11.0/
|
||||||
|
Disallow: /0.12.0/
|
||||||
|
Disallow: /1.0.0-alpha/
|
||||||
|
Disallow: /1.0.0-alpha.2/
|
||||||
|
Disallow: /1.0.0-beta/
|
||||||
|
Disallow: /1.0.0-beta.2/
|
||||||
|
Disallow: /1.0.0-beta.3/
|
||||||
|
Disallow: /1.0.0-beta.4/
|
||||||
|
Disallow: /1.0.0-beta.5/
|
|
@ -677,6 +677,9 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
|
||||||
fn next_back(&mut self) -> Option<I::Item> {
|
fn next_back(&mut self) -> Option<I::Item> {
|
||||||
(**self).next_back()
|
(**self).next_back()
|
||||||
}
|
}
|
||||||
|
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
|
||||||
|
(**self).nth_back(n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {
|
impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {
|
||||||
|
|
|
@ -115,6 +115,7 @@
|
||||||
#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
|
#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
|
||||||
#![feature(alloc_layout_extra)]
|
#![feature(alloc_layout_extra)]
|
||||||
#![feature(try_trait)]
|
#![feature(try_trait)]
|
||||||
|
#![feature(iter_nth_back)]
|
||||||
|
|
||||||
// Allow testing this library
|
// Allow testing this library
|
||||||
|
|
||||||
|
|
|
@ -62,13 +62,32 @@ pub unsafe fn unreachable_unchecked() -> ! {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
|
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
|
||||||
pub fn spin_loop() {
|
pub fn spin_loop() {
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(
|
||||||
unsafe {
|
all(
|
||||||
asm!("pause" ::: "memory" : "volatile");
|
any(target_arch = "x86", target_arch = "x86_64"),
|
||||||
|
target_feature = "sse2"
|
||||||
|
)
|
||||||
|
)] {
|
||||||
|
#[cfg(target_arch = "x86")] {
|
||||||
|
unsafe { crate::arch::x86::_mm_pause() };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")] {
|
||||||
|
unsafe { crate::arch::x86_64::_mm_pause() };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(
|
||||||
unsafe {
|
any(
|
||||||
asm!("yield" ::: "memory" : "volatile");
|
target_arch = "aarch64",
|
||||||
|
all(target_arch = "arm", target_feature = "v6")
|
||||||
|
)
|
||||||
|
)] {
|
||||||
|
#[cfg(target_arch = "aarch64")] {
|
||||||
|
unsafe { crate::arch::aarch64::__yield() };
|
||||||
|
}
|
||||||
|
#[cfg(target_arch = "arm")] {
|
||||||
|
unsafe { crate::arch::arm::__yield() };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3867,6 +3867,19 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||||
|
let (end, overflow) = self.v.len().overflowing_sub(n);
|
||||||
|
if end < self.size || overflow {
|
||||||
|
self.v = &[];
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let ret = &self.v[end-self.size..end];
|
||||||
|
self.v = &self.v[..end-1];
|
||||||
|
Some(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
|
@ -578,6 +578,19 @@ fn test_windows_nth() {
|
||||||
assert_eq!(c2.next(), None);
|
assert_eq!(c2.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_windows_nth_back() {
|
||||||
|
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||||
|
let mut c = v.windows(2);
|
||||||
|
assert_eq!(c.nth_back(2).unwrap()[0], 2);
|
||||||
|
assert_eq!(c.next_back().unwrap()[1], 2);
|
||||||
|
|
||||||
|
let v2: &[i32] = &[0, 1, 2, 3, 4];
|
||||||
|
let mut c2 = v2.windows(4);
|
||||||
|
assert_eq!(c2.nth_back(1).unwrap()[1], 1);
|
||||||
|
assert_eq!(c2.next_back(), None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_windows_last() {
|
fn test_windows_last() {
|
||||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||||
|
|
|
@ -1156,12 +1156,14 @@ fn prepare_union_metadata(
|
||||||
// Enums
|
// Enums
|
||||||
//=-----------------------------------------------------------------------------
|
//=-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// DWARF variant support is only available starting in LLVM 7.
|
// DWARF variant support is only available starting in LLVM 8.
|
||||||
// Although the earlier enum debug info output did not work properly
|
// Although the earlier enum debug info output did not work properly
|
||||||
// in all situations, it is better for the time being to continue to
|
// in all situations, it is better for the time being to continue to
|
||||||
// sometimes emit the old style rather than emit something completely
|
// sometimes emit the old style rather than emit something completely
|
||||||
// useless when rust is compiled against LLVM 6 or older. This
|
// useless when rust is compiled against LLVM 6 or older. LLVM 7
|
||||||
// function decides which representation will be emitted.
|
// contains an early version of the DWARF variant support, and will
|
||||||
|
// crash when handling the new debug info format. This function
|
||||||
|
// decides which representation will be emitted.
|
||||||
fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
|
fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
|
||||||
// On MSVC we have to use the fallback mode, because LLVM doesn't
|
// On MSVC we have to use the fallback mode, because LLVM doesn't
|
||||||
// lower variant parts to PDB.
|
// lower variant parts to PDB.
|
||||||
|
|
|
@ -633,10 +633,20 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
|
||||||
let body = tcx.hir().body(body_id);
|
let body = tcx.hir().body(body_id);
|
||||||
let cfg = cfg::CFG::new(tcx, &body);
|
let cfg = cfg::CFG::new(tcx, &body);
|
||||||
let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges;
|
let labelled_edges = mode != PpFlowGraphMode::UnlabelledEdges;
|
||||||
|
let hir_id = code.id();
|
||||||
|
// We have to disassemble the hir_id because name must be ASCII
|
||||||
|
// alphanumeric. This does not appear in the rendered graph, so it does not
|
||||||
|
// have to be user friendly.
|
||||||
|
let name = format!(
|
||||||
|
"hir_id_{}_{}_{}",
|
||||||
|
hir_id.owner.address_space().index(),
|
||||||
|
hir_id.owner.as_array_index(),
|
||||||
|
hir_id.local_id.index(),
|
||||||
|
);
|
||||||
let lcfg = LabelledCFG {
|
let lcfg = LabelledCFG {
|
||||||
tcx,
|
tcx,
|
||||||
cfg: &cfg,
|
cfg: &cfg,
|
||||||
name: format!("node_{}", code.id()),
|
name,
|
||||||
labelled_edges,
|
labelled_edges,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||||
let mut flow_inits = FlowAtLocation::new(do_dataflow(
|
let mut flow_inits = FlowAtLocation::new(do_dataflow(
|
||||||
tcx,
|
tcx,
|
||||||
mir,
|
mir,
|
||||||
id,
|
def_id,
|
||||||
&attributes,
|
&attributes,
|
||||||
&dead_unwinds,
|
&dead_unwinds,
|
||||||
MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|
MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|
||||||
|
@ -191,7 +191,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||||
let flow_borrows = FlowAtLocation::new(do_dataflow(
|
let flow_borrows = FlowAtLocation::new(do_dataflow(
|
||||||
tcx,
|
tcx,
|
||||||
mir,
|
mir,
|
||||||
id,
|
def_id,
|
||||||
&attributes,
|
&attributes,
|
||||||
&dead_unwinds,
|
&dead_unwinds,
|
||||||
Borrows::new(tcx, mir, regioncx.clone(), &borrow_set),
|
Borrows::new(tcx, mir, regioncx.clone(), &borrow_set),
|
||||||
|
@ -200,7 +200,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||||
let flow_uninits = FlowAtLocation::new(do_dataflow(
|
let flow_uninits = FlowAtLocation::new(do_dataflow(
|
||||||
tcx,
|
tcx,
|
||||||
mir,
|
mir,
|
||||||
id,
|
def_id,
|
||||||
&attributes,
|
&attributes,
|
||||||
&dead_unwinds,
|
&dead_unwinds,
|
||||||
MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
|
MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
|
||||||
|
@ -209,7 +209,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||||
let flow_ever_inits = FlowAtLocation::new(do_dataflow(
|
let flow_ever_inits = FlowAtLocation::new(do_dataflow(
|
||||||
tcx,
|
tcx,
|
||||||
mir,
|
mir,
|
||||||
id,
|
def_id,
|
||||||
&attributes,
|
&attributes,
|
||||||
&dead_unwinds,
|
&dead_unwinds,
|
||||||
EverInitializedPlaces::new(tcx, mir, &mdpe),
|
EverInitializedPlaces::new(tcx, mir, &mdpe),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Hook into libgraphviz for rendering dataflow graphs for MIR.
|
//! Hook into libgraphviz for rendering dataflow graphs for MIR.
|
||||||
|
|
||||||
use rustc::hir::HirId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::{BasicBlock, Mir};
|
use rustc::mir::{BasicBlock, Mir};
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
@ -8,13 +8,15 @@ use std::io;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::util::graphviz_safe_def_name;
|
||||||
|
|
||||||
use super::{BitDenotation, DataflowState};
|
use super::{BitDenotation, DataflowState};
|
||||||
use super::DataflowBuilder;
|
use super::DataflowBuilder;
|
||||||
use super::DebugFormatted;
|
use super::DebugFormatted;
|
||||||
|
|
||||||
pub trait MirWithFlowState<'tcx> {
|
pub trait MirWithFlowState<'tcx> {
|
||||||
type BD: BitDenotation<'tcx>;
|
type BD: BitDenotation<'tcx>;
|
||||||
fn hir_id(&self) -> HirId;
|
fn def_id(&self) -> DefId;
|
||||||
fn mir(&self) -> &Mir<'tcx>;
|
fn mir(&self) -> &Mir<'tcx>;
|
||||||
fn flow_state(&self) -> &DataflowState<'tcx, Self::BD>;
|
fn flow_state(&self) -> &DataflowState<'tcx, Self::BD>;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +25,7 @@ impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD>
|
||||||
where BD: BitDenotation<'tcx>
|
where BD: BitDenotation<'tcx>
|
||||||
{
|
{
|
||||||
type BD = BD;
|
type BD = BD;
|
||||||
fn hir_id(&self) -> HirId { self.hir_id }
|
fn def_id(&self) -> DefId { self.def_id }
|
||||||
fn mir(&self) -> &Mir<'tcx> { self.flow_state.mir() }
|
fn mir(&self) -> &Mir<'tcx> { self.flow_state.mir() }
|
||||||
fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { &self.flow_state.flow_state }
|
fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { &self.flow_state.flow_state }
|
||||||
}
|
}
|
||||||
|
@ -47,8 +49,8 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
|
||||||
let g = Graph { mbcx, phantom: PhantomData, render_idx };
|
let g = Graph { mbcx, phantom: PhantomData, render_idx };
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
dot::render(&g, &mut v)?;
|
dot::render(&g, &mut v)?;
|
||||||
debug!("print_borrowck_graph_to path: {} hir_id: {}",
|
debug!("print_borrowck_graph_to path: {} def_id: {:?}",
|
||||||
path.display(), mbcx.hir_id);
|
path.display(), mbcx.def_id);
|
||||||
fs::write(path, v)
|
fs::write(path, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +71,8 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
|
||||||
type Node = Node;
|
type Node = Node;
|
||||||
type Edge = Edge;
|
type Edge = Edge;
|
||||||
fn graph_id(&self) -> dot::Id<'_> {
|
fn graph_id(&self) -> dot::Id<'_> {
|
||||||
dot::Id::new(format!("graph_for_node_{}",
|
let name = graphviz_safe_def_name(self.mbcx.def_id());
|
||||||
self.mbcx.hir_id()))
|
dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap()
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_id(&self, n: &Node) -> dot::Id<'_> {
|
fn node_id(&self, n: &Node) -> dot::Id<'_> {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rustc_data_structures::bit_set::{BitSet, BitSetOperator, HybridBitSet};
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use rustc_data_structures::work_queue::WorkQueue;
|
use rustc_data_structures::work_queue::WorkQueue;
|
||||||
|
|
||||||
use rustc::hir::HirId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
|
use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
|
||||||
use rustc::mir::traversal;
|
use rustc::mir::traversal;
|
||||||
|
@ -39,7 +39,7 @@ pub(crate) struct DataflowBuilder<'a, 'tcx: 'a, BD>
|
||||||
where
|
where
|
||||||
BD: BitDenotation<'tcx>
|
BD: BitDenotation<'tcx>
|
||||||
{
|
{
|
||||||
hir_id: HirId,
|
def_id: DefId,
|
||||||
flow_state: DataflowAnalysis<'a, 'tcx, BD>,
|
flow_state: DataflowAnalysis<'a, 'tcx, BD>,
|
||||||
print_preflow_to: Option<String>,
|
print_preflow_to: Option<String>,
|
||||||
print_postflow_to: Option<String>,
|
print_postflow_to: Option<String>,
|
||||||
|
@ -117,7 +117,7 @@ pub struct MoveDataParamEnv<'gcx, 'tcx> {
|
||||||
|
|
||||||
pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
mir: &'a Mir<'tcx>,
|
mir: &'a Mir<'tcx>,
|
||||||
hir_id: HirId,
|
def_id: DefId,
|
||||||
attributes: &[ast::Attribute],
|
attributes: &[ast::Attribute],
|
||||||
dead_unwinds: &BitSet<BasicBlock>,
|
dead_unwinds: &BitSet<BasicBlock>,
|
||||||
bd: BD,
|
bd: BD,
|
||||||
|
@ -127,14 +127,14 @@ pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
P: Fn(&BD, BD::Idx) -> DebugFormatted
|
P: Fn(&BD, BD::Idx) -> DebugFormatted
|
||||||
{
|
{
|
||||||
let flow_state = DataflowAnalysis::new(mir, dead_unwinds, bd);
|
let flow_state = DataflowAnalysis::new(mir, dead_unwinds, bd);
|
||||||
flow_state.run(tcx, hir_id, attributes, p)
|
flow_state.run(tcx, def_id, attributes, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation<'tcx>
|
impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation<'tcx>
|
||||||
{
|
{
|
||||||
pub(crate) fn run<P>(self,
|
pub(crate) fn run<P>(self,
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
hir_id: HirId,
|
def_id: DefId,
|
||||||
attributes: &[ast::Attribute],
|
attributes: &[ast::Attribute],
|
||||||
p: P) -> DataflowResults<'tcx, BD>
|
p: P) -> DataflowResults<'tcx, BD>
|
||||||
where P: Fn(&BD, BD::Idx) -> DebugFormatted
|
where P: Fn(&BD, BD::Idx) -> DebugFormatted
|
||||||
|
@ -159,7 +159,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD
|
||||||
name_found(tcx.sess, attributes, "borrowck_graphviz_postflow");
|
name_found(tcx.sess, attributes, "borrowck_graphviz_postflow");
|
||||||
|
|
||||||
let mut mbcx = DataflowBuilder {
|
let mut mbcx = DataflowBuilder {
|
||||||
hir_id,
|
def_id,
|
||||||
print_preflow_to, print_postflow_to, flow_state: self,
|
print_preflow_to, print_postflow_to, flow_state: self,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ impl MirPass for ElaborateDrops {
|
||||||
{
|
{
|
||||||
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
|
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
|
||||||
|
|
||||||
let id = tcx.hir().as_local_hir_id(src.def_id()).unwrap();
|
let def_id = src.def_id();
|
||||||
let param_env = tcx.param_env(src.def_id()).with_reveal_all();
|
let param_env = tcx.param_env(src.def_id()).with_reveal_all();
|
||||||
let move_data = match MoveData::gather_moves(mir, tcx) {
|
let move_data = match MoveData::gather_moves(mir, tcx) {
|
||||||
Ok(move_data) => move_data,
|
Ok(move_data) => move_data,
|
||||||
|
@ -50,13 +50,13 @@ impl MirPass for ElaborateDrops {
|
||||||
move_data,
|
move_data,
|
||||||
param_env,
|
param_env,
|
||||||
};
|
};
|
||||||
let dead_unwinds = find_dead_unwinds(tcx, mir, id, &env);
|
let dead_unwinds = find_dead_unwinds(tcx, mir, def_id, &env);
|
||||||
let flow_inits =
|
let flow_inits =
|
||||||
do_dataflow(tcx, mir, id, &[], &dead_unwinds,
|
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds,
|
||||||
MaybeInitializedPlaces::new(tcx, mir, &env),
|
MaybeInitializedPlaces::new(tcx, mir, &env),
|
||||||
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
||||||
let flow_uninits =
|
let flow_uninits =
|
||||||
do_dataflow(tcx, mir, id, &[], &dead_unwinds,
|
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds,
|
||||||
MaybeUninitializedPlaces::new(tcx, mir, &env),
|
MaybeUninitializedPlaces::new(tcx, mir, &env),
|
||||||
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ impl MirPass for ElaborateDrops {
|
||||||
fn find_dead_unwinds<'a, 'tcx>(
|
fn find_dead_unwinds<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
id: hir::HirId,
|
def_id: hir::def_id::DefId,
|
||||||
env: &MoveDataParamEnv<'tcx, 'tcx>)
|
env: &MoveDataParamEnv<'tcx, 'tcx>)
|
||||||
-> BitSet<BasicBlock>
|
-> BitSet<BasicBlock>
|
||||||
{
|
{
|
||||||
|
@ -89,7 +89,7 @@ fn find_dead_unwinds<'a, 'tcx>(
|
||||||
// reach cleanup blocks, which can't have unwind edges themselves.
|
// reach cleanup blocks, which can't have unwind edges themselves.
|
||||||
let mut dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
let mut dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||||
let flow_inits =
|
let flow_inits =
|
||||||
do_dataflow(tcx, mir, id, &[], &dead_unwinds,
|
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds,
|
||||||
MaybeInitializedPlaces::new(tcx, mir, &env),
|
MaybeInitializedPlaces::new(tcx, mir, &env),
|
||||||
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
||||||
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
|
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
|
||||||
|
|
|
@ -390,13 +390,13 @@ fn locals_live_across_suspend_points(
|
||||||
FxHashMap<BasicBlock, liveness::LiveVarSet>,
|
FxHashMap<BasicBlock, liveness::LiveVarSet>,
|
||||||
) {
|
) {
|
||||||
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||||
let hir_id = tcx.hir().as_local_hir_id(source.def_id()).unwrap();
|
let def_id = source.def_id();
|
||||||
|
|
||||||
// Calculate when MIR locals have live storage. This gives us an upper bound of their
|
// Calculate when MIR locals have live storage. This gives us an upper bound of their
|
||||||
// lifetimes.
|
// lifetimes.
|
||||||
let storage_live_analysis = MaybeStorageLive::new(mir);
|
let storage_live_analysis = MaybeStorageLive::new(mir);
|
||||||
let storage_live =
|
let storage_live =
|
||||||
do_dataflow(tcx, mir, hir_id, &[], &dead_unwinds, storage_live_analysis,
|
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, storage_live_analysis,
|
||||||
|bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
|
|bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
|
||||||
|
|
||||||
// Find the MIR locals which do not use StorageLive/StorageDead statements.
|
// Find the MIR locals which do not use StorageLive/StorageDead statements.
|
||||||
|
@ -410,7 +410,7 @@ fn locals_live_across_suspend_points(
|
||||||
let borrowed_locals = if !movable {
|
let borrowed_locals = if !movable {
|
||||||
let analysis = HaveBeenBorrowedLocals::new(mir);
|
let analysis = HaveBeenBorrowedLocals::new(mir);
|
||||||
let result =
|
let result =
|
||||||
do_dataflow(tcx, mir, hir_id, &[], &dead_unwinds, analysis,
|
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, analysis,
|
||||||
|bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
|
|bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
|
||||||
Some((analysis, result))
|
Some((analysis, result))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use syntax::ast;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc::hir;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::{self, Mir, Location};
|
use rustc::mir::{self, Mir, Location};
|
||||||
use rustc_data_structures::bit_set::BitSet;
|
use rustc_data_structures::bit_set::BitSet;
|
||||||
use crate::transform::{MirPass, MirSource};
|
use crate::transform::{MirPass, MirSource};
|
||||||
|
@ -27,7 +27,6 @@ impl MirPass for SanityCheck {
|
||||||
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
src: MirSource<'tcx>, mir: &mut Mir<'tcx>) {
|
src: MirSource<'tcx>, mir: &mut Mir<'tcx>) {
|
||||||
let def_id = src.def_id();
|
let def_id = src.def_id();
|
||||||
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
|
||||||
if !tcx.has_attr(def_id, "rustc_mir") {
|
if !tcx.has_attr(def_id, "rustc_mir") {
|
||||||
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
|
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
|
||||||
return;
|
return;
|
||||||
|
@ -41,26 +40,26 @@ impl MirPass for SanityCheck {
|
||||||
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
||||||
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||||
let flow_inits =
|
let flow_inits =
|
||||||
do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds,
|
||||||
MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|
MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|
||||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
||||||
let flow_uninits =
|
let flow_uninits =
|
||||||
do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds,
|
||||||
MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
|
MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
|
||||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
||||||
let flow_def_inits =
|
let flow_def_inits =
|
||||||
do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds,
|
||||||
DefinitelyInitializedPlaces::new(tcx, mir, &mdpe),
|
DefinitelyInitializedPlaces::new(tcx, mir, &mdpe),
|
||||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
||||||
|
|
||||||
if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() {
|
if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() {
|
||||||
sanity_check_via_rustc_peek(tcx, mir, id, &attributes, &flow_inits);
|
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_inits);
|
||||||
}
|
}
|
||||||
if has_rustc_mir_with(&attributes, "rustc_peek_maybe_uninit").is_some() {
|
if has_rustc_mir_with(&attributes, "rustc_peek_maybe_uninit").is_some() {
|
||||||
sanity_check_via_rustc_peek(tcx, mir, id, &attributes, &flow_uninits);
|
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_uninits);
|
||||||
}
|
}
|
||||||
if has_rustc_mir_with(&attributes, "rustc_peek_definite_init").is_some() {
|
if has_rustc_mir_with(&attributes, "rustc_peek_definite_init").is_some() {
|
||||||
sanity_check_via_rustc_peek(tcx, mir, id, &attributes, &flow_def_inits);
|
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_def_inits);
|
||||||
}
|
}
|
||||||
if has_rustc_mir_with(&attributes, "stop_after_dataflow").is_some() {
|
if has_rustc_mir_with(&attributes, "stop_after_dataflow").is_some() {
|
||||||
tcx.sess.fatal("stop_after_dataflow ended compilation");
|
tcx.sess.fatal("stop_after_dataflow ended compilation");
|
||||||
|
@ -86,12 +85,12 @@ impl MirPass for SanityCheck {
|
||||||
/// errors are not intended to be used for unit tests.)
|
/// errors are not intended to be used for unit tests.)
|
||||||
pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
id: hir::HirId,
|
def_id: DefId,
|
||||||
_attributes: &[ast::Attribute],
|
_attributes: &[ast::Attribute],
|
||||||
results: &DataflowResults<'tcx, O>)
|
results: &DataflowResults<'tcx, O>)
|
||||||
where O: BitDenotation<'tcx, Idx=MovePathIndex> + HasMoveData<'tcx>
|
where O: BitDenotation<'tcx, Idx=MovePathIndex> + HasMoveData<'tcx>
|
||||||
{
|
{
|
||||||
debug!("sanity_check_via_rustc_peek id: {:?}", id);
|
debug!("sanity_check_via_rustc_peek def_id: {:?}", def_id);
|
||||||
// FIXME: this is not DRY. Figure out way to abstract this and
|
// FIXME: this is not DRY. Figure out way to abstract this and
|
||||||
// `dataflow::build_sets`. (But note it is doing non-standard
|
// `dataflow::build_sets`. (But note it is doing non-standard
|
||||||
// stuff, so such generalization may not be realistic.)
|
// stuff, so such generalization may not be realistic.)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
@ -20,6 +21,17 @@ pub fn write_mir_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so
|
||||||
|
// it does not have to be user friendly.
|
||||||
|
pub fn graphviz_safe_def_name(def_id: DefId) -> String {
|
||||||
|
format!(
|
||||||
|
"{}_{}_{}",
|
||||||
|
def_id.krate.index(),
|
||||||
|
def_id.index.address_space().index(),
|
||||||
|
def_id.index.as_array_index(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Write a graphviz DOT graph of the MIR.
|
/// Write a graphviz DOT graph of the MIR.
|
||||||
pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
|
@ -27,7 +39,7 @@ pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
||||||
w: &mut W) -> io::Result<()>
|
w: &mut W) -> io::Result<()>
|
||||||
where W: Write
|
where W: Write
|
||||||
{
|
{
|
||||||
writeln!(w, "digraph Mir_{} {{", tcx.hir().as_local_hir_id(def_id).unwrap())?;
|
writeln!(w, "digraph Mir_{} {{", graphviz_safe_def_name(def_id))?;
|
||||||
|
|
||||||
// Global graph properties
|
// Global graph properties
|
||||||
writeln!(w, r#" graph [fontname="monospace"];"#)?;
|
writeln!(w, r#" graph [fontname="monospace"];"#)?;
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub mod collect_writes;
|
||||||
|
|
||||||
pub use self::alignment::is_disaligned;
|
pub use self::alignment::is_disaligned;
|
||||||
pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere};
|
pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere};
|
||||||
pub use self::graphviz::{write_mir_graphviz};
|
pub use self::graphviz::{graphviz_safe_def_name, write_mir_graphviz};
|
||||||
pub use self::graphviz::write_node_label as write_graphviz_node_label;
|
pub use self::graphviz::write_node_label as write_graphviz_node_label;
|
||||||
|
|
||||||
/// If possible, suggest replacing `ref` with `ref mut`.
|
/// If possible, suggest replacing `ref` with `ref mut`.
|
||||||
|
|
|
@ -303,7 +303,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty groups `a::b::{}` are turned into synthetic `self` imports
|
// Empty groups `a::b::{}` are turned into synthetic `self` imports
|
||||||
// `a::b::c::{self as _}`, so that their prefixes are correctly
|
// `a::b::c::{self as __dummy}`, so that their prefixes are correctly
|
||||||
// resolved and checked for privacy/stability/etc.
|
// resolved and checked for privacy/stability/etc.
|
||||||
if items.is_empty() && !empty_for_self(&prefix) {
|
if items.is_empty() && !empty_for_self(&prefix) {
|
||||||
let new_span = prefix[prefix.len() - 1].ident.span;
|
let new_span = prefix[prefix.len() - 1].ident.span;
|
||||||
|
@ -312,7 +312,7 @@ impl<'a> Resolver<'a> {
|
||||||
Ident::new(keywords::SelfLower.name(), new_span)
|
Ident::new(keywords::SelfLower.name(), new_span)
|
||||||
),
|
),
|
||||||
kind: ast::UseTreeKind::Simple(
|
kind: ast::UseTreeKind::Simple(
|
||||||
Some(Ident::new(keywords::Underscore.name().gensymed(), new_span)),
|
Some(Ident::new(Name::gensym("__dummy"), new_span)),
|
||||||
ast::DUMMY_NODE_ID,
|
ast::DUMMY_NODE_ID,
|
||||||
ast::DUMMY_NODE_ID,
|
ast::DUMMY_NODE_ID,
|
||||||
),
|
),
|
||||||
|
|
|
@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
||||||
debug!("(resolving function) entering function");
|
debug!("(resolving function) entering function");
|
||||||
let (rib_kind, asyncness) = match function_kind {
|
let (rib_kind, asyncness) = match function_kind {
|
||||||
FnKind::ItemFn(_, ref header, ..) =>
|
FnKind::ItemFn(_, ref header, ..) =>
|
||||||
(ItemRibKind, header.asyncness.node),
|
(FnItemRibKind, header.asyncness.node),
|
||||||
FnKind::Method(_, ref sig, _, _) =>
|
FnKind::Method(_, ref sig, _, _) =>
|
||||||
(TraitOrImplItemRibKind, sig.header.asyncness.node),
|
(TraitOrImplItemRibKind, sig.header.asyncness.node),
|
||||||
FnKind::Closure(_) =>
|
FnKind::Closure(_) =>
|
||||||
|
@ -950,6 +950,10 @@ enum RibKind<'a> {
|
||||||
/// upvars).
|
/// upvars).
|
||||||
TraitOrImplItemRibKind,
|
TraitOrImplItemRibKind,
|
||||||
|
|
||||||
|
/// We passed through a function definition. Disallow upvars.
|
||||||
|
/// Permit only those const parameters that are specified in the function's generics.
|
||||||
|
FnItemRibKind,
|
||||||
|
|
||||||
/// We passed through an item scope. Disallow upvars.
|
/// We passed through an item scope. Disallow upvars.
|
||||||
ItemRibKind,
|
ItemRibKind,
|
||||||
|
|
||||||
|
@ -3863,7 +3867,7 @@ impl<'a> Resolver<'a> {
|
||||||
seen.insert(node_id, depth);
|
seen.insert(node_id, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemRibKind | TraitOrImplItemRibKind => {
|
ItemRibKind | FnItemRibKind | TraitOrImplItemRibKind => {
|
||||||
// This was an attempt to access an upvar inside a
|
// This was an attempt to access an upvar inside a
|
||||||
// named function item. This is not allowed, so we
|
// named function item. This is not allowed, so we
|
||||||
// report an error.
|
// report an error.
|
||||||
|
@ -3897,7 +3901,7 @@ impl<'a> Resolver<'a> {
|
||||||
ConstantItemRibKind => {
|
ConstantItemRibKind => {
|
||||||
// Nothing to do. Continue.
|
// Nothing to do. Continue.
|
||||||
}
|
}
|
||||||
ItemRibKind => {
|
ItemRibKind | FnItemRibKind => {
|
||||||
// This was an attempt to use a type parameter outside its scope.
|
// This was an attempt to use a type parameter outside its scope.
|
||||||
if record_used {
|
if record_used {
|
||||||
resolve_error(
|
resolve_error(
|
||||||
|
@ -3912,12 +3916,15 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Def::ConstParam(..) => {
|
Def::ConstParam(..) => {
|
||||||
// A const param is always declared in a signature, which is always followed by
|
let mut ribs = ribs.iter().peekable();
|
||||||
// some kind of function rib kind (specifically, ItemRibKind in the case of a
|
if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
|
||||||
// normal function), so we can skip the first rib as it will be guaranteed to
|
// When declaring const parameters inside function signatures, the first rib
|
||||||
// (spuriously) conflict with the const param.
|
// is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
|
||||||
for rib in &ribs[1..] {
|
// (spuriously) conflicting with the const param.
|
||||||
if let ItemRibKind = rib.kind {
|
ribs.next();
|
||||||
|
}
|
||||||
|
for rib in ribs {
|
||||||
|
if let ItemRibKind | FnItemRibKind = rib.kind {
|
||||||
// This was an attempt to use a const parameter outside its scope.
|
// This was an attempt to use a const parameter outside its scope.
|
||||||
if record_used {
|
if record_used {
|
||||||
resolve_error(
|
resolve_error(
|
||||||
|
|
|
@ -1295,9 +1295,11 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Filter away "empty import canaries" and ambiguous imports.
|
// Filter away ambiguous and gensymed imports. Gensymed imports
|
||||||
|
// (e.g. implicitly injected `std`) cannot be properly encoded in metadata,
|
||||||
|
// so they can cause name conflict errors downstream.
|
||||||
let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
|
let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
|
||||||
binding.vis != ty::Visibility::Invisible;
|
!(ident.name.is_gensymed() && ident.name != "_");
|
||||||
if is_good_import || binding.is_macro_def() {
|
if is_good_import || binding.is_macro_def() {
|
||||||
let def = binding.def();
|
let def = binding.def();
|
||||||
if def != Def::Err {
|
if def != Def::Err {
|
||||||
|
|
|
@ -179,6 +179,10 @@ impl Symbol {
|
||||||
with_interner(|interner| interner.gensymed(self))
|
with_interner(|interner| interner.gensymed(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_gensymed(self) -> bool {
|
||||||
|
with_interner(|interner| interner.is_gensymed(self))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_str(self) -> LocalInternedString {
|
pub fn as_str(self) -> LocalInternedString {
|
||||||
with_interner(|interner| unsafe {
|
with_interner(|interner| unsafe {
|
||||||
LocalInternedString {
|
LocalInternedString {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// min-system-llvm-version 7.0
|
// min-system-llvm-version 8.0
|
||||||
|
|
||||||
// compile-flags: -g -C no-prepopulate-passes
|
// compile-flags: -g -C no-prepopulate-passes
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// min-system-llvm-version 7.0
|
// min-system-llvm-version 8.0
|
||||||
|
|
||||||
// compile-flags: -g -C no-prepopulate-passes
|
// compile-flags: -g -C no-prepopulate-passes
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// min-system-llvm-version 7.0
|
// min-system-llvm-version 8.0
|
||||||
|
|
||||||
// compile-flags: -g -C no-prepopulate-passes
|
// compile-flags: -g -C no-prepopulate-passes
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// min-system-llvm-version 7.0
|
// min-system-llvm-version 8.0
|
||||||
|
|
||||||
// compile-flags: -g -C no-prepopulate-passes
|
// compile-flags: -g -C no-prepopulate-passes
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb or lldb that can read it.
|
// Require LLVM with DW_TAG_variant_part and a gdb or lldb that can read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
// rust-lldb
|
// rust-lldb
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// min-lldb-version: 310
|
// min-lldb-version: 310
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
|
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
|
|
||||||
// compile-flags:-g
|
// compile-flags:-g
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// min-lldb-version: 310
|
// min-lldb-version: 310
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
|
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
|
|
||||||
// compile-flags:-g
|
// compile-flags:-g
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
||||||
// read it.
|
// read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
// rust-lldb
|
// rust-lldb
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// ignore-lldb
|
// ignore-lldb
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
|
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
|
|
||||||
// compile-flags:-g
|
// compile-flags:-g
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
||||||
// read it.
|
// read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
// rust-lldb
|
// rust-lldb
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
||||||
// read it.
|
// read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
// rust-lldb
|
// rust-lldb
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
|
||||||
// read it.
|
// read it.
|
||||||
// min-system-llvm-version: 7.0
|
// min-system-llvm-version: 8.0
|
||||||
// min-gdb-version: 8.2
|
// min-gdb-version: 8.2
|
||||||
// rust-lldb
|
// rust-lldb
|
||||||
|
|
||||||
|
|
23
src/test/mir-opt/graphviz.rs
Normal file
23
src/test/mir-opt/graphviz.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Test graphviz output
|
||||||
|
// compile-flags: -Z dump-mir-graphviz
|
||||||
|
|
||||||
|
// ignore-tidy-linelength
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
// END RUST SOURCE
|
||||||
|
// START rustc.main.mir_map.0.dot
|
||||||
|
// digraph Mir_0_0_3 { // The name here MUST be an ASCII identifier.
|
||||||
|
// graph [fontname="monospace"];
|
||||||
|
// node [fontname="monospace"];
|
||||||
|
// edge [fontname="monospace"];
|
||||||
|
// label=<fn main() -> ()<br align="left"/>>;
|
||||||
|
// bb0 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = ()<br/></td></tr><tr><td align="left">goto</td></tr></table>
|
||||||
|
// >];
|
||||||
|
// bb1 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table>
|
||||||
|
// >];
|
||||||
|
// bb2 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left">return</td></tr></table>
|
||||||
|
// >];
|
||||||
|
// bb0 -> bb2 [label=""];
|
||||||
|
// }
|
||||||
|
// END rustc.main.mir_map.0.dot
|
|
@ -0,0 +1,6 @@
|
||||||
|
#![feature(const_generics)]
|
||||||
|
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
|
||||||
|
struct S<const C: u8>(C); //~ ERROR expected type, found const parameter
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,15 @@
|
||||||
|
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
--> $DIR/struct-with-invalid-const-param.rs:1:12
|
||||||
|
|
|
||||||
|
LL | #![feature(const_generics)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0573]: expected type, found const parameter `C`
|
||||||
|
--> $DIR/struct-with-invalid-const-param.rs:4:23
|
||||||
|
|
|
||||||
|
LL | struct S<const C: u8>(C);
|
||||||
|
| ^ help: a struct with a similar name exists: `S`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0573`.
|
3
src/test/ui/imports/auxiliary/gensymed.rs
Normal file
3
src/test/ui/imports/auxiliary/gensymed.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
mod std {}
|
7
src/test/ui/imports/gensymed.rs
Normal file
7
src/test/ui/imports/gensymed.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// compile-pass
|
||||||
|
// edition:2018
|
||||||
|
// aux-build:gensymed.rs
|
||||||
|
|
||||||
|
extern crate gensymed;
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue