Auto merge of #54711 - kennytm:rollup, r=kennytm

Rollup of 13 pull requests

Successful merges:

 - #53784 (Document that slices cannot be larger than `isize::MAX` bytes)
 - #54308 (Better user experience when attempting to call associated functions with dot notation)
 - #54488 (in which we include attributes in unused `extern crate` suggestion spans)
 - #54544 (Indicate how to move value out of Box in docs.)
 - #54623 (Added help message for `impl_trait_in_bindings` feature gate)
 - #54641 (A few cleanups and minor improvements to rustc/infer)
 - #54656 (Correct doc for WorkQueue<T>::pop().)
 - #54674 (update miri)
 - #54676 (Remove `-Z disable_ast_check_for_mutation_in_guard`)
 - #54679 (Improve bug! message for impossible case in Relate)
 - #54681 (Rename sanitizer runtime libraries on OSX)
 - #54708 (Make ./x.py help <cmd> invoke ./x.py <cmd> -h on its own)
 - #54713 (Add nightly check for tool_lints warning)
This commit is contained in:
bors 2018-10-01 10:16:00 +00:00
commit 6188c58a55
40 changed files with 493 additions and 300 deletions

View File

@ -844,6 +844,11 @@ def bootstrap(help_triggered):
def main():
"""Entry point for the bootstrap process"""
start_time = time()
# x.py help <cmd> ...
if len(sys.argv) > 1 and sys.argv[1] == 'help':
sys.argv = sys.argv[:1] + [sys.argv[2], '-h'] + sys.argv[3:]
help_triggered = (
'-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)
try:

View File

@ -249,7 +249,7 @@ impl Step for StdLink {
fn copy_apple_sanitizer_dylibs(builder: &Builder, native_dir: &Path, platform: &str, into: &Path) {
for &sanitizer in &["asan", "tsan"] {
let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let filename = format!("lib__rustc__clang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
let mut src_path = native_dir.join(sanitizer);
src_path.push("build");
src_path.push("lib");

View File

@ -178,6 +178,37 @@ pub struct NativeLibBoilerplate {
pub out_dir: PathBuf,
}
impl NativeLibBoilerplate {
/// On OSX we don't want to ship the exact filename that compiler-rt builds.
/// This conflicts with the system and ours is likely a wildly different
/// version, so they can't be substituted.
///
/// As a result, we rename it here but we need to also use
/// `install_name_tool` on OSX to rename the commands listed inside of it to
/// ensure it's linked against correctly.
pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) {
if env::var("TARGET").unwrap() != "x86_64-apple-darwin" {
return
}
let dir = self.out_dir.join("build/lib/darwin");
let name = format!("clang_rt.{}_osx_dynamic", sanitizer_name);
let src = dir.join(&format!("lib{}.dylib", name));
let new_name = format!("lib__rustc__{}.dylib", name);
let dst = dir.join(&new_name);
println!("{} => {}", src.display(), dst.display());
fs::rename(&src, &dst).unwrap();
let status = Command::new("install_name_tool")
.arg("-id")
.arg(format!("@rpath/{}", new_name))
.arg(&dst)
.status()
.expect("failed to execute `install_name_tool`");
assert!(status.success());
}
}
impl Drop for NativeLibBoilerplate {
fn drop(&mut self) {
if !thread::panicking() {
@ -229,7 +260,7 @@ pub fn native_lib_boilerplate(
pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
-> Result<(NativeLibBoilerplate, String), ()>
{
let (link_name, search_path, dynamic) = match &*env::var("TARGET").unwrap() {
let (link_name, search_path, apple) = match &*env::var("TARGET").unwrap() {
"x86_64-unknown-linux-gnu" => (
format!("clang_rt.{}-x86_64", sanitizer_name),
"build/lib/linux",
@ -242,8 +273,8 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
),
_ => return Err(()),
};
let to_link = if dynamic {
format!("dylib={}", link_name)
let to_link = if apple {
format!("dylib=__rustc__{}", link_name)
} else {
format!("static={}", link_name)
};

View File

@ -16,10 +16,18 @@
//!
//! # Examples
//!
//! Creating a box:
//! Move a value from the stack to the heap by creating a [`Box`]:
//!
//! ```
//! let x = Box::new(5);
//! let val: u8 = 5;
//! let boxed: Box<u8> = Box::new(val);
//! ```
//!
//! Move a value from a [`Box`] back to the stack by [dereferencing]:
//!
//! ```
//! let boxed: Box<u8> = Box::new(5);
//! let val: u8 = *boxed;
//! ```
//!
//! Creating a recursive data structure:
@ -52,6 +60,9 @@
//! elements are in the list, and so we don't know how much memory to allocate
//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how
//! big `Cons` needs to be.
//!
//! [dereferencing]: ../../std/ops/trait.Deref.html
//! [`Box`]: struct.Box.html
#![stable(feature = "rust1", since = "1.0.0")]

View File

@ -34,6 +34,7 @@ use cmp::Ordering::{self, Less, Equal, Greater};
use cmp;
use fmt;
use intrinsics::assume;
use isize;
use iter::*;
use ops::{FnMut, Try, self};
use option::Option;
@ -4080,6 +4081,9 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
/// them from other data. You can obtain a pointer that is usable as `data`
/// for zero-length slices using [`NonNull::dangling()`].
///
/// The total size of the slice must be no larger than `isize::MAX` **bytes**
/// in memory. See the safety documentation of [`pointer::offset`].
///
/// # Caveat
///
/// The lifetime for the returned slice is inferred from its usage. To
@ -4101,10 +4105,13 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
/// ```
///
/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
"attempt to create slice covering half the address space");
Repr { raw: FatPtr { data, len } }.rust
}
@ -4114,15 +4121,19 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
/// This function is unsafe for the same reasons as [`from_raw_parts`], as well
/// as not being able to provide a non-aliasing guarantee of the returned
/// mutable slice. `data` must be non-null and aligned even for zero-length
/// slices as with [`from_raw_parts`]. See the documentation of
/// [`from_raw_parts`] for more details.
/// slices as with [`from_raw_parts`]. The total size of the slice must be no
/// larger than `isize::MAX` **bytes** in memory.
///
/// See the documentation of [`from_raw_parts`] for more details.
///
/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
Repr { raw: FatPtr { data, len} }.rust_mut
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
"attempt to create slice covering half the address space");
Repr { raw: FatPtr { data, len } }.rust_mut
}
/// Converts a reference to T into a slice of length 1 (without copying).

View File

@ -54,6 +54,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::thin_vec::ThinVec;
use session::Session;
use session::config::nightly_options;
use util::common::FN_OUTPUT_NAME;
use util::nodemap::{DefIdMap, NodeMap};
@ -188,16 +189,28 @@ enum ImplTraitContext<'a> {
Existential(Option<DefId>),
/// `impl Trait` is not accepted in this position.
Disallowed,
Disallowed(ImplTraitPosition),
}
/// Position in which `impl Trait` is disallowed. Used for error reporting.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum ImplTraitPosition {
Binding,
Other,
}
impl<'a> ImplTraitContext<'a> {
#[inline]
fn disallowed() -> Self {
ImplTraitContext::Disallowed(ImplTraitPosition::Other)
}
fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
use self::ImplTraitContext::*;
match self {
Universal(params) => Universal(params),
Existential(did) => Existential(*did),
Disallowed => Disallowed,
Disallowed(pos) => Disallowed(*pos),
}
}
}
@ -1142,7 +1155,7 @@ impl<'a> LoweringContext<'a> {
generic_params: this.lower_generic_params(
&f.generic_params,
&NodeMap(),
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
),
unsafety: this.lower_unsafety(f.unsafety),
abi: f.abi,
@ -1255,20 +1268,27 @@ impl<'a> LoweringContext<'a> {
}),
))
}
ImplTraitContext::Disallowed => {
ImplTraitContext::Disallowed(pos) => {
let allowed_in = if self.sess.features_untracked()
.impl_trait_in_bindings {
"bindings or function and inherent method return types"
} else {
"function and inherent method return types"
};
span_err!(
let mut err = struct_span_err!(
self.sess,
t.span,
E0562,
"`impl Trait` not allowed outside of {}",
allowed_in,
);
if pos == ImplTraitPosition::Binding &&
nightly_options::is_nightly_build() {
help!(err,
"add #![feature(impl_trait_in_bindings)] to the crate attributes \
to enable");
}
err.emit();
hir::TyKind::Err
}
}
@ -1742,7 +1762,7 @@ impl<'a> LoweringContext<'a> {
param_mode,
0,
ParenthesizedGenericArgs::Err,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
)
})
.chain(ident.map(|ident| hir::PathSegment::from_ident(ident)))
@ -1872,9 +1892,11 @@ impl<'a> LoweringContext<'a> {
self.with_anonymous_lifetime_mode(
AnonymousLifetimeMode::PassThrough,
|this| {
const DISALLOWED: ImplTraitContext<'_> = ImplTraitContext::Disallowed;
let &ParenthesisedArgs { ref inputs, ref output, span } = data;
let inputs = inputs.iter().map(|ty| this.lower_ty_direct(ty, DISALLOWED)).collect();
let inputs = inputs
.iter()
.map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
.collect();
let mk_tup = |this: &mut Self, tys, span| {
let LoweredNodeId { node_id, hir_id } = this.next_id();
hir::Ty { node: hir::TyKind::Tup(tys), id: node_id, hir_id, span }
@ -1889,7 +1911,7 @@ impl<'a> LoweringContext<'a> {
ident: Ident::from_str(FN_OUTPUT_NAME),
ty: output
.as_ref()
.map(|ty| this.lower_ty(&ty, DISALLOWED))
.map(|ty| this.lower_ty(&ty, ImplTraitContext::disallowed()))
.unwrap_or_else(|| P(mk_tup(this, hir::HirVec::new(), span))),
span: output.as_ref().map_or(span, |ty| ty.span),
}
@ -1921,7 +1943,7 @@ impl<'a> LoweringContext<'a> {
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::Existential(Some(parent_def_id))
} else {
ImplTraitContext::Disallowed
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
}
)),
pat: self.lower_pat(&l.pat),
@ -1983,7 +2005,7 @@ impl<'a> LoweringContext<'a> {
if let Some((_, ref mut ibty)) = in_band_ty_params {
self.lower_ty_direct(&arg.ty, ImplTraitContext::Universal(ibty))
} else {
self.lower_ty_direct(&arg.ty, ImplTraitContext::Disallowed)
self.lower_ty_direct(&arg.ty, ImplTraitContext::disallowed())
}
})
.collect::<HirVec<_>>();
@ -1999,9 +2021,12 @@ impl<'a> LoweringContext<'a> {
match decl.output {
FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
Some((def_id, _)) if impl_trait_return_allow => {
hir::Return(self.lower_ty(ty, ImplTraitContext::Existential(Some(def_id))))
hir::Return(self.lower_ty(ty,
ImplTraitContext::Existential(Some(def_id))))
}
_ => {
hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed()))
}
_ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
},
FunctionRetTy::Default(span) => hir::DefaultReturn(span),
}
@ -2369,7 +2394,7 @@ impl<'a> LoweringContext<'a> {
span: ident.span,
kind: hir::GenericParamKind::Type {
default: default.as_ref().map(|x| {
self.lower_ty(x, ImplTraitContext::Disallowed)
self.lower_ty(x, ImplTraitContext::disallowed())
}),
synthetic: param.attrs.iter()
.filter(|attr| attr.check_name("rustc_synthetic"))
@ -2472,9 +2497,9 @@ impl<'a> LoweringContext<'a> {
bound_generic_params: this.lower_generic_params(
bound_generic_params,
&NodeMap(),
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
),
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
bounds: bounds
.iter()
.filter_map(|bound| match *bound {
@ -2483,7 +2508,7 @@ impl<'a> LoweringContext<'a> {
GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
_ => Some(this.lower_param_bound(
bound,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
)),
})
.collect(),
@ -2499,7 +2524,7 @@ impl<'a> LoweringContext<'a> {
}) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
span,
lifetime: self.lower_lifetime(lifetime),
bounds: self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
}),
WherePredicate::EqPredicate(WhereEqPredicate {
id,
@ -2508,8 +2533,8 @@ impl<'a> LoweringContext<'a> {
span,
}) => hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
id: self.lower_node_id(id).node_id,
lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::Disallowed),
rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::Disallowed),
lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
span,
}),
}
@ -2579,7 +2604,7 @@ impl<'a> LoweringContext<'a> {
None => Ident::new(Symbol::intern(&index.to_string()), f.span),
},
vis: self.lower_visibility(&f.vis, None),
ty: self.lower_ty(&f.ty, ImplTraitContext::Disallowed),
ty: self.lower_ty(&f.ty, ImplTraitContext::disallowed()),
attrs: self.lower_attrs(&f.attrs),
}
}
@ -2686,7 +2711,7 @@ impl<'a> LoweringContext<'a> {
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::Existential(None)
} else {
ImplTraitContext::Disallowed
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
}
),
self.lower_mutability(m),
@ -2701,7 +2726,7 @@ impl<'a> LoweringContext<'a> {
if self.sess.features_untracked().impl_trait_in_bindings {
ImplTraitContext::Existential(None)
} else {
ImplTraitContext::Disallowed
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
}
),
value
@ -2740,12 +2765,12 @@ impl<'a> LoweringContext<'a> {
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
ItemKind::Ty(ref t, ref generics) => hir::ItemKind::Ty(
self.lower_ty(t, ImplTraitContext::Disallowed),
self.lower_generics(generics, ImplTraitContext::Disallowed),
self.lower_ty(t, ImplTraitContext::disallowed()),
self.lower_generics(generics, ImplTraitContext::disallowed()),
),
ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential(hir::ExistTy {
generics: self.lower_generics(generics, ImplTraitContext::Disallowed),
bounds: self.lower_param_bounds(b, ImplTraitContext::Disallowed),
generics: self.lower_generics(generics, ImplTraitContext::disallowed()),
bounds: self.lower_param_bounds(b, ImplTraitContext::disallowed()),
impl_trait_fn: None,
}),
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
@ -2756,20 +2781,20 @@ impl<'a> LoweringContext<'a> {
.map(|x| self.lower_variant(x))
.collect(),
},
self.lower_generics(generics, ImplTraitContext::Disallowed),
self.lower_generics(generics, ImplTraitContext::disallowed()),
),
ItemKind::Struct(ref struct_def, ref generics) => {
let struct_def = self.lower_variant_data(struct_def);
hir::ItemKind::Struct(
struct_def,
self.lower_generics(generics, ImplTraitContext::Disallowed),
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
ItemKind::Union(ref vdata, ref generics) => {
let vdata = self.lower_variant_data(vdata);
hir::ItemKind::Union(
vdata,
self.lower_generics(generics, ImplTraitContext::Disallowed),
self.lower_generics(generics, ImplTraitContext::disallowed()),
)
}
ItemKind::Impl(
@ -2802,7 +2827,7 @@ impl<'a> LoweringContext<'a> {
AnonymousLifetimeMode::CreateParameter,
|this, _| {
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed())
});
if let Some(ref trait_ref) = trait_ref {
@ -2811,7 +2836,7 @@ impl<'a> LoweringContext<'a> {
}
}
let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed);
let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed());
(trait_ref, lowered_ty)
},
@ -2838,7 +2863,7 @@ impl<'a> LoweringContext<'a> {
)
}
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
let bounds = self.lower_param_bounds(bounds, ImplTraitContext::Disallowed);
let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
let items = items
.iter()
.map(|item| self.lower_trait_item_ref(item))
@ -2846,14 +2871,14 @@ impl<'a> LoweringContext<'a> {
hir::ItemKind::Trait(
self.lower_is_auto(is_auto),
self.lower_unsafety(unsafety),
self.lower_generics(generics, ImplTraitContext::Disallowed),
self.lower_generics(generics, ImplTraitContext::disallowed()),
bounds,
items,
)
}
ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
self.lower_generics(generics, ImplTraitContext::Disallowed),
self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
self.lower_generics(generics, ImplTraitContext::disallowed()),
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
),
ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
}
@ -3043,9 +3068,9 @@ impl<'a> LoweringContext<'a> {
let (generics, node) = match i.node {
TraitItemKind::Const(ref ty, ref default) => (
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
hir::TraitItemKind::Const(
self.lower_ty(ty, ImplTraitContext::Disallowed),
self.lower_ty(ty, ImplTraitContext::disallowed()),
default
.as_ref()
.map(|x| self.lower_body(None, |this| this.lower_expr(x))),
@ -3077,12 +3102,12 @@ impl<'a> LoweringContext<'a> {
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
}
TraitItemKind::Type(ref bounds, ref default) => (
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
hir::TraitItemKind::Type(
self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
default
.as_ref()
.map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
.map(|x| self.lower_ty(x, ImplTraitContext::disallowed())),
),
),
TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@ -3132,9 +3157,9 @@ impl<'a> LoweringContext<'a> {
ImplItemKind::Const(ref ty, ref expr) => {
let body_id = self.lower_body(None, |this| this.lower_expr(expr));
(
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
hir::ImplItemKind::Const(
self.lower_ty(ty, ImplTraitContext::Disallowed),
self.lower_ty(ty, ImplTraitContext::disallowed()),
body_id,
),
)
@ -3152,13 +3177,13 @@ impl<'a> LoweringContext<'a> {
(generics, hir::ImplItemKind::Method(sig, body_id))
}
ImplItemKind::Type(ref ty) => (
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::Disallowed)),
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::disallowed())),
),
ImplItemKind::Existential(ref bounds) => (
self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
hir::ImplItemKind::Existential(
self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
),
),
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@ -3349,7 +3374,8 @@ impl<'a> LoweringContext<'a> {
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
}
ForeignItemKind::Static(ref t, m) => {
hir::ForeignItemKind::Static(self.lower_ty(t, ImplTraitContext::Disallowed), m)
hir::ForeignItemKind::Static(
self.lower_ty(t, ImplTraitContext::disallowed()), m)
}
ForeignItemKind::Ty => hir::ForeignItemKind::Type,
ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
@ -3488,7 +3514,7 @@ impl<'a> LoweringContext<'a> {
&None,
path,
ParamMode::Optional,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
);
self.check_self_struct_ctor_feature(&qpath);
hir::PatKind::TupleStruct(
@ -3503,7 +3529,7 @@ impl<'a> LoweringContext<'a> {
qself,
path,
ParamMode::Optional,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
);
self.check_self_struct_ctor_feature(&qpath);
hir::PatKind::Path(qpath)
@ -3514,7 +3540,7 @@ impl<'a> LoweringContext<'a> {
&None,
path,
ParamMode::Optional,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
);
let fs = fields
@ -3608,7 +3634,7 @@ impl<'a> LoweringContext<'a> {
ParamMode::Optional,
0,
ParenthesizedGenericArgs::Err,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
);
let args = args.iter().map(|x| self.lower_expr(x)).collect();
hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args)
@ -3627,11 +3653,11 @@ impl<'a> LoweringContext<'a> {
ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((**l).clone())),
ExprKind::Cast(ref expr, ref ty) => {
let expr = P(self.lower_expr(expr));
hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::Disallowed))
hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
}
ExprKind::Type(ref expr, ref ty) => {
let expr = P(self.lower_expr(expr));
hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::Disallowed))
hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
}
ExprKind::AddrOf(m, ref ohs) => {
let m = self.lower_mutability(m);
@ -3900,7 +3926,7 @@ impl<'a> LoweringContext<'a> {
qself,
path,
ParamMode::Optional,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
);
self.check_self_struct_ctor_feature(&qpath);
hir::ExprKind::Path(qpath)
@ -3965,7 +3991,7 @@ impl<'a> LoweringContext<'a> {
&None,
path,
ParamMode::Optional,
ImplTraitContext::Disallowed,
ImplTraitContext::disallowed(),
),
fields.iter().map(|x| self.lower_field(x)).collect(),
maybe_expr.as_ref().map(|x| P(self.lower_expr(x))),

View File

@ -135,10 +135,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
);
// Select everything, returning errors.
let true_errors = match fulfill_cx.select_where_possible(self) {
Ok(()) => vec![],
Err(errors) => errors,
};
let true_errors = fulfill_cx.select_where_possible(self).err().unwrap_or_else(Vec::new);
debug!("true_errors = {:#?}", true_errors);
if !true_errors.is_empty() {
@ -148,10 +145,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
}
// Anything left unselected *now* must be an ambiguity.
let ambig_errors = match fulfill_cx.select_all_or_error(self) {
Ok(()) => vec![],
Err(errors) => errors,
};
let ambig_errors = fulfill_cx.select_all_or_error(self).err().unwrap_or_else(Vec::new);
debug!("ambig_errors = {:#?}", ambig_errors);
let region_obligations = self.take_registered_region_obligations();
@ -316,16 +310,18 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
}
// ...also include the other query region constraints from the query.
output_query_region_constraints.reserve(query_result.value.region_constraints.len());
for r_c in query_result.value.region_constraints.iter() {
let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
let k1 = substitute_value(self.tcx, &result_subst, &k1);
let r2 = substitute_value(self.tcx, &result_subst, &r2);
if k1 != r2.into() {
output_query_region_constraints
.push(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)));
}
}
output_query_region_constraints.extend(
query_result.value.region_constraints.iter().filter_map(|r_c| {
let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
let k1 = substitute_value(self.tcx, &result_subst, &k1);
let r2 = substitute_value(self.tcx, &result_subst, &r2);
if k1 != r2.into() {
Some(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)))
} else {
None
}
})
);
let user_result: R =
query_result.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
@ -448,10 +444,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
.variables
.iter()
.enumerate()
.map(|(index, info)| match opt_values[CanonicalVar::new(index)] {
Some(k) => k,
None => self.fresh_inference_var_for_canonical_var(cause.span, *info),
})
.map(|(index, info)| opt_values[CanonicalVar::new(index)].unwrap_or_else(||
self.fresh_inference_var_for_canonical_var(cause.span, *info)
))
.collect(),
};
@ -504,24 +499,22 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
let k1 = substitute_value(self.tcx, result_subst, k1);
let r2 = substitute_value(self.tcx, result_subst, r2);
match k1.unpack() {
UnpackedKind::Lifetime(r1) => Obligation::new(
cause.clone(),
param_env,
ty::Predicate::RegionOutlives(ty::Binder::dummy(
ty::OutlivesPredicate(r1, r2),
)),
),
UnpackedKind::Type(t1) => Obligation::new(
cause.clone(),
param_env,
ty::Predicate::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
t1, r2,
))),
),
}
}),
Obligation::new(
cause.clone(),
param_env,
match k1.unpack() {
UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
ty::Binder::dummy(
ty::OutlivesPredicate(r1, r2)
)),
UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives(
ty::Binder::dummy(ty::OutlivesPredicate(
t1, r2
)))
}
)
})
) as Box<dyn Iterator<Item = _>>
}
@ -583,31 +576,30 @@ pub fn make_query_outlives<'tcx>(
assert!(verifys.is_empty());
assert!(givens.is_empty());
let mut outlives: Vec<_> = constraints
.into_iter()
.map(|(k, _)| match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
tcx.mk_region(ty::ReVar(v2)).into(),
tcx.mk_region(ty::ReVar(v1)),
),
Constraint::VarSubReg(v1, r2) => {
ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
}
Constraint::RegSubVar(r1, v2) => {
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
})
.map(ty::Binder::dummy) // no bound regions in the code above
.collect();
outlives.extend(
outlives_obligations
.map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
.map(ty::Binder::dummy), // no bound regions in the code above
);
let outlives: Vec<_> = constraints
.into_iter()
.map(|(k, _)| match *k {
// Swap regions because we are going from sub (<=) to outlives
// (>=).
Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
tcx.mk_region(ty::ReVar(v2)).into(),
tcx.mk_region(ty::ReVar(v1)),
),
Constraint::VarSubReg(v1, r2) => {
ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
}
Constraint::RegSubVar(r1, v2) => {
ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
}
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
})
.map(ty::Binder::dummy) // no bound regions in the code above
.chain(
outlives_obligations
.map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
.map(ty::Binder::dummy), // no bound regions in the code above
)
.collect();
outlives
}

View File

@ -77,24 +77,22 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
match (&a.sty, &b.sty) {
(&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
infcx.type_variables.borrow_mut().equate(a_id, b_id);
Ok(a)
}
(&ty::Infer(TyVar(a_id)), _) => {
self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?;
Ok(a)
}
(_, &ty::Infer(TyVar(b_id))) => {
self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
Ok(a)
}
_ => {
self.fields.infcx.super_combine_tys(self, a, b)?;
Ok(a)
}
}
Ok(a)
}
fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)

View File

@ -406,10 +406,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
errors.clone()
} else {
errors
.iter()
.filter(|&e| !is_bound_failure(e))
.cloned()
.collect()
.iter()
.filter(|&e| !is_bound_failure(e))
.cloned()
.collect()
};
// sort the errors by span, for better error message stability.
@ -455,11 +455,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
TypeError::Sorts(ref exp_found) => {
// if they are both "path types", there's a chance of ambiguity
// due to different versions of the same crate
match (&exp_found.expected.sty, &exp_found.found.sty) {
(&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) => {
report_path_match(err, exp_adt.did, found_adt.did);
}
_ => (),
if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _))
= (&exp_found.expected.sty, &exp_found.found.sty)
{
report_path_match(err, exp_adt.did, found_adt.did);
}
}
TypeError::Traits(ref exp_found) => {

View File

@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let mut labels = vec![(
span,
if &name == "_" {
"cannot infer type".to_string()
"cannot infer type".to_owned()
} else {
format!("cannot infer type for `{}`", name)
},
@ -138,7 +138,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// ```
labels.clear();
labels.push(
(pattern.span, "consider giving this closure parameter a type".to_string()));
(pattern.span, "consider giving this closure parameter a type".to_owned()));
} else if let Some(pattern) = local_visitor.found_local_pattern {
if let Some(simple_ident) = pattern.simple_ident() {
match pattern.span.compiler_desugaring_kind() {
@ -146,12 +146,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
format!("consider giving `{}` a type", simple_ident))),
Some(CompilerDesugaringKind::ForLoop) => labels.push((
pattern.span,
"the element type for this iterator is not specified".to_string(),
"the element type for this iterator is not specified".to_owned(),
)),
_ => {}
}
} else {
labels.push((pattern.span, "consider giving the pattern a type".to_string()));
labels.push((pattern.span, "consider giving the pattern a type".to_owned()));
}
}

View File

@ -113,12 +113,12 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
(None, None) => {
let (main_label_1, span_label_1) = if ty_sup.id == ty_sub.id {
(
"this type is declared with multiple lifetimes...".to_string(),
"...but data with one lifetime flows into the other here".to_string()
"this type is declared with multiple lifetimes...".to_owned(),
"...but data with one lifetime flows into the other here".to_owned()
)
} else {
(
"these two types are declared with different lifetimes...".to_string(),
"these two types are declared with different lifetimes...".to_owned(),
format!(
"...but data{} flows{} here",
span_label_var1,
@ -133,7 +133,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
ty_sub.span,
ret_span,
"this parameter and the return type are declared \
with different lifetimes...".to_string()
with different lifetimes...".to_owned()
,
format!("...but data{} is returned here", span_label_var1),
),
@ -141,7 +141,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
ty_sup.span,
ret_span,
"this parameter and the return type are declared \
with different lifetimes...".to_string()
with different lifetimes...".to_owned()
,
format!("...but data{} is returned here", span_label_var1),
),

View File

@ -58,18 +58,17 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
&RegionKind::ReFree(ref free_region)) = (&sub_origin, sup_region) {
let hir = &self.tcx.hir;
if let Some(node_id) = hir.as_local_node_id(free_region.scope) {
match hir.get(node_id) {
Node::Expr(Expr {
node: Closure(_, _, _, closure_span, None),
..
}) => {
let sup_sp = sup_origin.span();
let origin_sp = origin.span();
let mut err = self.tcx.sess.struct_span_err(
sup_sp,
"borrowed data cannot be stored outside of its closure");
err.span_label(sup_sp, "cannot be stored outside of its closure");
if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
if let Node::Expr(Expr {
node: Closure(_, _, _, closure_span, None),
..
}) = hir.get(node_id) {
let sup_sp = sup_origin.span();
let origin_sp = origin.span();
let mut err = self.tcx.sess.struct_span_err(
sup_sp,
"borrowed data cannot be stored outside of its closure");
err.span_label(sup_sp, "cannot be stored outside of its closure");
if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
// // sup_sp == origin.span():
//
// let mut x = None;
@ -87,11 +86,11 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
// ------------ ... because it cannot outlive this closure
// f = Some(x);
// ^ cannot be stored outside of its closure
err.span_label(*external_span,
"borrowed data cannot be stored into here...");
err.span_label(*closure_span,
"...because it cannot outlive this closure");
} else {
err.span_label(*external_span,
"borrowed data cannot be stored into here...");
err.span_label(*closure_span,
"...because it cannot outlive this closure");
} else {
// FIXME: the wording for this case could be much improved
//
// let mut lines_to_use: Vec<&CrateId> = Vec::new();
@ -102,18 +101,16 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
// ...so that variable is valid at time of its declaration
// lines_to_use.push(installed_id);
// ^^^^^^^^^^^^ cannot be stored outside of its closure
err.span_label(origin_sp,
"cannot infer an appropriate lifetime...");
err.span_label(*external_span,
"...so that variable is valid at time of its \
declaration");
err.span_label(*closure_span,
"borrowed data cannot outlive this closure");
}
err.emit();
return Some(ErrorReported);
err.span_label(origin_sp,
"cannot infer an appropriate lifetime...");
err.span_label(*external_span,
"...so that variable is valid at time of its \
declaration");
err.span_label(*closure_span,
"borrowed data cannot outlive this closure");
}
_ => {}
err.emit();
return Some(ErrorReported);
}
}
}

View File

@ -20,64 +20,62 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
/// Print the error message for lifetime errors when the return type is a static impl Trait.
pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
if let Some(ref error) = self.error {
match error.clone() {
RegionResolutionError::SubSupConflict(
if let RegionResolutionError::SubSupConflict(
var_origin,
sub_origin,
sub_r,
sup_origin,
sup_r,
) => {
let anon_reg_sup = self.tcx.is_suitable_region(sup_r)?;
if sub_r == &RegionKind::ReStatic &&
self.tcx.return_type_impl_trait(anon_reg_sup.def_id).is_some()
{
let sp = var_origin.span();
let return_sp = sub_origin.span();
let mut err = self.tcx.sess.struct_span_err(
sp,
"cannot infer an appropriate lifetime",
);
err.span_label(
return_sp,
"this return type evaluates to the `'static` lifetime...",
);
err.span_label(
sup_origin.span(),
"...but this borrow...",
);
) = error.clone()
{
let anon_reg_sup = self.tcx.is_suitable_region(sup_r)?;
if sub_r == &RegionKind::ReStatic &&
self.tcx.return_type_impl_trait(anon_reg_sup.def_id).is_some()
{
let sp = var_origin.span();
let return_sp = sub_origin.span();
let mut err = self.tcx.sess.struct_span_err(
sp,
"cannot infer an appropriate lifetime",
);
err.span_label(
return_sp,
"this return type evaluates to the `'static` lifetime...",
);
err.span_label(
sup_origin.span(),
"...but this borrow...",
);
let (lifetime, lt_sp_opt) = self.tcx.msg_span_from_free_region(sup_r);
if let Some(lifetime_sp) = lt_sp_opt {
err.span_note(
lifetime_sp,
&format!("...can't outlive {}", lifetime),
);
}
let lifetime_name = match sup_r {
RegionKind::ReFree(FreeRegion {
bound_region: BoundRegion::BrNamed(_, ref name), ..
}) => name.to_string(),
_ => "'_".to_owned(),
};
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) {
err.span_suggestion_with_applicability(
return_sp,
&format!(
"you can add a constraint to the return type to make it last \
less than `'static` and match {}",
lifetime,
),
format!("{} + {}", snippet, lifetime_name),
Applicability::Unspecified,
);
}
err.emit();
return Some(ErrorReported);
let (lifetime, lt_sp_opt) = self.tcx.msg_span_from_free_region(sup_r);
if let Some(lifetime_sp) = lt_sp_opt {
err.span_note(
lifetime_sp,
&format!("...can't outlive {}", lifetime),
);
}
let lifetime_name = match sup_r {
RegionKind::ReFree(FreeRegion {
bound_region: BoundRegion::BrNamed(_, ref name), ..
}) => name.to_string(),
_ => "'_".to_owned(),
};
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) {
err.span_suggestion_with_applicability(
return_sp,
&format!(
"you can add a constraint to the return type to make it last \
less than `'static` and match {}",
lifetime,
),
format!("{} + {}", snippet, lifetime_name),
Applicability::Unspecified,
);
}
err.emit();
return Some(ErrorReported);
}
_ => {}
}
}
None

View File

@ -119,16 +119,13 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
decl: &hir::FnDecl,
) -> Option<Span> {
let ret_ty = self.tcx.type_of(scope_def_id);
match ret_ty.sty {
ty::FnDef(_, _) => {
let sig = ret_ty.fn_sig(self.tcx);
let late_bound_regions = self.tcx
.collect_referenced_late_bound_regions(&sig.output());
if late_bound_regions.iter().any(|r| *r == br) {
return Some(decl.output.span());
}
if let ty::FnDef(_, _) = ret_ty.sty {
let sig = ret_ty.fn_sig(self.tcx);
let late_bound_regions = self.tcx
.collect_referenced_late_bound_regions(&sig.output());
if late_bound_regions.iter().any(|r| *r == br) {
return Some(decl.output.span());
}
_ => {}
}
None
}
@ -140,8 +137,8 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
pub(super) fn is_self_anon(&self, is_first: bool, scope_def_id: DefId) -> bool {
is_first
&& self.tcx
.opt_associated_item(scope_def_id)
.map(|i| i.method_has_self_argument) == Some(true)
.opt_associated_item(scope_def_id)
.map(|i| i.method_has_self_argument) == Some(true)
}
}

View File

@ -112,12 +112,9 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
}
};
match dump_region_data_to(region_rels, &region_data.constraints, &output_path) {
Ok(()) => {}
Err(e) => {
let msg = format!("io error dumping region constraints: {}", e);
tcx.sess.err(&msg)
}
if let Err(e) = dump_region_data_to(region_rels, &region_data.constraints, &output_path) {
let msg = format!("io error dumping region constraints: {}", e);
tcx.sess.err(&msg)
}
}
@ -187,12 +184,9 @@ impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
None => bug!("no node_id found for node: {:?}", n),
};
let name = || format!("node_{}", node_id);
match dot::Id::new(name()) {
Ok(id) => id,
Err(_) => {
bug!("failed to create graphviz node identified by {}", name());
}
}
dot::Id::new(name()).unwrap_or_else(|_|
bug!("failed to create graphviz node identified by {}", name()))
}
fn node_label(&self, n: &Node) -> dot::LabelText<'_> {
match *n {
@ -204,7 +198,7 @@ impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
match *e {
Edge::Constraint(ref c) =>
dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap())),
Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_string()),
Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_owned()),
}
}
}

View File

@ -147,9 +147,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
fn construct_var_data(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> LexicalRegionResolutions<'tcx> {
LexicalRegionResolutions {
error_region: tcx.types.re_static,
values: (0..self.num_vars())
.map(|_| VarValue::Value(tcx.types.re_empty))
.collect(),
values: IndexVec::from_elem_n(VarValue::Value(tcx.types.re_empty), self.num_vars())
}
}

View File

@ -803,6 +803,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
);
debug!("instantiate_opaque_types: ty_var={:?}", ty_var);
self.obligations.reserve(bounds.predicates.len());
for predicate in bounds.predicates {
// Change the predicate to refer to the type variable,
// which will be the concrete type instead of the opaque type.

View File

@ -443,7 +443,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
assert!(self.undo_log[snapshot.length] == OpenSnapshot);
if snapshot.length == 0 {
self.undo_log.truncate(0);
self.undo_log.clear();
} else {
(*self.undo_log)[snapshot.length] = CommitedSnapshot;
}
@ -661,11 +661,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
debug!("RegionConstraintCollector: add_verify({:?})", verify);
// skip no-op cases known to be satisfied
match verify.bound {
VerifyBound::AllBounds(ref bs) if bs.len() == 0 => {
if let VerifyBound::AllBounds(ref bs) = verify.bound {
if bs.len() == 0 {
return;
}
_ => {}
}
let index = self.data.verifys.len();

View File

@ -153,8 +153,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if !t.needs_infer() && !ty::keep_local(&t) {
t // micro-optimize -- if there is nothing in this type that this fold affects...
// ^ we need to have the `keep_local` check to un-default
// defaulted tuples.
// ^ we need to have the `keep_local` check to un-default
// defaulted tuples.
} else {
let t = self.infcx.shallow_resolve(t);
match t.sty {

View File

@ -273,11 +273,8 @@ impl<'tcx> TypeVariableTable<'tcx> {
pub fn rollback_to(&mut self, s: Snapshot<'tcx>) {
debug!("rollback_to{:?}", {
for action in self.values.actions_since_snapshot(&s.snapshot) {
match *action {
sv::UndoLog::NewElem(index) => {
debug!("inference variable _#{}t popped", index)
}
_ => { }
if let sv::UndoLog::NewElem(index) = *action {
debug!("inference variable _#{}t popped", index)
}
}
});

View File

@ -18,7 +18,7 @@ use lint::context::CheckLintNameResult;
use lint::{self, Lint, LintId, Level, LintSource};
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
StableHasher, StableHasherResult};
use session::Session;
use session::{config::nightly_options, Session};
use syntax::ast;
use syntax::attr;
use syntax::source_map::MultiSpan;
@ -299,7 +299,13 @@ impl<'a> LintLevelsBuilder<'a> {
"change it to",
new_lint_name.to_string(),
Applicability::MachineApplicable,
).emit();
);
if nightly_options::is_nightly_build() {
err.emit();
} else {
err.cancel();
}
let src = LintSource::Node(Symbol::intern(&new_lint_name), li.span);
for id in ids {

View File

@ -1322,8 +1322,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
useful for profiling / PGO."),
relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
"choose which RELRO level to use"),
disable_ast_check_for_mutation_in_guard: bool = (false, parse_bool, [UNTRACKED],
"skip AST-based mutation-in-guard check (mir-borrowck provides more precise check)"),
nll_subminimal_causes: bool = (false, parse_bool, [UNTRACKED],
"when tracking region error causes, accept subminimal results for faster execution."),
nll_facts: bool = (false, parse_bool, [UNTRACKED],

View File

@ -1467,11 +1467,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// If true, we should use a naive AST walk to determine if match
/// guard could perform bad mutations (or mutable-borrows).
pub fn check_for_mutation_in_guard_via_ast_walk(self) -> bool {
// If someone passes the `-Z` flag, they're asking for the footgun.
if self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard {
return false;
}
// If someone requests the feature, then be a little more
// careful and ensure that MIR-borrowck is enabled (which can
// happen via edition selection, via `feature(nll)`, or via an

View File

@ -702,7 +702,12 @@ impl<'tcx> Relate<'tcx> for Kind<'tcx> {
(UnpackedKind::Type(a_ty), UnpackedKind::Type(b_ty)) => {
Ok(relation.relate(&a_ty, &b_ty)?.into())
}
(UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => bug!()
(UnpackedKind::Lifetime(unpacked), x) => {
bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
}
(UnpackedKind::Type(unpacked), x) => {
bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
}
}
}
}

View File

@ -31,6 +31,7 @@ fn main() {
.out_dir(&native.out_dir)
.build_target(&target)
.build();
native.fixup_sanitizer_lib_name("asan");
}
println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
}

View File

@ -53,7 +53,7 @@ impl<T: Idx> WorkQueue<T> {
}
}
/// Attempt to enqueue `element` in the work queue. Returns false if it was already present.
/// Attempt to pop an element from the work queue.
#[inline]
pub fn pop(&mut self) -> Option<T> {
if let Some(element) = self.deque.pop_front() {

View File

@ -3147,11 +3147,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
// parser issue where a struct literal is being used on an expression
// where a brace being opened means a block is being started. Look
// ahead for the next text to see if `span` is followed by a `{`.
let cm = this.session.source_map();
let sm = this.session.source_map();
let mut sp = span;
loop {
sp = cm.next_point(sp);
match cm.span_to_snippet(sp) {
sp = sm.next_point(sp);
match sm.span_to_snippet(sp) {
Ok(ref snippet) => {
if snippet.chars().any(|c| { !c.is_whitespace() }) {
break;
@ -3160,20 +3160,51 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
_ => break,
}
}
let followed_by_brace = match cm.span_to_snippet(sp) {
let followed_by_brace = match sm.span_to_snippet(sp) {
Ok(ref snippet) if snippet == "{" => true,
_ => false,
};
if let (PathSource::Expr(None), true) = (source, followed_by_brace) {
err.span_label(
span,
format!("did you mean `({} {{ /* fields */ }})`?", path_str),
);
} else {
err.span_label(
span,
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
);
match source {
PathSource::Expr(Some(parent)) => {
match parent.node {
ExprKind::MethodCall(ref path_assignment, _) => {
err.span_suggestion_with_applicability(
sm.start_point(parent.span)
.to(path_assignment.ident.span),
"use `::` to access an associated function",
format!("{}::{}",
path_str,
path_assignment.ident),
Applicability::MaybeIncorrect
);
return (err, candidates);
},
_ => {
err.span_label(
span,
format!("did you mean `{} {{ /* fields */ }}`?",
path_str),
);
return (err, candidates);
},
}
},
PathSource::Expr(None) if followed_by_brace == true => {
err.span_label(
span,
format!("did you mean `({} {{ /* fields */ }})`?",
path_str),
);
return (err, candidates);
},
_ => {
err.span_label(
span,
format!("did you mean `{} {{ /* fields */ }}`?",
path_str),
);
return (err, candidates);
},
}
}
return (err, candidates);

View File

@ -31,6 +31,7 @@ fn main() {
.out_dir(&native.out_dir)
.build_target(&target)
.build();
native.fixup_sanitizer_lib_name("tsan");
}
println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
}

View File

@ -138,9 +138,15 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
if extern_crate.warn_if_unused {
if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) {
let msg = "unused extern crate";
// Removal suggestion span needs to include attributes (Issue #54400)
let span_with_attrs = tcx.get_attrs(extern_crate.def_id).iter()
.map(|attr| attr.span)
.fold(span, |acc, attr_span| acc.to(attr_span));
tcx.struct_span_lint_node(lint, id, span, msg)
.span_suggestion_short_with_applicability(
span,
span_with_attrs,
"remove it",
String::new(),
Applicability::MachineApplicable)

View File

@ -12,12 +12,11 @@
// This test illustrates that under NLL, we can remove our overly
// conservative approach for disallowing mutations of match inputs.
// See further discussion on rust-lang/rust#24535 and
// rust-lang/rfcs#1006.
// compile-flags: -Z disable-ast-check-for-mutation-in-guard
// See further discussion on rust-lang/rust#24535,
// rust-lang/rfcs#1006, and rust-lang/rfcs#107
#![feature(nll)]
#![feature(bind_by_move_pattern_guards)]
fn main() {
rust_issue_24535();

View File

@ -9,12 +9,16 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r
|
LL | const FOO: impl Copy = 42;
| ^^^^^^^^^
|
= help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> $DIR/feature-gate-impl_trait_in_bindings.rs:13:13
|
LL | static BAR: impl Copy = 42;
| ^^^^^^^^^
|
= help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable
error: aborting due to 3 previous errors

View File

@ -231,6 +231,8 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r
|
LL | let _in_local_variable: impl Fn() = || {};
| ^^^^^^^^^
|
= help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> $DIR/where-allowed.rs:232:46

View File

@ -15,8 +15,8 @@
// reject it. But I want to make sure that we continue to reject it
// (under NLL) even when that conservaive check goes away.
// compile-flags: -Z disable-ast-check-for-mutation-in-guard
#![feature(bind_by_move_pattern_guards)]
#![feature(nll)]
fn main() {

View File

@ -5,8 +5,8 @@
// Test that we don't allow mutating the value being matched on in a way that
// changes which patterns it matches, until we have chosen an arm.
// compile-flags: -Zdisable-ast-check-for-mutation-in-guard
#![feature(bind_by_move_pattern_guards)]
#![feature(nll)]
fn ok_mutation_in_guard(mut q: i32) {

View File

@ -0,0 +1,13 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn main() {
let _ = String.new();
}

View File

@ -0,0 +1,11 @@
error[E0423]: expected value, found struct `String`
--> $DIR/issue-22692.rs:12:13
|
LL | let _ = String.new();
| ^^^^^^----
| |
| help: use `::` to access an associated function: `String::new`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0423`.

View File

@ -0,0 +1,24 @@
// 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:edition-lint-paths.rs
// run-rustfix
// compile-flags:--extern edition_lint_paths --cfg blandiloquence
// edition:2018
#![deny(rust_2018_idioms)]
#![allow(dead_code)]
// The suggestion span should include the attribute.
//~^ ERROR unused extern crate
fn main() {}

View File

@ -0,0 +1,25 @@
// 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:edition-lint-paths.rs
// run-rustfix
// compile-flags:--extern edition_lint_paths --cfg blandiloquence
// edition:2018
#![deny(rust_2018_idioms)]
#![allow(dead_code)]
// The suggestion span should include the attribute.
#[cfg(blandiloquence)] //~ HELP remove it
extern crate edition_lint_paths;
//~^ ERROR unused extern crate
fn main() {}

View File

@ -0,0 +1,18 @@
error: unused extern crate
--> $DIR/issue-54400-unused-extern-crate-attr-span.rs:22:1
|
LL | / #[cfg(blandiloquence)] //~ HELP remove it
LL | | extern crate edition_lint_paths;
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |________________________________|
| help: remove it
|
note: lint level defined here
--> $DIR/issue-54400-unused-extern-crate-attr-span.rs:16:9
|
LL | #![deny(rust_2018_idioms)]
| ^^^^^^^^^^^^^^^^
= note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
error: aborting due to previous error

@ -1 +1 @@
Subproject commit 130d803b3243a92f5c2d9230935cba7fa88e263e
Subproject commit e8f6973e2d40ab39e30cdbe0cf8e77a72c867d4f