Auto merge of #54146 - kennytm:rollup, r=kennytm
Rollup of 15 pull requests Successful merges: - #52514 (Fix a few AMDGPU related issues) - #53703 (Document .0 to unpack integer from Wrapping) - #53777 (Implemented map_or_else for Result<T, E>) - #54031 (A few cleanups and minor improvements to rustc_passes) - #54046 (Update documentation for fill_buf in std::io::BufRead) - #54064 (`&CStr`, not `CStr`, is the counterpart of `&str`) - #54072 (Stabilization change for mod.rs) - #54073 (docs: Use dollar sign for all bash prompts) - #54074 (simplify ordering for Kind) - #54085 (Remove documentation about proc_macro being bare-bones) - #54087 (rustdoc: Remove generated blanket impls from trait pages) - #54106 (Reexport CheckLintNameResult) - #54107 (Fix typos in libstd hash map) - #54136 (Update LLVM to fix GlobalISel dbg.declare) - #54142 (Recover proper regression test for issue #16278.) Failed merges: r? @ghost
This commit is contained in:
commit
8586ec6980
@ -125,9 +125,9 @@ you have a more recent version installed the build system doesn't understand
|
||||
then you may need to force rustbuild to use an older version. This can be done
|
||||
by manually calling the appropriate vcvars file before running the bootstrap.
|
||||
|
||||
```
|
||||
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
|
||||
python x.py build
|
||||
```batch
|
||||
> CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
|
||||
> python x.py build
|
||||
```
|
||||
|
||||
#### Specifying an ABI
|
||||
|
@ -8,14 +8,14 @@ system.
|
||||
|
||||
The rustbuild build system has a primary entry point, a top level `x.py` script:
|
||||
|
||||
```
|
||||
python ./x.py build
|
||||
```sh
|
||||
$ python ./x.py build
|
||||
```
|
||||
|
||||
Note that if you're on Unix you should be able to execute the script directly:
|
||||
|
||||
```
|
||||
./x.py build
|
||||
```sh
|
||||
$ ./x.py build
|
||||
```
|
||||
|
||||
The script accepts commands, flags, and arguments to determine what to do:
|
||||
@ -129,18 +129,18 @@ To follow this course of action, first thing you will want to do is to
|
||||
install a nightly, presumably using `rustup`. You will then want to
|
||||
configure your directory to use this build, like so:
|
||||
|
||||
```
|
||||
```sh
|
||||
# configure to use local rust instead of downloading a beta.
|
||||
# `--local-rust-root` is optional here. If elided, we will
|
||||
# use whatever rustc we find on your PATH.
|
||||
> ./configure --local-rust-root=~/.cargo/ --enable-local-rebuild
|
||||
$ ./configure --local-rust-root=~/.cargo/ --enable-local-rebuild
|
||||
```
|
||||
|
||||
After that, you can use the `--incremental` flag to actually do
|
||||
incremental builds:
|
||||
|
||||
```
|
||||
> ./x.py build --incremental
|
||||
```sh
|
||||
$ ./x.py build --incremental
|
||||
```
|
||||
|
||||
The `--incremental` flag will store incremental compilation artifacts
|
||||
@ -159,7 +159,7 @@ will still be using the local nightly as your bootstrap).
|
||||
This build system houses all output under the `build` directory, which looks
|
||||
like this:
|
||||
|
||||
```
|
||||
```sh
|
||||
# Root folder of all output. Everything is scoped underneath here
|
||||
build/
|
||||
|
||||
|
@ -12,7 +12,7 @@ $ cat main.rs
|
||||
fn main() {
|
||||
let x = 5;
|
||||
}
|
||||
> rustc main.rs
|
||||
$ rustc main.rs
|
||||
warning: unused variable: `x`
|
||||
--> main.rs:2:9
|
||||
|
|
||||
|
@ -45,7 +45,7 @@ pub fn foo() {
|
||||
|
||||
This will produce this warning:
|
||||
|
||||
```console
|
||||
```bash
|
||||
$ rustc lib.rs --crate-type=lib
|
||||
warning: unused variable: `x`
|
||||
--> lib.rs:2:9
|
||||
@ -69,7 +69,7 @@ fn main() {
|
||||
```
|
||||
|
||||
```bash
|
||||
> rustc main.rs
|
||||
$ rustc main.rs
|
||||
error: bitshift exceeds the type's number of bits
|
||||
--> main.rs:2:13
|
||||
|
|
||||
@ -129,7 +129,10 @@ warning: missing documentation for a function
|
||||
|
|
||||
1 | pub fn foo() {}
|
||||
| ^^^^^^^^^^^^
|
||||
> rustc lib.rs --crate-type=lib -D missing-docs
|
||||
```
|
||||
|
||||
```bash
|
||||
$ rustc lib.rs --crate-type=lib -D missing-docs
|
||||
error: missing documentation for crate
|
||||
--> lib.rs:1:1
|
||||
|
|
||||
@ -150,13 +153,13 @@ error: aborting due to 2 previous errors
|
||||
You can also pass each flag more than once for changing multiple lints:
|
||||
|
||||
```bash
|
||||
rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables
|
||||
$ rustc lib.rs --crate-type=lib -D missing-docs -D unused-variables
|
||||
```
|
||||
|
||||
And of course, you can mix these four flags together:
|
||||
|
||||
```bash
|
||||
rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables
|
||||
$ rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables
|
||||
```
|
||||
|
||||
### Via an attribute
|
||||
@ -164,7 +167,7 @@ rustc lib.rs --crate-type=lib -D missing-docs -A unused-variables
|
||||
You can also modify the lint level with a crate-wide attribute:
|
||||
|
||||
```bash
|
||||
> cat lib.rs
|
||||
$ cat lib.rs
|
||||
#![warn(missing_docs)]
|
||||
|
||||
pub fn foo() {}
|
||||
|
@ -122,6 +122,9 @@ nonzero_integers! {
|
||||
/// all standard arithmetic operations on the underlying value are
|
||||
/// intended to have wrapping semantics.
|
||||
///
|
||||
/// The underlying value can be retrieved through the `.0` index of the
|
||||
/// `Wrapping` tuple.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -470,6 +470,36 @@ impl<T, E> Result<T, E> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Maps a `Result<T, E>` to `U` by applying a function to a
|
||||
/// contained [`Ok`] value, or a fallback function to a
|
||||
/// contained [`Err`] value.
|
||||
///
|
||||
/// This function can be used to unpack a successful result
|
||||
/// while handling an error.
|
||||
///
|
||||
/// [`Ok`]: enum.Result.html#variant.Ok
|
||||
/// [`Err`]: enum.Result.html#variant.Err
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_map_or_else)]
|
||||
/// let k = 21;
|
||||
///
|
||||
/// let x : Result<_, &str> = Ok("foo");
|
||||
/// assert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 3);
|
||||
///
|
||||
/// let x : Result<&str, _> = Err("bar");
|
||||
/// assert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 42);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "result_map_or_else", issue = "53268")]
|
||||
pub fn map_or_else<U, M: FnOnce(T) -> U, F: FnOnce(E) -> U>(self, fallback: F, map: M) -> U {
|
||||
self.map(map).unwrap_or_else(fallback)
|
||||
}
|
||||
|
||||
/// Maps a `Result<T, E>` to `Result<T, F>` by applying a function to a
|
||||
/// contained [`Err`] value, leaving an [`Ok`] value untouched.
|
||||
///
|
||||
|
@ -15,10 +15,6 @@
|
||||
//! function-like macros `#[proc_macro]`, macro attributes `#[proc_macro_attribute]` and
|
||||
//! custom derive attributes`#[proc_macro_derive]`.
|
||||
//!
|
||||
//! Note that this crate is intentionally bare-bones currently.
|
||||
//! This functionality is intended to be expanded over time as more surface
|
||||
//! area for macro authors is stabilized.
|
||||
//!
|
||||
//! See [the book](../book/first-edition/procedural-macros.html) for more.
|
||||
|
||||
#![stable(feature = "proc_macro_lib", since = "1.15.0")]
|
||||
@ -73,9 +69,6 @@ use syntax_pos::{Pos, FileName};
|
||||
///
|
||||
/// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
|
||||
/// and `#[proc_macro_derive]` definitions.
|
||||
///
|
||||
/// The API of this type is intentionally bare-bones, but it'll be expanded over
|
||||
/// time!
|
||||
#[stable(feature = "proc_macro_lib", since = "1.15.0")]
|
||||
#[derive(Clone)]
|
||||
pub struct TokenStream(tokenstream::TokenStream);
|
||||
|
@ -53,7 +53,7 @@ use ty::query::Providers;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
||||
check_crate, check_ast_crate,
|
||||
check_crate, check_ast_crate, CheckLintNameResult,
|
||||
FutureIncompatibleInfo, BufferedEarlyLint};
|
||||
|
||||
/// Specification of a single lint.
|
||||
|
@ -42,7 +42,7 @@ const TAG_MASK: usize = 0b11;
|
||||
const TYPE_TAG: usize = 0b00;
|
||||
const REGION_TAG: usize = 0b01;
|
||||
|
||||
#[derive(Debug, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Debug, RustcEncodable, RustcDecodable, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum UnpackedKind<'tcx> {
|
||||
Lifetime(ty::Region<'tcx>),
|
||||
Type(Ty<'tcx>),
|
||||
@ -74,17 +74,7 @@ impl<'tcx> UnpackedKind<'tcx> {
|
||||
|
||||
impl<'tcx> Ord for Kind<'tcx> {
|
||||
fn cmp(&self, other: &Kind) -> Ordering {
|
||||
match (self.unpack(), other.unpack()) {
|
||||
(UnpackedKind::Type(_), UnpackedKind::Lifetime(_)) => Ordering::Greater,
|
||||
|
||||
(UnpackedKind::Type(ty1), UnpackedKind::Type(ty2)) => {
|
||||
ty1.sty.cmp(&ty2.sty)
|
||||
}
|
||||
|
||||
(UnpackedKind::Lifetime(reg1), UnpackedKind::Lifetime(reg2)) => reg1.cmp(reg2),
|
||||
|
||||
(UnpackedKind::Lifetime(_), UnpackedKind::Type(_)) => Ordering::Less,
|
||||
}
|
||||
self.unpack().cmp(&other.unpack())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::Sanitizer;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::layout::HasTyCtxt;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
@ -32,12 +33,16 @@ use value::Value;
|
||||
|
||||
/// Mark LLVM function to use provided inline heuristic.
|
||||
#[inline]
|
||||
pub fn inline(val: &'ll Value, inline: InlineAttr) {
|
||||
pub fn inline(cx: &CodegenCx<'ll, '_>, val: &'ll Value, inline: InlineAttr) {
|
||||
use self::InlineAttr::*;
|
||||
match inline {
|
||||
Hint => Attribute::InlineHint.apply_llfn(Function, val),
|
||||
Always => Attribute::AlwaysInline.apply_llfn(Function, val),
|
||||
Never => Attribute::NoInline.apply_llfn(Function, val),
|
||||
Never => {
|
||||
if cx.tcx().sess.target.target.arch != "amdgpu" {
|
||||
Attribute::NoInline.apply_llfn(Function, val);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
Attribute::InlineHint.unapply_llfn(Function, val);
|
||||
Attribute::AlwaysInline.unapply_llfn(Function, val);
|
||||
@ -143,7 +148,7 @@ pub fn from_fn_attrs(
|
||||
let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id))
|
||||
.unwrap_or(CodegenFnAttrs::new());
|
||||
|
||||
inline(llfn, codegen_fn_attrs.inline);
|
||||
inline(cx, llfn, codegen_fn_attrs.inline);
|
||||
|
||||
// The `uwtable` attribute according to LLVM is:
|
||||
//
|
||||
|
@ -496,6 +496,14 @@ impl Builder<'a, 'll, 'tcx> {
|
||||
|
||||
|
||||
pub fn range_metadata(&self, load: &'ll Value, range: Range<u128>) {
|
||||
if self.sess().target.target.arch == "amdgpu" {
|
||||
// amdgpu/LLVM does something weird and thinks a i64 value is
|
||||
// split into a v2i32, halving the bitwidth LLVM expects,
|
||||
// tripping an assertion. So, for now, just disable this
|
||||
// optimization.
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let llty = val_ty(load);
|
||||
let v = [
|
||||
|
@ -96,7 +96,7 @@ pub fn get_fn(
|
||||
debug!("get_fn: not casting pointer!");
|
||||
|
||||
if instance.def.is_inline(tcx) {
|
||||
attributes::inline(llfn, attributes::InlineAttr::Hint);
|
||||
attributes::inline(cx, llfn, attributes::InlineAttr::Hint);
|
||||
}
|
||||
attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id()));
|
||||
|
||||
|
@ -180,7 +180,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
|
||||
debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance);
|
||||
if instance.def.is_inline(cx.tcx) {
|
||||
attributes::inline(lldecl, attributes::InlineAttr::Hint);
|
||||
attributes::inline(cx, lldecl, attributes::InlineAttr::Hint);
|
||||
}
|
||||
attributes::from_fn_attrs(cx, lldecl, Some(instance.def.def_id()));
|
||||
|
||||
|
@ -81,7 +81,7 @@ fn main() {
|
||||
let is_crossed = target != host;
|
||||
|
||||
let mut optional_components =
|
||||
vec!["x86", "arm", "aarch64", "mips", "powerpc",
|
||||
vec!["x86", "arm", "aarch64", "amdgpu", "mips", "powerpc",
|
||||
"systemz", "jsbackend", "webassembly", "msp430", "sparc", "nvptx"];
|
||||
|
||||
let mut version_cmd = Command::new(&llvm_config);
|
||||
|
@ -99,14 +99,11 @@ impl<'a> AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn check_trait_fn_not_const(&self, constness: Spanned<Constness>) {
|
||||
match constness.node {
|
||||
Constness::Const => {
|
||||
struct_span_err!(self.session, constness.span, E0379,
|
||||
"trait fns cannot be declared const")
|
||||
.span_label(constness.span, "trait fns cannot be const")
|
||||
.emit();
|
||||
}
|
||||
_ => {}
|
||||
if constness.node == Constness::Const {
|
||||
struct_span_err!(self.session, constness.span, E0379,
|
||||
"trait fns cannot be declared const")
|
||||
.span_label(constness.span, "trait fns cannot be const")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +111,7 @@ impl<'a> AstValidator<'a> {
|
||||
for bound in bounds {
|
||||
if let GenericBound::Trait(ref poly, TraitBoundModifier::Maybe) = *bound {
|
||||
let mut err = self.err_handler().struct_span_err(poly.span,
|
||||
&format!("`?Trait` is not permitted in {}", where_));
|
||||
&format!("`?Trait` is not permitted in {}", where_));
|
||||
if is_trait {
|
||||
err.note(&format!("traits are `?{}` by default", poly.trait_ref.path));
|
||||
}
|
||||
@ -153,16 +150,16 @@ impl<'a> AstValidator<'a> {
|
||||
// Check only lifetime parameters are present and that the lifetime
|
||||
// parameters that are present have no bounds.
|
||||
let non_lt_param_spans: Vec<_> = params.iter().filter_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if !param.bounds.is_empty() {
|
||||
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
|
||||
self.err_handler()
|
||||
.span_err(spans, "lifetime bounds cannot be used in this context");
|
||||
}
|
||||
None
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if !param.bounds.is_empty() {
|
||||
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
|
||||
self.err_handler()
|
||||
.span_err(spans, "lifetime bounds cannot be used in this context");
|
||||
}
|
||||
_ => Some(param.ident.span),
|
||||
}).collect();
|
||||
None
|
||||
}
|
||||
_ => Some(param.ident.span),
|
||||
}).collect();
|
||||
if !non_lt_param_spans.is_empty() {
|
||||
self.err_handler().span_err(non_lt_param_spans,
|
||||
"only lifetime parameters can be used in this context");
|
||||
@ -438,7 +435,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.err_handler().span_err(item.span,
|
||||
"tuple and unit unions are not permitted");
|
||||
}
|
||||
if vdata.fields().len() == 0 {
|
||||
if vdata.fields().is_empty() {
|
||||
self.err_handler().span_err(item.span,
|
||||
"unions cannot have zero fields");
|
||||
}
|
||||
@ -465,14 +462,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
|
||||
fn visit_vis(&mut self, vis: &'a Visibility) {
|
||||
match vis.node {
|
||||
VisibilityKind::Restricted { ref path, .. } => {
|
||||
path.segments.iter().find(|segment| segment.args.is_some()).map(|segment| {
|
||||
self.err_handler().span_err(segment.args.as_ref().unwrap().span(),
|
||||
"generic arguments in visibility path");
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
if let VisibilityKind::Restricted { ref path, .. } = vis.node {
|
||||
path.segments.iter().find(|segment| segment.args.is_some()).map(|segment| {
|
||||
self.err_handler().span_err(segment.args.as_ref().unwrap().span(),
|
||||
"generic arguments in visibility path");
|
||||
});
|
||||
}
|
||||
|
||||
visit::walk_vis(self, vis)
|
||||
@ -642,8 +636,7 @@ impl<'a> Visitor<'a> for ImplTraitProjectionVisitor<'a> {
|
||||
TyKind::ImplTrait(..) => {
|
||||
if self.is_banned {
|
||||
struct_span_err!(self.session, t.span, E0667,
|
||||
"`impl Trait` is not allowed in path parameters")
|
||||
.emit();
|
||||
"`impl Trait` is not allowed in path parameters").emit();
|
||||
}
|
||||
}
|
||||
TyKind::Path(ref qself, ref path) => {
|
||||
@ -667,7 +660,7 @@ impl<'a> Visitor<'a> for ImplTraitProjectionVisitor<'a> {
|
||||
|
||||
for (i, segment) in path.segments.iter().enumerate() {
|
||||
// Allow `impl Trait` iff we're on the final path segment
|
||||
if i == (path.segments.len() - 1) {
|
||||
if i == path.segments.len() - 1 {
|
||||
visit::walk_path_segment(self, path.span, segment);
|
||||
} else {
|
||||
self.with_ban(|this|
|
||||
|
@ -61,10 +61,8 @@ pub fn print_ast_stats<'v>(krate: &'v ast::Crate, title: &str) {
|
||||
impl<'k> StatCollector<'k> {
|
||||
|
||||
fn record<T>(&mut self, label: &'static str, id: Id, node: &T) {
|
||||
if id != Id::None {
|
||||
if !self.seen.insert(id) {
|
||||
return
|
||||
}
|
||||
if id != Id::None && !self.seen.insert(id) {
|
||||
return
|
||||
}
|
||||
|
||||
let entry = self.data.entry(label).or_insert(NodeData {
|
||||
@ -135,40 +133,46 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||
hir_visit::walk_item(self, i)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn visit_mod(&mut self, m: &'v hir::Mod, _s: Span, n: NodeId) {
|
||||
self.record("Mod", Id::None, m);
|
||||
hir_visit::walk_mod(self, m, n)
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, i: &'v hir::ForeignItem) {
|
||||
self.record("ForeignItem", Id::Node(i.id), i);
|
||||
hir_visit::walk_foreign_item(self, i)
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &'v hir::Local) {
|
||||
self.record("Local", Id::Node(l.id), l);
|
||||
hir_visit::walk_local(self, l)
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b: &'v hir::Block) {
|
||||
self.record("Block", Id::Node(b.id), b);
|
||||
hir_visit::walk_block(self, b)
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, s: &'v hir::Stmt) {
|
||||
self.record("Stmt", Id::Node(s.node.id()), s);
|
||||
hir_visit::walk_stmt(self, s)
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, a: &'v hir::Arm) {
|
||||
self.record("Arm", Id::None, a);
|
||||
hir_visit::walk_arm(self, a)
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &'v hir::Pat) {
|
||||
self.record("Pat", Id::Node(p.id), p);
|
||||
hir_visit::walk_pat(self, p)
|
||||
}
|
||||
|
||||
fn visit_decl(&mut self, d: &'v hir::Decl) {
|
||||
self.record("Decl", Id::None, d);
|
||||
hir_visit::walk_decl(self, d)
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'v hir::Expr) {
|
||||
self.record("Expr", Id::Node(ex.id), ex);
|
||||
hir_visit::walk_expr(self, ex)
|
||||
@ -198,6 +202,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||
self.record("TraitItem", Id::Node(ti.id), ti);
|
||||
hir_visit::walk_trait_item(self, ti)
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
|
||||
self.record("ImplItem", Id::Node(ii.id), ii);
|
||||
hir_visit::walk_impl_item(self, ii)
|
||||
@ -220,31 +225,38 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||
self.record("Variant", Id::None, v);
|
||||
hir_visit::walk_variant(self, v, g, item_id)
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
|
||||
self.record("Lifetime", Id::Node(lifetime.id), lifetime);
|
||||
hir_visit::walk_lifetime(self, lifetime)
|
||||
}
|
||||
|
||||
fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: hir::HirId, span: Span) {
|
||||
self.record("QPath", Id::None, qpath);
|
||||
hir_visit::walk_qpath(self, qpath, id, span)
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &'v hir::Path, _id: hir::HirId) {
|
||||
self.record("Path", Id::None, path);
|
||||
hir_visit::walk_path(self, path)
|
||||
}
|
||||
|
||||
fn visit_path_segment(&mut self,
|
||||
path_span: Span,
|
||||
path_segment: &'v hir::PathSegment) {
|
||||
self.record("PathSegment", Id::None, path_segment);
|
||||
hir_visit::walk_path_segment(self, path_span, path_segment)
|
||||
}
|
||||
|
||||
fn visit_assoc_type_binding(&mut self, type_binding: &'v hir::TypeBinding) {
|
||||
self.record("TypeBinding", Id::Node(type_binding.id), type_binding);
|
||||
hir_visit::walk_assoc_type_binding(self, type_binding)
|
||||
}
|
||||
|
||||
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
|
||||
self.record("Attribute", Id::Attr(attr.id), attr);
|
||||
}
|
||||
|
||||
fn visit_macro_def(&mut self, macro_def: &'v hir::MacroDef) {
|
||||
self.record("MacroDef", Id::Node(macro_def.id), macro_def);
|
||||
hir_visit::walk_macro_def(self, macro_def)
|
||||
|
@ -114,9 +114,8 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
|
||||
};
|
||||
|
||||
if loop_id != ast::DUMMY_NODE_ID {
|
||||
match self.hir_map.find(loop_id).unwrap() {
|
||||
Node::Block(_) => return,
|
||||
_=> (),
|
||||
if let Node::Block(_) = self.hir_map.find(loop_id).unwrap() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,10 +152,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
|
||||
|
||||
self.require_break_cx("break", e.span);
|
||||
}
|
||||
hir::ExprKind::Continue(label) => {
|
||||
self.require_label_in_labeled_block(e.span, &label, "continue");
|
||||
hir::ExprKind::Continue(destination) => {
|
||||
self.require_label_in_labeled_block(e.span, &destination, "continue");
|
||||
|
||||
match label.target_id {
|
||||
match destination.target_id {
|
||||
Ok(loop_id) => {
|
||||
if let Node::Block(block) = self.hir_map.find(loop_id).unwrap() {
|
||||
struct_span_err!(self.sess, e.span, E0696,
|
||||
@ -171,7 +170,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
|
||||
Err(hir::LoopIdError::UnlabeledCfInWhileCondition) => {
|
||||
self.emit_unlabled_cf_in_while_condition(e.span, "continue");
|
||||
}
|
||||
_ => {}
|
||||
Err(_) => {}
|
||||
}
|
||||
self.require_break_cx("continue", e.span)
|
||||
},
|
||||
@ -192,8 +191,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
|
||||
|
||||
fn require_break_cx(&self, name: &str, span: Span) {
|
||||
match self.cx {
|
||||
LabeledBlock |
|
||||
Loop(_) => {}
|
||||
LabeledBlock | Loop(_) => {}
|
||||
Closure => {
|
||||
struct_span_err!(self.sess, span, E0267, "`{}` inside of a closure", name)
|
||||
.span_label(span, "cannot break inside of a closure")
|
||||
|
@ -65,15 +65,12 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
|
||||
self.super_mir(mir);
|
||||
}
|
||||
|
||||
fn visit_basic_block_data(&mut self,
|
||||
block: BasicBlock,
|
||||
data: &BasicBlockData<'tcx>) {
|
||||
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &BasicBlockData<'tcx>) {
|
||||
self.record("BasicBlockData", data);
|
||||
self.super_basic_block_data(block, data);
|
||||
}
|
||||
|
||||
fn visit_source_scope_data(&mut self,
|
||||
scope_data: &SourceScopeData) {
|
||||
fn visit_source_scope_data(&mut self, scope_data: &SourceScopeData) {
|
||||
self.record("SourceScopeData", scope_data);
|
||||
self.super_source_scope_data(scope_data);
|
||||
}
|
||||
@ -130,9 +127,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
|
||||
self.super_terminator_kind(block, kind, location);
|
||||
}
|
||||
|
||||
fn visit_assert_message(&mut self,
|
||||
msg: &AssertMessage<'tcx>,
|
||||
location: Location) {
|
||||
fn visit_assert_message(&mut self, msg: &AssertMessage<'tcx>, location: Location) {
|
||||
self.record("AssertMessage", msg);
|
||||
self.record(match *msg {
|
||||
EvalErrorKind::BoundsCheck { .. } => "AssertMessage::BoundsCheck",
|
||||
@ -151,9 +146,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
|
||||
self.super_assert_message(msg, location);
|
||||
}
|
||||
|
||||
fn visit_rvalue(&mut self,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
self.record("Rvalue", rvalue);
|
||||
let rvalue_kind = match *rvalue {
|
||||
Rvalue::Use(..) => "Rvalue::Use",
|
||||
@ -184,9 +177,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
|
||||
self.super_rvalue(rvalue, location);
|
||||
}
|
||||
|
||||
fn visit_operand(&mut self,
|
||||
operand: &Operand<'tcx>,
|
||||
location: Location) {
|
||||
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
|
||||
self.record("Operand", operand);
|
||||
self.record(match *operand {
|
||||
Operand::Copy(..) => "Operand::Copy",
|
||||
@ -234,42 +225,32 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
|
||||
self.super_projection_elem(place, context, location);
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self,
|
||||
constant: &Constant<'tcx>,
|
||||
location: Location) {
|
||||
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
|
||||
self.record("Constant", constant);
|
||||
self.super_constant(constant, location);
|
||||
}
|
||||
|
||||
fn visit_source_info(&mut self,
|
||||
source_info: &SourceInfo) {
|
||||
fn visit_source_info(&mut self, source_info: &SourceInfo) {
|
||||
self.record("SourceInfo", source_info);
|
||||
self.super_source_info(source_info);
|
||||
}
|
||||
|
||||
fn visit_closure_substs(&mut self,
|
||||
substs: &ClosureSubsts<'tcx>,
|
||||
_: Location) {
|
||||
fn visit_closure_substs(&mut self, substs: &ClosureSubsts<'tcx>, _: Location) {
|
||||
self.record("ClosureSubsts", substs);
|
||||
self.super_closure_substs(substs);
|
||||
}
|
||||
|
||||
fn visit_const(&mut self,
|
||||
constant: &&'tcx ty::Const<'tcx>,
|
||||
_: Location) {
|
||||
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
|
||||
self.record("Const", constant);
|
||||
self.super_const(constant);
|
||||
}
|
||||
|
||||
fn visit_local_decl(&mut self,
|
||||
local: Local,
|
||||
local_decl: &LocalDecl<'tcx>) {
|
||||
fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
|
||||
self.record("LocalDecl", local_decl);
|
||||
self.super_local_decl(local, local_decl);
|
||||
}
|
||||
|
||||
fn visit_source_scope(&mut self,
|
||||
scope: &SourceScope) {
|
||||
fn visit_source_scope(&mut self, scope: &SourceScope) {
|
||||
self.record("VisiblityScope", scope);
|
||||
self.super_source_scope(scope);
|
||||
}
|
||||
|
@ -41,8 +41,7 @@ use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use self::Promotability::*;
|
||||
use std::ops::{BitAnd, BitOr};
|
||||
|
||||
use std::ops::{BitAnd, BitAndAssign, BitOr};
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
@ -114,7 +113,7 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
enum Promotability {
|
||||
Promotable,
|
||||
NotPromotable
|
||||
@ -125,23 +124,25 @@ impl BitAnd for Promotability {
|
||||
|
||||
fn bitand(self, rhs: Self) -> Self {
|
||||
match (self, rhs) {
|
||||
(Promotable, NotPromotable) => NotPromotable,
|
||||
(NotPromotable, Promotable) => NotPromotable,
|
||||
(NotPromotable, NotPromotable) => NotPromotable,
|
||||
(Promotable, Promotable) => Promotable,
|
||||
_ => NotPromotable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAndAssign for Promotability {
|
||||
fn bitand_assign(&mut self, rhs: Self) {
|
||||
*self = *self & rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOr for Promotability {
|
||||
type Output = Self;
|
||||
|
||||
fn bitor(self, rhs: Self) -> Self {
|
||||
match (self, rhs) {
|
||||
(Promotable, NotPromotable) => Promotable,
|
||||
(NotPromotable, Promotable) => Promotable,
|
||||
(NotPromotable, NotPromotable) => NotPromotable,
|
||||
(Promotable, Promotable) => Promotable,
|
||||
_ => Promotable,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,7 +162,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
|
||||
|
||||
fn handle_const_fn_call(&mut self, def_id: DefId,
|
||||
ret_ty: Ty<'gcx>, span: Span) -> Promotability {
|
||||
if let NotPromotable = self.type_promotability(ret_ty) {
|
||||
if self.type_promotability(ret_ty) == NotPromotable {
|
||||
return NotPromotable;
|
||||
}
|
||||
|
||||
@ -266,9 +267,8 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
match local.init {
|
||||
Some(ref expr) => { let _ = self.check_expr(&expr); },
|
||||
None => {},
|
||||
if let Some(ref expr) = local.init {
|
||||
let _ = self.check_expr(&expr);
|
||||
}
|
||||
NotPromotable
|
||||
}
|
||||
@ -287,7 +287,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||
fn check_expr(&mut self, ex: &'tcx hir::Expr) -> Promotability {
|
||||
let node_ty = self.tables.node_id_to_type(ex.hir_id);
|
||||
let mut outer = check_expr_kind(self, ex, node_ty);
|
||||
outer = outer & check_adjustments(self, ex);
|
||||
outer &= check_adjustments(self, ex);
|
||||
|
||||
// Handle borrows on (or inside the autorefs of) this expression.
|
||||
if self.mut_rvalue_borrows.remove(&ex.id) {
|
||||
@ -303,7 +303,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||
fn check_block(&mut self, block: &'tcx hir::Block) -> Promotability {
|
||||
let mut iter_result = Promotable;
|
||||
for index in block.stmts.iter() {
|
||||
iter_result = iter_result & self.check_stmt(index);
|
||||
iter_result &= self.check_stmt(index);
|
||||
}
|
||||
match block.expr {
|
||||
Some(ref box_expr) => iter_result & self.check_expr(&*box_expr),
|
||||
@ -336,10 +336,7 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
}
|
||||
hir::ExprKind::Unary(op, ref expr) => {
|
||||
let expr_promotability = v.check_expr(expr);
|
||||
if v.tables.is_method_call(e) {
|
||||
return NotPromotable;
|
||||
}
|
||||
if op == hir::UnDeref {
|
||||
if v.tables.is_method_call(e) || op == hir::UnDeref {
|
||||
return NotPromotable;
|
||||
}
|
||||
expr_promotability
|
||||
@ -353,8 +350,8 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
match v.tables.node_id_to_type(lhs.hir_id).sty {
|
||||
ty::RawPtr(_) => {
|
||||
assert!(op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne ||
|
||||
op.node == hir::BinOpKind::Le || op.node == hir::BinOpKind::Lt ||
|
||||
op.node == hir::BinOpKind::Ge || op.node == hir::BinOpKind::Gt);
|
||||
op.node == hir::BinOpKind::Le || op.node == hir::BinOpKind::Lt ||
|
||||
op.node == hir::BinOpKind::Ge || op.node == hir::BinOpKind::Gt);
|
||||
|
||||
NotPromotable
|
||||
}
|
||||
@ -400,7 +397,6 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
debug!("Reference to Static(id={:?}) is unpromotable as it is not \
|
||||
referenced from a static", did);
|
||||
NotPromotable
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,7 +421,7 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
hir::ExprKind::Call(ref callee, ref hirvec) => {
|
||||
let mut call_result = v.check_expr(callee);
|
||||
for index in hirvec.iter() {
|
||||
call_result = call_result & v.check_expr(index);
|
||||
call_result &= v.check_expr(index);
|
||||
}
|
||||
let mut callee = &**callee;
|
||||
loop {
|
||||
@ -464,7 +460,7 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
hir::ExprKind::MethodCall(ref _pathsegment, ref _span, ref hirvec) => {
|
||||
let mut method_call_result = Promotable;
|
||||
for index in hirvec.iter() {
|
||||
method_call_result = method_call_result & v.check_expr(index);
|
||||
method_call_result &= v.check_expr(index);
|
||||
}
|
||||
if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) {
|
||||
let def_id = def.def_id();
|
||||
@ -483,11 +479,10 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
hir::ExprKind::Struct(ref _qpath, ref hirvec, ref option_expr) => {
|
||||
let mut struct_result = Promotable;
|
||||
for index in hirvec.iter() {
|
||||
struct_result = struct_result & v.check_expr(&index.expr);
|
||||
struct_result &= v.check_expr(&index.expr);
|
||||
}
|
||||
match *option_expr {
|
||||
Some(ref expr) => { struct_result = struct_result & v.check_expr(&expr); },
|
||||
None => {},
|
||||
if let Some(ref expr) = *option_expr {
|
||||
struct_result &= v.check_expr(&expr);
|
||||
}
|
||||
if let ty::Adt(adt, ..) = v.tables.expr_ty(e).sty {
|
||||
// unsafe_cell_type doesn't necessarily exist with no_core
|
||||
@ -506,7 +501,7 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
}
|
||||
|
||||
hir::ExprKind::Closure(_capture_clause, ref _box_fn_decl,
|
||||
body_id, _span, _option_generator_movability) => {
|
||||
body_id, _span, _option_generator_movability) => {
|
||||
let nested_body_promotable = v.check_nested_body(body_id);
|
||||
// Paths in constant contexts cannot refer to local variables,
|
||||
// as there are none, and thus closures can't have upvars there.
|
||||
@ -543,7 +538,7 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
hir::ExprKind::Array(ref hirvec) => {
|
||||
let mut array_result = Promotable;
|
||||
for index in hirvec.iter() {
|
||||
array_result = array_result & v.check_expr(index);
|
||||
array_result &= v.check_expr(index);
|
||||
}
|
||||
array_result
|
||||
}
|
||||
@ -555,7 +550,7 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
hir::ExprKind::Tup(ref hirvec) => {
|
||||
let mut tup_result = Promotable;
|
||||
for index in hirvec.iter() {
|
||||
tup_result = tup_result & v.check_expr(index);
|
||||
tup_result &= v.check_expr(index);
|
||||
}
|
||||
tup_result
|
||||
}
|
||||
@ -576,12 +571,9 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
let _ = v.check_expr(expr);
|
||||
for index in hirvec_arm.iter() {
|
||||
let _ = v.check_expr(&*index.body);
|
||||
match index.guard {
|
||||
Some(hir::Guard::If(ref expr)) => {
|
||||
let _ = v.check_expr(&expr);
|
||||
},
|
||||
None => {},
|
||||
};
|
||||
if let Some(hir::Guard::If(ref expr)) = index.guard {
|
||||
let _ = v.check_expr(&expr);
|
||||
}
|
||||
}
|
||||
NotPromotable
|
||||
}
|
||||
@ -589,10 +581,9 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
hir::ExprKind::If(ref lhs, ref rhs, ref option_expr) => {
|
||||
let _ = v.check_expr(lhs);
|
||||
let _ = v.check_expr(rhs);
|
||||
match option_expr {
|
||||
Some(ref expr) => { let _ = v.check_expr(&expr); },
|
||||
None => {},
|
||||
};
|
||||
if let Some(ref expr) = option_expr {
|
||||
let _ = v.check_expr(&expr);
|
||||
}
|
||||
NotPromotable
|
||||
}
|
||||
|
||||
@ -610,9 +601,8 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
|
||||
// More control flow (also not very meaningful).
|
||||
hir::ExprKind::Break(_, ref option_expr) | hir::ExprKind::Ret(ref option_expr) => {
|
||||
match *option_expr {
|
||||
Some(ref expr) => { let _ = v.check_expr(&expr); },
|
||||
None => {},
|
||||
if let Some(ref expr) = *option_expr {
|
||||
let _ = v.check_expr(&expr);
|
||||
}
|
||||
NotPromotable
|
||||
}
|
||||
@ -635,10 +625,7 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
}
|
||||
|
||||
hir::ExprKind::InlineAsm(ref _inline_asm, ref hirvec_lhs, ref hirvec_rhs) => {
|
||||
for index in hirvec_lhs.iter() {
|
||||
let _ = v.check_expr(index);
|
||||
}
|
||||
for index in hirvec_rhs.iter() {
|
||||
for index in hirvec_lhs.iter().chain(hirvec_rhs.iter()) {
|
||||
let _ = v.check_expr(index);
|
||||
}
|
||||
NotPromotable
|
||||
@ -703,11 +690,8 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> {
|
||||
// These occur when we convert a &T or *T to a *U, as well as
|
||||
// when making a thin pointer (e.g., `*T`) into a fat pointer
|
||||
// (e.g., `*Trait`).
|
||||
match loan_cause {
|
||||
euv::LoanCause::AutoUnsafe => {
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
if let euv::LoanCause::AutoUnsafe = loan_cause {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut cur = cmt;
|
||||
|
42
src/librustc_target/abi/call/amdgpu.rs
Normal file
42
src/librustc_target/abi/call/amdgpu.rs
Normal file
@ -0,0 +1,42 @@
|
||||
// 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.
|
||||
|
||||
use abi::call::{ArgType, FnType, };
|
||||
use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
|
||||
|
||||
fn classify_ret_ty<'a, Ty, C>(_tuncx: C, ret: &mut ArgType<'a, Ty>)
|
||||
where Ty: TyLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
|
||||
{
|
||||
ret.extend_integer_width_to(32);
|
||||
}
|
||||
|
||||
fn classify_arg_ty<'a, Ty, C>(_cx: C, arg: &mut ArgType<'a, Ty>)
|
||||
where Ty: TyLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
|
||||
{
|
||||
arg.extend_integer_width_to(32);
|
||||
}
|
||||
|
||||
pub fn compute_abi_info<'a, Ty, C>(cx: C, fty: &mut FnType<'a, Ty>)
|
||||
where Ty: TyLayoutMethods<'a, C> + Copy,
|
||||
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
|
||||
{
|
||||
if !fty.ret.is_ignore() {
|
||||
classify_ret_ty(cx, &mut fty.ret);
|
||||
}
|
||||
|
||||
for arg in &mut fty.args {
|
||||
if arg.is_ignore() {
|
||||
continue;
|
||||
}
|
||||
classify_arg_ty(cx, arg);
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
|
||||
use spec::HasTargetSpec;
|
||||
|
||||
mod aarch64;
|
||||
mod amdgpu;
|
||||
mod arm;
|
||||
mod asmjs;
|
||||
mod hexagon;
|
||||
@ -503,6 +504,7 @@ impl<'a, Ty> FnType<'a, Ty> {
|
||||
x86_64::compute_abi_info(cx, self);
|
||||
},
|
||||
"aarch64" => aarch64::compute_abi_info(cx, self),
|
||||
"amdgpu" => amdgpu::compute_abi_info(cx, self),
|
||||
"arm" => arm::compute_abi_info(cx, self),
|
||||
"mips" => mips::compute_abi_info(cx, self),
|
||||
"mips64" => mips64::compute_abi_info(cx, self),
|
||||
|
@ -1257,9 +1257,11 @@ impl DocFolder for Cache {
|
||||
// Collect all the implementors of traits.
|
||||
if let clean::ImplItem(ref i) = item.inner {
|
||||
if let Some(did) = i.trait_.def_id() {
|
||||
self.implementors.entry(did).or_default().push(Impl {
|
||||
impl_item: item.clone(),
|
||||
});
|
||||
if i.blanket_impl.is_none() {
|
||||
self.implementors.entry(did).or_default().push(Impl {
|
||||
impl_item: item.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2931,7 +2933,6 @@ fn item_trait(
|
||||
|
||||
|
||||
let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter()
|
||||
.filter(|i| i.inner_impl().blanket_impl.is_none())
|
||||
.partition(|i| i.inner_impl().synthetic);
|
||||
|
||||
if !foreign.is_empty() {
|
||||
@ -2941,17 +2942,14 @@ fn item_trait(
|
||||
</h2>
|
||||
")?;
|
||||
|
||||
let mut foreign_cache = FxHashSet();
|
||||
for implementor in foreign {
|
||||
if foreign_cache.insert(implementor.inner_impl().to_string()) {
|
||||
let assoc_link = AssocItemLink::GotoSource(
|
||||
implementor.impl_item.def_id,
|
||||
&implementor.inner_impl().provided_trait_methods
|
||||
);
|
||||
render_impl(w, cx, &implementor, assoc_link,
|
||||
RenderMode::Normal, implementor.impl_item.stable_since(), false,
|
||||
None)?;
|
||||
}
|
||||
let assoc_link = AssocItemLink::GotoSource(
|
||||
implementor.impl_item.def_id,
|
||||
&implementor.inner_impl().provided_trait_methods
|
||||
);
|
||||
render_impl(w, cx, &implementor, assoc_link,
|
||||
RenderMode::Normal, implementor.impl_item.stable_since(), false,
|
||||
None)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,14 +166,14 @@ impl DefaultResizePolicy {
|
||||
// Our hash generation scheme consists of generating a 64-bit hash and
|
||||
// truncating the most significant bits. When moving to the new table, we
|
||||
// simply introduce a new bit to the front of the hash. Therefore, if an
|
||||
// elements has ideal index i in the old table, it can have one of two ideal
|
||||
// element has ideal index i in the old table, it can have one of two ideal
|
||||
// locations in the new table. If the new bit is 0, then the new ideal index
|
||||
// is i. If the new bit is 1, then the new ideal index is n + i. Intuitively,
|
||||
// we are producing two independent tables of size n, and for each element we
|
||||
// independently choose which table to insert it into with equal probability.
|
||||
// However the rather than wrapping around themselves on overflowing their
|
||||
// indexes, the first table overflows into the first, and the first into the
|
||||
// second. Visually, our new table will look something like:
|
||||
// However, rather than wrapping around themselves on overflowing their
|
||||
// indexes, the first table overflows into the second, and the second into the
|
||||
// first. Visually, our new table will look something like:
|
||||
//
|
||||
// [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy]
|
||||
//
|
||||
|
@ -33,7 +33,7 @@ use sys;
|
||||
/// type is a static guarantee that the underlying bytes contain no interior 0
|
||||
/// bytes ("nul characters") and that the final byte is 0 ("nul terminator").
|
||||
///
|
||||
/// `CString` is to [`CStr`] as [`String`] is to [`&str`]: the former
|
||||
/// `CString` is to [`&CStr`] as [`String`] is to [`&str`]: the former
|
||||
/// in each pair are owned strings; the latter are borrowed
|
||||
/// references.
|
||||
///
|
||||
@ -88,6 +88,7 @@ use sys;
|
||||
/// [slice.len]: ../primitive.slice.html#method.len
|
||||
/// [`Deref`]: ../ops/trait.Deref.html
|
||||
/// [`CStr`]: struct.CStr.html
|
||||
/// [`&CStr`]: struct.CStr.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -137,7 +138,7 @@ pub struct CString {
|
||||
/// converted to a Rust [`&str`] by performing UTF-8 validation, or
|
||||
/// into an owned [`CString`].
|
||||
///
|
||||
/// `CStr` is to [`CString`] as [`&str`] is to [`String`]: the former
|
||||
/// `&CStr` is to [`CString`] as [`&str`] is to [`String`]: the former
|
||||
/// in each pair are borrowed references; the latter are owned
|
||||
/// strings.
|
||||
///
|
||||
|
@ -1330,7 +1330,8 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
|
||||
///
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait BufRead: Read {
|
||||
/// Fills the internal buffer of this object, returning the buffer contents.
|
||||
/// Returns the contents of the internal buffer, filling it with more data
|
||||
/// from the inner reader if it is empty.
|
||||
///
|
||||
/// This function is a lower-level call. It needs to be paired with the
|
||||
/// [`consume`] method to function properly. When calling this
|
||||
|
@ -37,7 +37,7 @@ use visit::{self, FnKind, Visitor};
|
||||
use parse::ParseSess;
|
||||
use symbol::{keywords, Symbol};
|
||||
|
||||
use std::{env, path};
|
||||
use std::{env};
|
||||
|
||||
macro_rules! set {
|
||||
// The const_fn feature also enables the min_const_fn feature, because `min_const_fn` allows
|
||||
@ -406,9 +406,6 @@ declare_features! (
|
||||
// Resolve absolute paths as paths from other crates
|
||||
(active, extern_absolute_paths, "1.24.0", Some(44660), Some(Edition::Edition2018)),
|
||||
|
||||
// `foo.rs` as an alternative to `foo/mod.rs`
|
||||
(active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)),
|
||||
|
||||
// `extern` in paths
|
||||
(active, extern_in_paths, "1.23.0", Some(44660), None),
|
||||
|
||||
@ -660,6 +657,8 @@ declare_features! (
|
||||
(accepted, repr_transparent, "1.28.0", Some(43036), None),
|
||||
// Defining procedural macros in `proc-macro` crates
|
||||
(accepted, proc_macro, "1.29.0", Some(38356), None),
|
||||
// `foo.rs` as an alternative to `foo/mod.rs`
|
||||
(accepted, non_modrs_mods, "1.30.0", Some(44660), None),
|
||||
// Allows use of the :vis macro fragment specifier
|
||||
(accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
|
||||
// Allows importing and reexporting macros with `use`,
|
||||
@ -1498,31 +1497,6 @@ impl<'a> PostExpansionVisitor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PostExpansionVisitor<'a> {
|
||||
fn whole_crate_feature_gates(&mut self, _krate: &ast::Crate) {
|
||||
for &(ident, span) in &*self.context.parse_sess.non_modrs_mods.borrow() {
|
||||
if !span.allows_unstable() {
|
||||
let cx = &self.context;
|
||||
let level = GateStrength::Hard;
|
||||
let has_feature = cx.features.non_modrs_mods;
|
||||
let name = "non_modrs_mods";
|
||||
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}",
|
||||
name, span, has_feature);
|
||||
|
||||
if !has_feature && !span.allows_unstable() {
|
||||
leveled_feature_err(
|
||||
cx.parse_sess, name, span, GateIssue::Language,
|
||||
"mod statements in non-mod.rs files are unstable", level
|
||||
)
|
||||
.help(&format!("on stable builds, rename this file to {}{}mod.rs",
|
||||
ident, path::MAIN_SEPARATOR))
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
||||
if !attr.span.allows_unstable() {
|
||||
@ -2092,7 +2066,6 @@ pub fn check_crate(krate: &ast::Crate,
|
||||
};
|
||||
|
||||
let visitor = &mut PostExpansionVisitor { context: &ctx };
|
||||
visitor.whole_crate_feature_gates(krate);
|
||||
visit::walk_crate(visitor, krate);
|
||||
}
|
||||
|
||||
|
2
src/llvm
2
src/llvm
@ -1 +1 @@
|
||||
Subproject commit 2a1cdeadd3ea8e1eba9cc681037b83f07332763b
|
||||
Subproject commit 5a081f0363340dd895d0958955d0c84661f60f05
|
@ -1,4 +1,4 @@
|
||||
# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
|
||||
# The actual contents of this file do not matter, but to trigger a change on the
|
||||
# build bots then the contents should be changed so git updates the mtime.
|
||||
2018-08-22
|
||||
2018-09-11
|
||||
|
1
src/test/run-pass/.gitattributes
vendored
1
src/test/run-pass/.gitattributes
vendored
@ -1,2 +1 @@
|
||||
lexer-crlf-line-endings-string-literal-doc-comment.rs -text
|
||||
issue-16278.rs -text
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// 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.
|
||||
//
|
||||
@ -8,8 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: mod statements in non-mod.rs files are unstable
|
||||
|
||||
mod mod_file_not_owning_aux1;
|
||||
|
||||
fn main() {}
|
||||
pub struct MyStruct;
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// 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.
|
||||
//
|
||||
@ -8,8 +8,19 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: mod statements in non-mod.rs files are unstable
|
||||
// aux-build:issue-53689.rs
|
||||
|
||||
// This is not a directory owner since the file name is not "mod.rs".
|
||||
#[path = "mod_file_not_owning_aux1.rs"]
|
||||
mod foo;
|
||||
#![crate_name = "foo"]
|
||||
|
||||
extern crate issue_53689;
|
||||
|
||||
// @has foo/trait.MyTrait.html
|
||||
// @!has - 'MyStruct'
|
||||
// @count - '//*[code="impl<T> MyTrait for T"]' 1
|
||||
pub trait MyTrait {}
|
||||
|
||||
impl<T> MyTrait for T {}
|
||||
|
||||
mod a {
|
||||
pub use issue_53689::MyStruct;
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660)
|
||||
--> $DIR/mod_file_not_owning_aux1.rs:14:17
|
||||
|
|
||||
LL | () => { mod mod_file_not_owning_aux2; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | }
|
||||
LL | m!();
|
||||
| ----- in this macro invocation
|
||||
|
|
||||
= help: add #![feature(non_modrs_mods)] to the crate attributes to enable
|
||||
= help: on stable builds, rename this file to mod_file_not_owning_aux1/mod.rs
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -1,15 +0,0 @@
|
||||
error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660)
|
||||
--> $DIR/mod_file_not_owning_aux1.rs:14:17
|
||||
|
|
||||
LL | () => { mod mod_file_not_owning_aux2; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | }
|
||||
LL | m!();
|
||||
| ----- in this macro invocation
|
||||
|
|
||||
= help: add #![feature(non_modrs_mods)] to the crate attributes to enable
|
||||
= help: on stable builds, rename this file to foo/mod.rs
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -1,28 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
//
|
||||
// Tests the formatting of the feature-gate errors for non_modrs_mods
|
||||
//
|
||||
// gate-test-non_modrs_mods
|
||||
// ignore-windows
|
||||
// ignore-pretty issue #37195
|
||||
pub mod modrs_mod;
|
||||
pub mod foors_mod;
|
||||
|
||||
#[path = "some_crazy_attr_mod_dir/arbitrary_name.rs"]
|
||||
pub mod attr_mod;
|
||||
|
||||
pub fn main() {
|
||||
modrs_mod::inner_modrs_mod::innest::foo();
|
||||
modrs_mod::inner_foors_mod::innest::foo();
|
||||
foors_mod::inner_modrs_mod::innest::foo();
|
||||
foors_mod::inner_foors_mod::innest::foo();
|
||||
attr_mod::inner_modrs_mod::innest::foo();
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660)
|
||||
--> $DIR/modrs_mod/inner_foors_mod.rs:11:9
|
||||
|
|
||||
LL | pub mod innest;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: add #![feature(non_modrs_mods)] to the crate attributes to enable
|
||||
= help: on stable builds, rename this file to inner_foors_mod/mod.rs
|
||||
|
||||
error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660)
|
||||
--> $DIR/foors_mod.rs:13:9
|
||||
|
|
||||
LL | pub mod inner_modrs_mod;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(non_modrs_mods)] to the crate attributes to enable
|
||||
= help: on stable builds, rename this file to foors_mod/mod.rs
|
||||
|
||||
error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660)
|
||||
--> $DIR/foors_mod.rs:14:9
|
||||
|
|
||||
LL | pub mod inner_foors_mod;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(non_modrs_mods)] to the crate attributes to enable
|
||||
= help: on stable builds, rename this file to foors_mod/mod.rs
|
||||
|
||||
error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660)
|
||||
--> $DIR/foors_mod/inner_foors_mod.rs:11:9
|
||||
|
|
||||
LL | pub mod innest;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: add #![feature(non_modrs_mods)] to the crate attributes to enable
|
||||
= help: on stable builds, rename this file to inner_foors_mod/mod.rs
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
1
src/test/ui/run-pass/issues/.gitattributes
vendored
Normal file
1
src/test/ui/run-pass/issues/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
issue-16278.rs -text
|
@ -13,8 +13,9 @@
|
||||
|
||||
// this file has some special \r\n endings (use xxd to see them)
|
||||
|
||||
fn main() {assert_eq!(b"", b"\
|
||||
fn main() {assert_eq!(b"", b"\
|
||||
");
|
||||
assert_eq!(b"\n", b"
|
||||
assert_eq!(b"\n", b"
|
||||
");
|
||||
}
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// run-pass
|
||||
//
|
||||
// ignore-pretty issue #37195
|
||||
#![feature(non_modrs_mods)]
|
||||
|
||||
pub mod modrs_mod;
|
||||
pub mod foors_mod;
|
||||
|
||||
#[path = "some_crazy_attr_mod_dir/arbitrary_name.rs"]
|
||||
pub mod attr_mod;
|
||||
|
||||
pub fn main() {
|
||||
modrs_mod::inner_modrs_mod::innest::foo();
|
||||
modrs_mod::inner_foors_mod::innest::foo();
|
||||
foors_mod::inner_modrs_mod::innest::foo();
|
||||
foors_mod::inner_foors_mod::innest::foo();
|
||||
attr_mod::inner_modrs_mod::innest::foo();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user