Auto merge of #51082 - kennytm:rollup, r=kennytm
Rollup of 11 pull requests Successful merges: - #50987 (Underline multiple suggested replacements in the same line) - #51014 (Add documentation about env! second argument) - #51034 (Remove unused lowering field and method) - #51047 (Use AllFacts from polonius-engine) - #51048 (Add more missing examples for Formatter) - #51056 (Mention and use `Once::new` instead of `ONCE_INIT`) - #51059 (What does an expression look like, that consists only of special characters?) - #51065 (Update nomicon link in transmute docs) - #51067 (Add inner links in documentation) - #51070 (Fail typecheck if we encounter a bogus break) - #51073 (Rename TokenStream::empty to TokenStream::new) Failed merges:
This commit is contained in:
commit
7a0e6a837f
@ -1441,6 +1441,11 @@ name = "pkg-config"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "polonius-engine"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
version = "0.1.1"
|
||||
@ -1763,6 +1768,7 @@ dependencies = [
|
||||
"jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"polonius-engine 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc_macro 0.0.0",
|
||||
"rustc_apfloat 0.0.0",
|
||||
"rustc_data_structures 0.0.0",
|
||||
@ -2135,6 +2141,7 @@ dependencies = [
|
||||
"graphviz 0.0.0",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"polonius-engine 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc 0.0.0",
|
||||
"rustc_apfloat 0.0.0",
|
||||
"rustc_data_structures 0.0.0",
|
||||
@ -3134,6 +3141,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
|
||||
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
|
||||
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
||||
"checksum polonius-engine 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6201ffe79e3da53bd065fbec2a9b391e5a0dc21038b39bb300612ddc658eb7ee"
|
||||
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
|
||||
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
|
||||
|
@ -340,7 +340,8 @@
|
||||
//!
|
||||
//! ## Fill/Alignment
|
||||
//!
|
||||
//! The fill character is provided normally in conjunction with the `width`
|
||||
//! The fill character is provided normally in conjunction with the
|
||||
//! [`width`](#width)
|
||||
//! parameter. This indicates that if the value being formatted is smaller than
|
||||
//! `width` some extra characters will be printed around it. The extra
|
||||
//! characters are specified by `fill`, and the alignment can be one of the
|
||||
@ -388,7 +389,8 @@
|
||||
//! padding specified by fill/alignment will be used to take up the required
|
||||
//! space.
|
||||
//!
|
||||
//! The default fill/alignment for non-numerics is a space and left-aligned. The
|
||||
//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
|
||||
//! left-aligned. The
|
||||
//! defaults for numeric formatters is also a space but with right-alignment. If
|
||||
//! the `0` flag is specified for numerics, then the implicit fill character is
|
||||
//! `0`.
|
||||
|
@ -1202,6 +1202,23 @@ impl<'a> Formatter<'a> {
|
||||
/// is longer than this length
|
||||
///
|
||||
/// Notably this function ignores the `flag` parameters.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl fmt::Display for Foo {
|
||||
/// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// formatter.pad("Foo")
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(&format!("{:<4}", Foo), "Foo ");
|
||||
/// assert_eq!(&format!("{:0>4}", Foo), "0Foo");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn pad(&mut self, s: &str) -> Result {
|
||||
// Make sure there's a fast path up front
|
||||
@ -1368,7 +1385,7 @@ impl<'a> Formatter<'a> {
|
||||
self.buf.write_str(data)
|
||||
}
|
||||
|
||||
/// Writes some formatted information into this instance
|
||||
/// Writes some formatted information into this instance.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn write_fmt(&mut self, fmt: Arguments) -> Result {
|
||||
write(self.buf, fmt)
|
||||
@ -1381,11 +1398,69 @@ impl<'a> Formatter<'a> {
|
||||
or `sign_aware_zero_pad` methods instead")]
|
||||
pub fn flags(&self) -> u32 { self.flags }
|
||||
|
||||
/// Character used as 'fill' whenever there is alignment
|
||||
/// Character used as 'fill' whenever there is alignment.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl fmt::Display for Foo {
|
||||
/// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// let c = formatter.fill();
|
||||
/// if let Some(width) = formatter.width() {
|
||||
/// for _ in 0..width {
|
||||
/// write!(formatter, "{}", c)?;
|
||||
/// }
|
||||
/// Ok(())
|
||||
/// } else {
|
||||
/// write!(formatter, "{}", c)
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // We set alignment to the left with ">".
|
||||
/// assert_eq!(&format!("{:G>3}", Foo), "GGG");
|
||||
/// assert_eq!(&format!("{:t>6}", Foo), "tttttt");
|
||||
/// ```
|
||||
#[stable(feature = "fmt_flags", since = "1.5.0")]
|
||||
pub fn fill(&self) -> char { self.fill }
|
||||
|
||||
/// Flag indicating what form of alignment was requested
|
||||
/// Flag indicating what form of alignment was requested.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(fmt_flags_align)]
|
||||
///
|
||||
/// extern crate core;
|
||||
///
|
||||
/// use std::fmt;
|
||||
/// use core::fmt::Alignment;
|
||||
///
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl fmt::Display for Foo {
|
||||
/// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// let s = match formatter.align() {
|
||||
/// Alignment::Left => "left",
|
||||
/// Alignment::Right => "right",
|
||||
/// Alignment::Center => "center",
|
||||
/// Alignment::Unknown => "into the void",
|
||||
/// };
|
||||
/// write!(formatter, "{}", s)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(&format!("{:<}", Foo), "left");
|
||||
/// assert_eq!(&format!("{:>}", Foo), "right");
|
||||
/// assert_eq!(&format!("{:^}", Foo), "center");
|
||||
/// assert_eq!(&format!("{}", Foo), "into the void");
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "fmt_flags_align", reason = "method was just created",
|
||||
issue = "27726")]
|
||||
pub fn align(&self) -> Alignment {
|
||||
|
@ -717,7 +717,7 @@ extern "rust-intrinsic" {
|
||||
/// Reinterprets the bits of a value of one type as another type.
|
||||
///
|
||||
/// Both types must have the same size. Neither the original, nor the result,
|
||||
/// may be an [invalid value](../../nomicon/meet-safe-and-unsafe.html).
|
||||
/// may be an [invalid value](../../nomicon/what-unsafe-does.html).
|
||||
///
|
||||
/// `transmute` is semantically equivalent to a bitwise move of one type
|
||||
/// into another. It copies the bits from the source value into the
|
||||
|
@ -93,7 +93,7 @@ impl !Sync for LexError {}
|
||||
impl TokenStream {
|
||||
/// Returns an empty `TokenStream` containing no token trees.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
pub fn empty() -> TokenStream {
|
||||
pub fn new() -> TokenStream {
|
||||
TokenStream(tokenstream::TokenStream::empty())
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ macro_rules! quote_tree {
|
||||
}
|
||||
|
||||
macro_rules! quote {
|
||||
() => { TokenStream::empty() };
|
||||
() => { TokenStream::new() };
|
||||
($($t:tt)*) => {
|
||||
[$(quote_tree!($t),)*].iter()
|
||||
.cloned()
|
||||
@ -104,7 +104,7 @@ impl<T: Quote> Quote for Option<T> {
|
||||
impl Quote for TokenStream {
|
||||
fn quote(self) -> TokenStream {
|
||||
if self.is_empty() {
|
||||
return quote!(::TokenStream::empty());
|
||||
return quote!(::TokenStream::new());
|
||||
}
|
||||
let mut after_dollar = false;
|
||||
let tokens = self.into_iter().filter_map(|tree| {
|
||||
|
@ -16,6 +16,7 @@ graphviz = { path = "../libgraphviz" }
|
||||
jobserver = "0.1"
|
||||
lazy_static = "1.0.0"
|
||||
log = { version = "0.4", features = ["release_max_level_info", "std"] }
|
||||
polonius-engine = "0.1.1"
|
||||
proc_macro = { path = "../libproc_macro" }
|
||||
rustc_apfloat = { path = "../librustc_apfloat" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
|
@ -82,10 +82,6 @@ pub struct LoweringContext<'a> {
|
||||
|
||||
cstore: &'a CrateStore,
|
||||
|
||||
// As we walk the AST we must keep track of the current 'parent' def id (in
|
||||
// the form of a DefIndex) so that if we create a new node which introduces
|
||||
// a definition, then we can properly create the def id.
|
||||
parent_def: Option<DefIndex>,
|
||||
resolver: &'a mut Resolver,
|
||||
name_map: FxHashMap<Ident, Name>,
|
||||
|
||||
@ -205,7 +201,6 @@ pub fn lower_crate(
|
||||
crate_root: std_inject::injected_crate_name(),
|
||||
sess,
|
||||
cstore,
|
||||
parent_def: None,
|
||||
resolver,
|
||||
name_map: FxHashMap(),
|
||||
items: BTreeMap::new(),
|
||||
@ -885,22 +880,6 @@ impl<'a> LoweringContext<'a> {
|
||||
result
|
||||
}
|
||||
|
||||
fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut LoweringContext) -> T,
|
||||
{
|
||||
let old_def = self.parent_def;
|
||||
self.parent_def = {
|
||||
let defs = self.resolver.definitions();
|
||||
Some(defs.opt_def_index(parent_id).unwrap())
|
||||
};
|
||||
|
||||
let result = f(self);
|
||||
|
||||
self.parent_def = old_def;
|
||||
result
|
||||
}
|
||||
|
||||
fn def_key(&mut self, id: DefId) -> DefKey {
|
||||
if id.is_local() {
|
||||
self.resolver.definitions().def_key(id.index)
|
||||
@ -2461,74 +2440,72 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
|
||||
self.with_parent_def(i.id, |this| {
|
||||
let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
|
||||
let trait_item_def_id = this.resolver.definitions().local_def_id(node_id);
|
||||
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
|
||||
let trait_item_def_id = self.resolver.definitions().local_def_id(node_id);
|
||||
|
||||
let (generics, node) = match i.node {
|
||||
TraitItemKind::Const(ref ty, ref default) => (
|
||||
this.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::TraitItemKind::Const(
|
||||
this.lower_ty(ty, ImplTraitContext::Disallowed),
|
||||
default
|
||||
.as_ref()
|
||||
.map(|x| this.lower_body(None, |this| this.lower_expr(x))),
|
||||
),
|
||||
let (generics, node) = match i.node {
|
||||
TraitItemKind::Const(ref ty, ref default) => (
|
||||
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::TraitItemKind::Const(
|
||||
self.lower_ty(ty, ImplTraitContext::Disallowed),
|
||||
default
|
||||
.as_ref()
|
||||
.map(|x| self.lower_body(None, |this| this.lower_expr(x))),
|
||||
),
|
||||
TraitItemKind::Method(ref sig, None) => {
|
||||
let names = this.lower_fn_args_to_names(&sig.decl);
|
||||
this.add_in_band_defs(
|
||||
&i.generics,
|
||||
trait_item_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::TraitItemKind::Method(
|
||||
this.lower_method_sig(sig, trait_item_def_id, false),
|
||||
hir::TraitMethod::Required(names),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
TraitItemKind::Method(ref sig, Some(ref body)) => {
|
||||
let body_id = this.lower_body(Some(&sig.decl), |this| {
|
||||
let body = this.lower_block(body, false);
|
||||
this.expr_block(body, ThinVec::new())
|
||||
});
|
||||
|
||||
this.add_in_band_defs(
|
||||
&i.generics,
|
||||
trait_item_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::TraitItemKind::Method(
|
||||
this.lower_method_sig(sig, trait_item_def_id, false),
|
||||
hir::TraitMethod::Provided(body_id),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
TraitItemKind::Type(ref bounds, ref default) => (
|
||||
this.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::TraitItemKind::Type(
|
||||
this.lower_bounds(bounds, ImplTraitContext::Disallowed),
|
||||
default
|
||||
.as_ref()
|
||||
.map(|x| this.lower_ty(x, ImplTraitContext::Disallowed)),
|
||||
),
|
||||
),
|
||||
TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
|
||||
};
|
||||
|
||||
hir::TraitItem {
|
||||
id: node_id,
|
||||
hir_id,
|
||||
name: this.lower_ident(i.ident),
|
||||
attrs: this.lower_attrs(&i.attrs),
|
||||
generics,
|
||||
node,
|
||||
span: i.span,
|
||||
),
|
||||
TraitItemKind::Method(ref sig, None) => {
|
||||
let names = self.lower_fn_args_to_names(&sig.decl);
|
||||
self.add_in_band_defs(
|
||||
&i.generics,
|
||||
trait_item_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::TraitItemKind::Method(
|
||||
this.lower_method_sig(sig, trait_item_def_id, false),
|
||||
hir::TraitMethod::Required(names),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
TraitItemKind::Method(ref sig, Some(ref body)) => {
|
||||
let body_id = self.lower_body(Some(&sig.decl), |this| {
|
||||
let body = this.lower_block(body, false);
|
||||
this.expr_block(body, ThinVec::new())
|
||||
});
|
||||
|
||||
self.add_in_band_defs(
|
||||
&i.generics,
|
||||
trait_item_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::TraitItemKind::Method(
|
||||
this.lower_method_sig(sig, trait_item_def_id, false),
|
||||
hir::TraitMethod::Provided(body_id),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
TraitItemKind::Type(ref bounds, ref default) => (
|
||||
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::TraitItemKind::Type(
|
||||
self.lower_bounds(bounds, ImplTraitContext::Disallowed),
|
||||
default
|
||||
.as_ref()
|
||||
.map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
|
||||
),
|
||||
),
|
||||
TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
|
||||
};
|
||||
|
||||
hir::TraitItem {
|
||||
id: node_id,
|
||||
hir_id,
|
||||
name: self.lower_ident(i.ident),
|
||||
attrs: self.lower_attrs(&i.attrs),
|
||||
generics,
|
||||
node,
|
||||
span: i.span,
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
|
||||
@ -2557,63 +2534,61 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
|
||||
self.with_parent_def(i.id, |this| {
|
||||
let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
|
||||
let impl_item_def_id = this.resolver.definitions().local_def_id(node_id);
|
||||
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
|
||||
let impl_item_def_id = self.resolver.definitions().local_def_id(node_id);
|
||||
|
||||
let (generics, node) = match i.node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
let body_id = this.lower_body(None, |this| this.lower_expr(expr));
|
||||
(
|
||||
this.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::ImplItemKind::Const(
|
||||
this.lower_ty(ty, ImplTraitContext::Disallowed),
|
||||
body_id,
|
||||
),
|
||||
)
|
||||
}
|
||||
ImplItemKind::Method(ref sig, ref body) => {
|
||||
let body_id = this.lower_body(Some(&sig.decl), |this| {
|
||||
let body = this.lower_block(body, false);
|
||||
this.expr_block(body, ThinVec::new())
|
||||
});
|
||||
let impl_trait_return_allow = !this.is_in_trait_impl;
|
||||
|
||||
this.add_in_band_defs(
|
||||
&i.generics,
|
||||
impl_item_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::ImplItemKind::Method(
|
||||
this.lower_method_sig(
|
||||
sig,
|
||||
impl_item_def_id,
|
||||
impl_trait_return_allow,
|
||||
),
|
||||
body_id,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
ImplItemKind::Type(ref ty) => (
|
||||
this.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::ImplItemKind::Type(this.lower_ty(ty, ImplTraitContext::Disallowed)),
|
||||
),
|
||||
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
|
||||
};
|
||||
|
||||
hir::ImplItem {
|
||||
id: node_id,
|
||||
hir_id,
|
||||
name: this.lower_ident(i.ident),
|
||||
attrs: this.lower_attrs(&i.attrs),
|
||||
generics,
|
||||
vis: this.lower_visibility(&i.vis, None),
|
||||
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
|
||||
node,
|
||||
span: i.span,
|
||||
let (generics, node) = match i.node {
|
||||
ImplItemKind::Const(ref ty, ref expr) => {
|
||||
let body_id = self.lower_body(None, |this| this.lower_expr(expr));
|
||||
(
|
||||
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::ImplItemKind::Const(
|
||||
self.lower_ty(ty, ImplTraitContext::Disallowed),
|
||||
body_id,
|
||||
),
|
||||
)
|
||||
}
|
||||
})
|
||||
ImplItemKind::Method(ref sig, ref body) => {
|
||||
let body_id = self.lower_body(Some(&sig.decl), |this| {
|
||||
let body = this.lower_block(body, false);
|
||||
this.expr_block(body, ThinVec::new())
|
||||
});
|
||||
let impl_trait_return_allow = !self.is_in_trait_impl;
|
||||
|
||||
self.add_in_band_defs(
|
||||
&i.generics,
|
||||
impl_item_def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
hir::ImplItemKind::Method(
|
||||
this.lower_method_sig(
|
||||
sig,
|
||||
impl_item_def_id,
|
||||
impl_trait_return_allow,
|
||||
),
|
||||
body_id,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
ImplItemKind::Type(ref ty) => (
|
||||
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
|
||||
hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::Disallowed)),
|
||||
),
|
||||
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
|
||||
};
|
||||
|
||||
hir::ImplItem {
|
||||
id: node_id,
|
||||
hir_id,
|
||||
name: self.lower_ident(i.ident),
|
||||
attrs: self.lower_attrs(&i.attrs),
|
||||
generics,
|
||||
vis: self.lower_visibility(&i.vis, None),
|
||||
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
|
||||
node,
|
||||
span: i.span,
|
||||
}
|
||||
|
||||
// [1] since `default impl` is not yet implemented, this is always true in impls
|
||||
}
|
||||
@ -2689,9 +2664,7 @@ impl<'a> LoweringContext<'a> {
|
||||
return None;
|
||||
}
|
||||
|
||||
let node = self.with_parent_def(i.id, |this| {
|
||||
this.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node)
|
||||
});
|
||||
let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node);
|
||||
|
||||
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
|
||||
|
||||
@ -2707,40 +2680,38 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
|
||||
self.with_parent_def(i.id, |this| {
|
||||
let node_id = this.lower_node_id(i.id).node_id;
|
||||
let def_id = this.resolver.definitions().local_def_id(node_id);
|
||||
hir::ForeignItem {
|
||||
id: node_id,
|
||||
name: i.ident.name,
|
||||
attrs: this.lower_attrs(&i.attrs),
|
||||
node: match i.node {
|
||||
ForeignItemKind::Fn(ref fdec, ref generics) => {
|
||||
let (generics, (fn_dec, fn_args)) = this.add_in_band_defs(
|
||||
generics,
|
||||
def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
(
|
||||
// Disallow impl Trait in foreign items
|
||||
this.lower_fn_decl(fdec, None, false),
|
||||
this.lower_fn_args_to_names(fdec),
|
||||
)
|
||||
},
|
||||
);
|
||||
let node_id = self.lower_node_id(i.id).node_id;
|
||||
let def_id = self.resolver.definitions().local_def_id(node_id);
|
||||
hir::ForeignItem {
|
||||
id: node_id,
|
||||
name: i.ident.name,
|
||||
attrs: self.lower_attrs(&i.attrs),
|
||||
node: match i.node {
|
||||
ForeignItemKind::Fn(ref fdec, ref generics) => {
|
||||
let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
|
||||
generics,
|
||||
def_id,
|
||||
AnonymousLifetimeMode::PassThrough,
|
||||
|this| {
|
||||
(
|
||||
// Disallow impl Trait in foreign items
|
||||
this.lower_fn_decl(fdec, None, false),
|
||||
this.lower_fn_args_to_names(fdec),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
hir::ForeignItemFn(fn_dec, fn_args, generics)
|
||||
}
|
||||
ForeignItemKind::Static(ref t, m) => {
|
||||
hir::ForeignItemStatic(this.lower_ty(t, ImplTraitContext::Disallowed), m)
|
||||
}
|
||||
ForeignItemKind::Ty => hir::ForeignItemType,
|
||||
ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
|
||||
},
|
||||
vis: this.lower_visibility(&i.vis, None),
|
||||
span: i.span,
|
||||
}
|
||||
})
|
||||
hir::ForeignItemFn(fn_dec, fn_args, generics)
|
||||
}
|
||||
ForeignItemKind::Static(ref t, m) => {
|
||||
hir::ForeignItemStatic(self.lower_ty(t, ImplTraitContext::Disallowed), m)
|
||||
}
|
||||
ForeignItemKind::Ty => hir::ForeignItemType,
|
||||
ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
|
||||
},
|
||||
vis: self.lower_visibility(&i.vis, None),
|
||||
span: i.span,
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_method_sig(
|
||||
@ -3064,46 +3035,44 @@ impl<'a> LoweringContext<'a> {
|
||||
),
|
||||
ExprKind::Closure(capture_clause, movability, ref decl, ref body, fn_decl_span) => {
|
||||
self.with_new_scopes(|this| {
|
||||
this.with_parent_def(e.id, |this| {
|
||||
let mut is_generator = false;
|
||||
let body_id = this.lower_body(Some(decl), |this| {
|
||||
let e = this.lower_expr(body);
|
||||
is_generator = this.is_generator;
|
||||
e
|
||||
});
|
||||
let generator_option = if is_generator {
|
||||
if !decl.inputs.is_empty() {
|
||||
span_err!(
|
||||
this.sess,
|
||||
fn_decl_span,
|
||||
E0628,
|
||||
"generators cannot have explicit arguments"
|
||||
);
|
||||
this.sess.abort_if_errors();
|
||||
}
|
||||
Some(match movability {
|
||||
Movability::Movable => hir::GeneratorMovability::Movable,
|
||||
Movability::Static => hir::GeneratorMovability::Static,
|
||||
})
|
||||
} else {
|
||||
if movability == Movability::Static {
|
||||
span_err!(
|
||||
this.sess,
|
||||
fn_decl_span,
|
||||
E0906,
|
||||
"closures cannot be static"
|
||||
);
|
||||
}
|
||||
None
|
||||
};
|
||||
hir::ExprClosure(
|
||||
this.lower_capture_clause(capture_clause),
|
||||
this.lower_fn_decl(decl, None, false),
|
||||
body_id,
|
||||
fn_decl_span,
|
||||
generator_option,
|
||||
)
|
||||
})
|
||||
let mut is_generator = false;
|
||||
let body_id = this.lower_body(Some(decl), |this| {
|
||||
let e = this.lower_expr(body);
|
||||
is_generator = this.is_generator;
|
||||
e
|
||||
});
|
||||
let generator_option = if is_generator {
|
||||
if !decl.inputs.is_empty() {
|
||||
span_err!(
|
||||
this.sess,
|
||||
fn_decl_span,
|
||||
E0628,
|
||||
"generators cannot have explicit arguments"
|
||||
);
|
||||
this.sess.abort_if_errors();
|
||||
}
|
||||
Some(match movability {
|
||||
Movability::Movable => hir::GeneratorMovability::Movable,
|
||||
Movability::Static => hir::GeneratorMovability::Static,
|
||||
})
|
||||
} else {
|
||||
if movability == Movability::Static {
|
||||
span_err!(
|
||||
this.sess,
|
||||
fn_decl_span,
|
||||
E0906,
|
||||
"closures cannot be static"
|
||||
);
|
||||
}
|
||||
None
|
||||
};
|
||||
hir::ExprClosure(
|
||||
this.lower_capture_clause(capture_clause),
|
||||
this.lower_fn_decl(decl, None, false),
|
||||
body_id,
|
||||
fn_decl_span,
|
||||
generator_option,
|
||||
)
|
||||
})
|
||||
}
|
||||
ExprKind::Block(ref blk, opt_label) => {
|
||||
|
@ -81,6 +81,7 @@ extern crate graphviz;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
#[cfg(windows)]
|
||||
extern crate libc;
|
||||
extern crate polonius_engine;
|
||||
extern crate rustc_target;
|
||||
#[macro_use] extern crate rustc_data_structures;
|
||||
extern crate serialize;
|
||||
|
@ -14,6 +14,7 @@ use hir::def_id::DefId;
|
||||
|
||||
use middle::const_val::ConstVal;
|
||||
use middle::region;
|
||||
use polonius_engine::Atom;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use ty::subst::{Substs, Subst, Kind, UnpackedKind};
|
||||
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
|
||||
@ -1169,6 +1170,24 @@ newtype_index!(RegionVid
|
||||
DEBUG_FORMAT = custom,
|
||||
});
|
||||
|
||||
impl Atom for RegionVid {
|
||||
fn index(self) -> usize {
|
||||
Idx::index(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for RegionVid {
|
||||
fn from(i: usize) -> RegionVid {
|
||||
RegionVid::new(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RegionVid> for usize {
|
||||
fn from(vid: RegionVid) -> usize {
|
||||
Idx::index(vid)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub enum InferTy {
|
||||
TyVar(TyVid),
|
||||
|
@ -1215,19 +1215,20 @@ impl EmitterWriter {
|
||||
|
||||
let mut row_num = 2;
|
||||
for &(ref complete, ref parts) in suggestions.iter().take(MAX_SUGGESTIONS) {
|
||||
let show_underline = parts.len() == 1
|
||||
&& complete.lines().count() == 1
|
||||
&& parts[0].snippet.trim() != complete.trim();
|
||||
// Only show underline if the suggestion spans a single line and doesn't cover the
|
||||
// entirety of the code output. If you have multiple replacements in the same line
|
||||
// of code, show the underline.
|
||||
let show_underline = !(parts.len() == 1
|
||||
&& parts[0].snippet.trim() == complete.trim())
|
||||
&& complete.lines().count() == 1;
|
||||
|
||||
let lines = cm.span_to_lines(parts[0].span).unwrap();
|
||||
|
||||
assert!(!lines.lines.is_empty());
|
||||
|
||||
let span_start_pos = cm.lookup_char_pos(parts[0].span.lo());
|
||||
let line_start = span_start_pos.line;
|
||||
let line_start = cm.lookup_char_pos(parts[0].span.lo()).line;
|
||||
draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
|
||||
let mut line_pos = 0;
|
||||
// Only show underline if there's a single suggestion and it is a single line
|
||||
let mut lines = complete.lines();
|
||||
for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) {
|
||||
// Print the span column to avoid confusion
|
||||
@ -1241,22 +1242,55 @@ impl EmitterWriter {
|
||||
line_pos += 1;
|
||||
row_num += 1;
|
||||
}
|
||||
|
||||
// This offset and the ones below need to be signed to account for replacement code
|
||||
// that is shorter than the original code.
|
||||
let mut offset: isize = 0;
|
||||
// Only show an underline in the suggestions if the suggestion is not the
|
||||
// entirety of the code being shown and the displayed code is not multiline.
|
||||
if show_underline {
|
||||
draw_col_separator(&mut buffer, row_num, max_line_num_len + 1);
|
||||
let start = parts[0].snippet.len() - parts[0].snippet.trim_left().len();
|
||||
// account for substitutions containing unicode characters
|
||||
let sub_len = parts[0].snippet.trim().chars().fold(0, |acc, ch| {
|
||||
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
|
||||
});
|
||||
let underline_start = span_start_pos.col_display + start;
|
||||
let underline_end = span_start_pos.col_display + start + sub_len;
|
||||
for p in underline_start..underline_end {
|
||||
buffer.putc(row_num,
|
||||
max_line_num_len + 3 + p,
|
||||
'^',
|
||||
Style::UnderlinePrimary);
|
||||
for part in parts {
|
||||
let span_start_pos = cm.lookup_char_pos(part.span.lo()).col_display;
|
||||
let span_end_pos = cm.lookup_char_pos(part.span.hi()).col_display;
|
||||
|
||||
// Do not underline the leading...
|
||||
let start = part.snippet.len()
|
||||
.saturating_sub(part.snippet.trim_left().len());
|
||||
// ...or trailing spaces. Account for substitutions containing unicode
|
||||
// characters.
|
||||
let sub_len = part.snippet.trim().chars().fold(0, |acc, ch| {
|
||||
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
|
||||
});
|
||||
|
||||
let underline_start = (span_start_pos + start) as isize + offset;
|
||||
let underline_end = (span_start_pos + start + sub_len) as isize + offset;
|
||||
for p in underline_start..underline_end {
|
||||
buffer.putc(row_num,
|
||||
max_line_num_len + 3 + p as usize,
|
||||
'^',
|
||||
Style::UnderlinePrimary);
|
||||
}
|
||||
// underline removals too
|
||||
if underline_start == underline_end {
|
||||
for p in underline_start-1..underline_start+1 {
|
||||
buffer.putc(row_num,
|
||||
max_line_num_len + 3 + p as usize,
|
||||
'-',
|
||||
Style::UnderlineSecondary);
|
||||
}
|
||||
}
|
||||
|
||||
// length of the code after substitution
|
||||
let full_sub_len = part.snippet.chars().fold(0, |acc, ch| {
|
||||
acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) as isize
|
||||
});
|
||||
|
||||
// length of the code to be substituted
|
||||
let snippet_len = (span_end_pos - span_start_pos) as isize;
|
||||
// For multiple substitutions, use the position *after* the previous
|
||||
// substitutions have happened.
|
||||
offset += full_sub_len - snippet_len;
|
||||
}
|
||||
row_num += 1;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ bitflags = "1.0"
|
||||
graphviz = { path = "../libgraphviz" }
|
||||
log = "0.4"
|
||||
log_settings = "0.1.1"
|
||||
polonius-engine = "0.1.1"
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
|
@ -10,41 +10,28 @@
|
||||
|
||||
use borrow_check::location::{LocationIndex, LocationTable};
|
||||
use dataflow::indexes::BorrowIndex;
|
||||
use polonius_engine::AllFacts as PoloniusAllFacts;
|
||||
use polonius_engine::Atom;
|
||||
use rustc::ty::RegionVid;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::error::Error;
|
||||
use std::fmt::Debug;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
/// The "facts" which are the basis of the NLL borrow analysis.
|
||||
#[derive(Default)]
|
||||
crate struct AllFacts {
|
||||
// `borrow_region(R, B, P)` -- the region R may refer to data from borrow B
|
||||
// starting at the point P (this is usually the point *after* a borrow rvalue)
|
||||
crate borrow_region: Vec<(RegionVid, BorrowIndex, LocationIndex)>,
|
||||
crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex>;
|
||||
|
||||
// universal_region(R) -- this is a "free region" within fn body
|
||||
crate universal_region: Vec<RegionVid>,
|
||||
|
||||
// `cfg_edge(P,Q)` for each edge P -> Q in the control flow
|
||||
crate cfg_edge: Vec<(LocationIndex, LocationIndex)>,
|
||||
|
||||
// `killed(B,P)` when some prefix of the path borrowed at B is assigned at point P
|
||||
crate killed: Vec<(BorrowIndex, LocationIndex)>,
|
||||
|
||||
// `outlives(R1, R2, P)` when we require `R1@P: R2@P`
|
||||
crate outlives: Vec<(RegionVid, RegionVid, LocationIndex)>,
|
||||
|
||||
// `region_live_at(R, P)` when the region R appears in a live variable at P
|
||||
crate region_live_at: Vec<(RegionVid, LocationIndex)>,
|
||||
|
||||
// `invalidates(P, B)` when the borrow B is invalidated at point P
|
||||
crate invalidates: Vec<(LocationIndex, BorrowIndex)>,
|
||||
crate trait AllFactsExt {
|
||||
fn write_to_dir(
|
||||
&self,
|
||||
dir: impl AsRef<Path>,
|
||||
location_table: &LocationTable,
|
||||
) -> Result<(), Box<dyn Error>>;
|
||||
}
|
||||
|
||||
impl AllFacts {
|
||||
crate fn write_to_dir(
|
||||
impl AllFactsExt for AllFacts {
|
||||
fn write_to_dir(
|
||||
&self,
|
||||
dir: impl AsRef<Path>,
|
||||
location_table: &LocationTable,
|
||||
@ -79,6 +66,42 @@ impl AllFacts {
|
||||
}
|
||||
}
|
||||
|
||||
impl Atom for BorrowIndex {
|
||||
fn index(self) -> usize {
|
||||
Idx::index(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for BorrowIndex {
|
||||
fn from(i: usize) -> BorrowIndex {
|
||||
BorrowIndex::new(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BorrowIndex> for usize {
|
||||
fn from(vid: BorrowIndex) -> usize {
|
||||
Idx::index(vid)
|
||||
}
|
||||
}
|
||||
|
||||
impl Atom for LocationIndex {
|
||||
fn index(self) -> usize {
|
||||
Idx::index(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for LocationIndex {
|
||||
fn from(i: usize) -> LocationIndex {
|
||||
LocationIndex::new(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LocationIndex> for usize {
|
||||
fn from(vid: LocationIndex) -> usize {
|
||||
Idx::index(vid)
|
||||
}
|
||||
}
|
||||
|
||||
struct FactWriter<'w> {
|
||||
location_table: &'w LocationTable,
|
||||
dir: &'w Path,
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
use borrow_check::borrow_set::BorrowSet;
|
||||
use borrow_check::location::LocationTable;
|
||||
use borrow_check::nll::facts::AllFactsExt;
|
||||
use dataflow::move_paths::MoveData;
|
||||
use dataflow::FlowAtLocation;
|
||||
use dataflow::MaybeInitializedPlaces;
|
||||
|
@ -34,7 +34,7 @@ pub(crate) mod indexes {
|
||||
|
||||
macro_rules! new_index {
|
||||
($Index:ident, $debug_name:expr) => {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct $Index(NonZeroUsize);
|
||||
|
||||
impl Idx for $Index {
|
||||
|
@ -39,6 +39,7 @@ extern crate arena;
|
||||
extern crate bitflags;
|
||||
#[macro_use] extern crate log;
|
||||
extern crate graphviz as dot;
|
||||
extern crate polonius_engine;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
#[macro_use] extern crate rustc_data_structures;
|
||||
|
@ -777,7 +777,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let new_generics_span = tcx
|
||||
.sess
|
||||
.codemap()
|
||||
.generate_fn_name_span(impl_m.span)?
|
||||
.generate_fn_name_span(impl_span)?
|
||||
.shrink_to_hi();
|
||||
// in case there are generics, just replace them
|
||||
let generics_span = impl_m
|
||||
|
@ -3764,6 +3764,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
ctxt.may_break = true;
|
||||
|
||||
// the type of a `break` is always `!`, since it diverges
|
||||
tcx.types.never
|
||||
} else {
|
||||
// Otherwise, we failed to find the enclosing loop;
|
||||
// this can only happen if the `break` was not
|
||||
@ -3784,10 +3787,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
// There was an error, make typecheck fail
|
||||
tcx.types.err
|
||||
}
|
||||
|
||||
// the type of a `break` is always `!`, since it diverges
|
||||
tcx.types.never
|
||||
}
|
||||
hir::ExprAgain(_) => { tcx.types.never }
|
||||
hir::ExprRet(ref expr_opt) => {
|
||||
|
@ -364,7 +364,6 @@ pub mod builtin {
|
||||
///
|
||||
/// let s = fmt::format(format_args!("hello {}", "world"));
|
||||
/// assert_eq!(s, format!("hello {}", "world"));
|
||||
///
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[macro_export]
|
||||
@ -379,7 +378,7 @@ pub mod builtin {
|
||||
/// compile time, yielding an expression of type `&'static str`.
|
||||
///
|
||||
/// If the environment variable is not defined, then a compilation error
|
||||
/// will be emitted. To not emit a compile error, use the [`option_env!`]
|
||||
/// will be emitted. To not emit a compile error, use the [`option_env!`]
|
||||
/// macro instead.
|
||||
///
|
||||
/// [`option_env!`]: ../std/macro.option_env.html
|
||||
@ -390,6 +389,20 @@ pub mod builtin {
|
||||
/// let path: &'static str = env!("PATH");
|
||||
/// println!("the $PATH variable at the time of compiling was: {}", path);
|
||||
/// ```
|
||||
///
|
||||
/// You can customize the error message by passing a string as the second
|
||||
/// parameter:
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// let doc: &'static str = env!("documentation", "what's that?!");
|
||||
/// ```
|
||||
///
|
||||
/// If the `documentation` environment variable is not defined, you'll get
|
||||
/// the following error:
|
||||
///
|
||||
/// ```text
|
||||
/// error: what's that?!
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[macro_export]
|
||||
macro_rules! env {
|
||||
|
@ -73,16 +73,17 @@ use thread::{self, Thread};
|
||||
/// A synchronization primitive which can be used to run a one-time global
|
||||
/// initialization. Useful for one-time initialization for FFI or related
|
||||
/// functionality. This type can only be constructed with the [`ONCE_INIT`]
|
||||
/// value.
|
||||
/// value or the equivalent [`Once::new`] constructor.
|
||||
///
|
||||
/// [`ONCE_INIT`]: constant.ONCE_INIT.html
|
||||
/// [`Once::new`]: struct.Once.html#method.new
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::sync::{Once, ONCE_INIT};
|
||||
/// use std::sync::Once;
|
||||
///
|
||||
/// static START: Once = ONCE_INIT;
|
||||
/// static START: Once = Once::new();
|
||||
///
|
||||
/// START.call_once(|| {
|
||||
/// // run initialization here
|
||||
@ -180,10 +181,10 @@ impl Once {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::sync::{Once, ONCE_INIT};
|
||||
/// use std::sync::Once;
|
||||
///
|
||||
/// static mut VAL: usize = 0;
|
||||
/// static INIT: Once = ONCE_INIT;
|
||||
/// static INIT: Once = Once::new();
|
||||
///
|
||||
/// // Accessing a `static mut` is unsafe much of the time, but if we do so
|
||||
/// // in a synchronized fashion (e.g. write once or read all) then we're
|
||||
@ -248,10 +249,10 @@ impl Once {
|
||||
/// ```
|
||||
/// #![feature(once_poison)]
|
||||
///
|
||||
/// use std::sync::{Once, ONCE_INIT};
|
||||
/// use std::sync::Once;
|
||||
/// use std::thread;
|
||||
///
|
||||
/// static INIT: Once = ONCE_INIT;
|
||||
/// static INIT: Once = Once::new();
|
||||
///
|
||||
/// // poison the once
|
||||
/// let handle = thread::spawn(|| {
|
||||
@ -431,10 +432,10 @@ impl OnceState {
|
||||
/// ```
|
||||
/// #![feature(once_poison)]
|
||||
///
|
||||
/// use std::sync::{Once, ONCE_INIT};
|
||||
/// use std::sync::Once;
|
||||
/// use std::thread;
|
||||
///
|
||||
/// static INIT: Once = ONCE_INIT;
|
||||
/// static INIT: Once = Once::new();
|
||||
///
|
||||
/// // poison the once
|
||||
/// let handle = thread::spawn(|| {
|
||||
@ -452,9 +453,9 @@ impl OnceState {
|
||||
/// ```
|
||||
/// #![feature(once_poison)]
|
||||
///
|
||||
/// use std::sync::{Once, ONCE_INIT};
|
||||
/// use std::sync::Once;
|
||||
///
|
||||
/// static INIT: Once = ONCE_INIT;
|
||||
/// static INIT: Once = Once::new();
|
||||
///
|
||||
/// INIT.call_once_force(|state| {
|
||||
/// assert!(!state.poisoned());
|
||||
|
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
fn foo() -> bool {
|
||||
//~^ ERROR E0308
|
||||
break true; //~ ERROR E0268
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ pub fn assert1(_a: TokenStream, b: TokenStream) -> TokenStream {
|
||||
#[proc_macro_derive(Foo, attributes(foo))]
|
||||
pub fn assert2(a: TokenStream) -> TokenStream {
|
||||
assert_eq(a, "pub struct MyStructc { _a: i32, }".parse().unwrap());
|
||||
TokenStream::empty()
|
||||
TokenStream::new()
|
||||
}
|
||||
|
||||
fn assert_eq(a: TokenStream, b: TokenStream) {
|
||||
|
@ -20,13 +20,13 @@ use proc_macro::*;
|
||||
#[proc_macro]
|
||||
pub fn tokens(input: TokenStream) -> TokenStream {
|
||||
assert_nothing_joint(input);
|
||||
TokenStream::empty()
|
||||
TokenStream::new()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn nothing(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
assert_nothing_joint(input);
|
||||
TokenStream::empty()
|
||||
TokenStream::new()
|
||||
}
|
||||
|
||||
fn assert_nothing_joint(s: TokenStream) {
|
||||
|
@ -112,6 +112,12 @@ fn union() {
|
||||
union union<'union> { union: &'union union<'union>, }
|
||||
}
|
||||
|
||||
fn special_characters() {
|
||||
let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
|
||||
;
|
||||
assert!(!val);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
strange();
|
||||
funny();
|
||||
@ -125,4 +131,5 @@ pub fn main() {
|
||||
you_eight();
|
||||
fishy();
|
||||
union();
|
||||
special_characters();
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ fn parse(input: TokenStream) -> Result<(), Diagnostic> {
|
||||
pub fn three_equals(input: TokenStream) -> TokenStream {
|
||||
if let Err(diag) = parse(input) {
|
||||
diag.emit();
|
||||
return TokenStream::empty();
|
||||
return TokenStream::new();
|
||||
}
|
||||
|
||||
"3".parse().unwrap()
|
||||
|
@ -9,7 +9,7 @@ LL | fn foo<U: Debug>(&self, _: &U) { }
|
||||
help: try removing the generic parameter and using `impl Trait` instead
|
||||
|
|
||||
LL | fn foo(&self, _: &impl Debug) { }
|
||||
|
|
||||
| -- ^^^^^^^^^^
|
||||
|
||||
error[E0643]: method `bar` has incompatible signature for trait
|
||||
--> $DIR/impl-generic-mismatch.rs:27:23
|
||||
@ -21,12 +21,8 @@ LL | fn bar(&self, _: &impl Debug) { }
|
||||
| ^^^^^^^^^^ expected generic parameter, found `impl Trait`
|
||||
help: try changing the `impl Trait` argument to a generic parameter
|
||||
|
|
||||
LL | fn bar<U: Debug><U: Debug>(&self, _: &U);
|
||||
LL | }
|
||||
LL |
|
||||
LL | impl Bar for () {
|
||||
LL | fn bar(&self, _: &U) { }
|
||||
|
|
||||
LL | fn bar<U: Debug>(&self, _: &U) { }
|
||||
| ^^^^^^^^^^ ^
|
||||
|
||||
error[E0643]: method `hash` has incompatible signature for trait
|
||||
--> $DIR/impl-generic-mismatch.rs:38:33
|
||||
|
16
src/test/ui/issue-50576.rs
Normal file
16
src/test/ui/issue-50576.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// 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.
|
||||
|
||||
fn main() {
|
||||
|bool: [u8; break 'L]| 0;
|
||||
//~^ ERROR [E0426]
|
||||
//~| ERROR [E0268]
|
||||
Vec::<[u8; break]>::new(); //~ ERROR [E0268]
|
||||
}
|
22
src/test/ui/issue-50576.stderr
Normal file
22
src/test/ui/issue-50576.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0426]: use of undeclared label `'L`
|
||||
--> $DIR/issue-50576.rs:12:23
|
||||
|
|
||||
LL | |bool: [u8; break 'L]| 0;
|
||||
| ^^ undeclared label `'L`
|
||||
|
||||
error[E0268]: `break` outside of loop
|
||||
--> $DIR/issue-50576.rs:12:17
|
||||
|
|
||||
LL | |bool: [u8; break 'L]| 0;
|
||||
| ^^^^^^^^ cannot break outside of a loop
|
||||
|
||||
error[E0268]: `break` outside of loop
|
||||
--> $DIR/issue-50576.rs:15:16
|
||||
|
|
||||
LL | Vec::<[u8; break]>::new(); //~ ERROR [E0268]
|
||||
| ^^^^^ cannot break outside of a loop
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors occurred: E0268, E0426.
|
||||
For more information about an error, try `rustc --explain E0268`.
|
13
src/test/ui/issue-50581.rs
Normal file
13
src/test/ui/issue-50581.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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.
|
||||
|
||||
fn main() {
|
||||
|_: [u8; break]| (); //~ ERROR [E0268]
|
||||
}
|
9
src/test/ui/issue-50581.stderr
Normal file
9
src/test/ui/issue-50581.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0268]: `break` outside of loop
|
||||
--> $DIR/issue-50581.rs:12:14
|
||||
|
|
||||
LL | |_: [u8; break]| (); //~ ERROR [E0268]
|
||||
| ^^^^^ cannot break outside of a loop
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0268`.
|
@ -96,6 +96,7 @@ static WHITELIST: &'static [Crate] = &[
|
||||
Crate("owning_ref"),
|
||||
Crate("parking_lot"),
|
||||
Crate("parking_lot_core"),
|
||||
Crate("polonius-engine"),
|
||||
Crate("quick-error"),
|
||||
Crate("rand"),
|
||||
Crate("redox_syscall"),
|
||||
|
Loading…
Reference in New Issue
Block a user