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
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:
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
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/
fn main() {
let x = 5;
}
-> rustc main.rs
+$ rustc main.rs
warning: unused variable: `x`
--> main.rs:2:9
|
This will produce this warning:
-```console
+```bash
$ rustc lib.rs --crate-type=lib
warning: unused variable: `x`
--> lib.rs:2:9
```
```bash
-> rustc main.rs
+$ rustc main.rs
error: bitshift exceeds the type's number of bits
--> main.rs:2:13
|
|
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
|
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
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() {}
/// 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
///
/// ```
}
}
+ /// 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.
///
//! 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")]
///
/// 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);
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.
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>),
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())
}
}
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;
/// 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);
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:
//
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 = [
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()));
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()));
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);
}
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();
}
}
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));
}
// 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");
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");
}
}
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)
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) => {
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|
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 {
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)
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)
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)
};
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
}
}
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,
Err(hir::LoopIdError::UnlabeledCfInWhileCondition) => {
self.emit_unlabled_cf_in_while_condition(e.span, "continue");
}
- _ => {}
+ Err(_) => {}
}
self.require_break_cx("continue", e.span)
},
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")
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);
}
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",
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",
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",
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);
}
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 {
}
#[must_use]
-#[derive(Debug, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq)]
enum Promotability {
Promotable,
NotPromotable
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,
}
}
}
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;
}
}
}
- 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
}
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) {
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),
}
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
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
}
debug!("Reference to Static(id={:?}) is unpromotable as it is not \
referenced from a static", did);
NotPromotable
-
}
}
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 {
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();
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
}
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.
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
}
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
}
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
}
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
}
// 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
}
}
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
// 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;
--- /dev/null
+// 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);
+ }
+}
use spec::HasTargetSpec;
mod aarch64;
+mod amdgpu;
mod arm;
mod asmjs;
mod hexagon;
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),
// 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(),
+ });
+ }
}
}
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() {
</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)?;
}
}
// 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]
//
/// 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.
///
/// [slice.len]: ../primitive.slice.html#method.len
/// [`Deref`]: ../ops/trait.Deref.html
/// [`CStr`]: struct.CStr.html
+/// [`&CStr`]: struct.CStr.html
///
/// # Examples
///
/// 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.
///
///
#[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
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
// 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),
(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`,
}
}
-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() {
};
let visitor = &mut PostExpansionVisitor { context: &ctx };
- visitor.whole_crate_feature_gates(krate);
visit::walk_crate(visitor, krate);
}
-Subproject commit 2a1cdeadd3ea8e1eba9cc681037b83f07332763b
+Subproject commit 5a081f0363340dd895d0958955d0c84661f60f05
# 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
lexer-crlf-line-endings-string-literal-doc-comment.rs -text
-issue-16278.rs -text
--- /dev/null
+// 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.
+
+pub struct MyStruct;
--- /dev/null
+// 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.
+
+// aux-build:issue-53689.rs
+
+#![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;
+}
+++ /dev/null
-// Copyright 2014 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.
-
-// error-pattern: mod statements in non-mod.rs files are unstable
-
-mod mod_file_not_owning_aux1;
-
-fn main() {}
+++ /dev/null
-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`.
+++ /dev/null
-// Copyright 2016 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.
-
-// error-pattern: mod statements in non-mod.rs files are unstable
-
-// This is not a directory owner since the file name is not "mod.rs".
-#[path = "mod_file_not_owning_aux1.rs"]
-mod foo;
+++ /dev/null
-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`.
+++ /dev/null
-// 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();
-}
+++ /dev/null
-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`.
--- /dev/null
+issue-16278.rs -text
// 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"\\r
");
-assert_eq!(b"\n", b"
+assert_eq!(b"\n", b"\r
");
}
+
+++ /dev/null
-// 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();
-}