cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
- // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.
- if self.config.deny_warnings && !(mode == Mode::Std && stage == 0) {
+ if self.config.deny_warnings {
cargo.env("RUSTC_DENY_WARNINGS", "1");
}
RustdocBook, "src/doc/rustdoc", "rustdoc", default=true;
RustcBook, "src/doc/rustc", "rustc", default=true;
RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false;
+ EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false;
TheBook, "src/doc/book", "book", default=false;
UnstableBook, "src/doc/unstable-book", "unstable-book", default=true;
);
name = "build_helper"
version = "0.1.0"
authors = ["The Rust Project Developers"]
+edition = "2018"
[lib]
name = "build_helper"
+#![deny(rust_2018_idioms)]
+
use std::fs::File;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
+#![cfg(not(miri))]
+
use std::any::Any;
use std::sync::{Arc, Weak};
use std::cell::RefCell;
//
// Destructors must be called exactly once per element.
#[test]
+#[cfg(not(miri))]
fn panic_safe() {
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
+#![cfg(not(miri))]
+
mod map;
mod set;
+#![cfg(not(miri))]
+
use std::alloc::{Global, Alloc, Layout, System};
/// https://github.com/rust-lang/rust/issues/45955
+#![cfg(not(miri))]
+
use std::any::Any;
use std::rc::{Rc, Weak};
use std::cell::RefCell;
+#![cfg(not(miri))]
+
use std::cell::Cell;
use std::cmp::Ordering::{self, Equal, Greater, Less};
use std::mem;
}
#[test]
+#[cfg(not(miri))]
fn test_collect() {
let empty = "";
let s: String = empty.chars().collect();
#[test]
fn test_concat_for_different_lengths() {
let empty: &[&str] = &[];
+ #[cfg(not(miri))]
test_concat!("", empty);
test_concat!("a", ["a"]);
test_concat!("ab", ["a", "b"]);
#[test]
fn test_join_for_different_lengths() {
let empty: &[&str] = &[];
+ #[cfg(not(miri))]
test_join!("", empty, "-");
test_join!("a", ["a"], "-");
test_join!("a-b", ["a", "b"], "-");
assert_eq!("~~~~~".len(), 15);
let empty: &[&str] = &[];
+ #[cfg(not(miri))]
test_join!("", empty, "~~~~~");
test_join!("a", ["a"], "~~~~~");
test_join!("a~~~~~b", ["a", "b"], "~~~~~");
}
#[test]
+#[cfg(not(miri))]
fn test_unsafe_slice() {
assert_eq!("ab", unsafe {"abc".get_unchecked(0..2)});
assert_eq!("bc", unsafe {"abc".get_unchecked(1..3)});
#[test]
fn test_replace() {
let a = "a";
+ #[cfg(not(miri))]
assert_eq!("".replace(a, "b"), "");
assert_eq!("a".replace(a, "b"), "b");
assert_eq!("ab".replace(a, "b"), "bb");
// The current implementation of SliceIndex fails to handle methods
// orthogonally from range types; therefore, it is worth testing
// all of the indexing operations on each input.
+#[cfg(not(miri))]
mod slice_index {
// Test a slicing operation **that should succeed,**
// testing it on all of the indexing methods.
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_str_slice_rangetoinclusive_notok() {
let s = "abcαβγ";
&s[..=3];
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_str_slicemut_rangetoinclusive_notok() {
let mut s = "abcαβγ".to_owned();
let s: &mut str = &mut s;
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_as_bytes_fail() {
// Don't double free. (I'm not sure if this exercises the
// original problem code path anymore.)
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_split_at_boundscheck() {
let s = "ศไทย中华Việt Nam";
s.split_at(1);
}
#[test]
+#[cfg(not(miri))]
fn test_chars_decoding() {
let mut bytes = [0; 4];
for c in (0..0x110000).filter_map(std::char::from_u32) {
}
#[test]
+#[cfg(not(miri))]
fn test_chars_rev_decoding() {
let mut bytes = [0; 4];
for c in (0..0x110000).filter_map(std::char::from_u32) {
}
#[test]
+#[cfg(not(miri))]
fn test_str_default() {
use std::default::Default;
assert_eq!("not even a boolean".parse::<bool>().ok(), None);
}
+#[cfg(not(miri))]
fn check_contains_all_substrings(s: &str) {
assert!(s.contains(""));
for i in 0..s.len() {
}
#[test]
+#[cfg(not(miri))]
fn strslice_issue_16589() {
assert!("bananas".contains("nana"));
}
#[test]
+#[cfg(not(miri))]
fn strslice_issue_16878() {
assert!(!"1234567ah012345678901ah".contains("hah"));
assert!(!"00abc01234567890123456789abc".contains("bcabc"));
#[test]
+#[cfg(not(miri))]
fn test_strslice_contains() {
let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
check_contains_all_substrings(x);
#[test]
fn to_lowercase() {
+ #[cfg(not(miri))]
assert_eq!("".to_lowercase(), "");
assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
#[test]
fn to_uppercase() {
+ #[cfg(not(miri))]
assert_eq!("".to_uppercase(), "");
assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
}
}
#[test]
+#[cfg(not(miri))]
fn test_repeat() {
assert_eq!("".repeat(3), "");
assert_eq!("abc".repeat(0), "");
+#![cfg(not(miri))]
+
use std::borrow::Cow;
use std::collections::CollectionAllocErr::*;
use std::mem::size_of;
+#![cfg(not(miri))]
+
use std::borrow::Cow;
use std::mem::size_of;
use std::{usize, isize};
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_index_out_of_bounds() {
let mut deq = VecDeque::new();
for i in 1..4 {
// normal append
a.append(&mut b);
assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+ #[cfg(not(miri))]
assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
// append nothing to something
a.append(&mut b);
assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+ #[cfg(not(miri))]
assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
// append something to nothing
b.append(&mut a);
assert_eq!(b.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+ #[cfg(not(miri))]
assert_eq!(a.iter().cloned().collect::<Vec<_>>(), []);
}
#[test]
+#[cfg(not(miri))]
fn test_append_permutations() {
fn construct_vec_deque(
push_back: usize,
}
#[test]
+#[cfg(not(miri))]
fn test_try_reserve() {
// These are the interesting cases:
}
#[test]
+#[cfg(not(miri))]
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
+#![cfg(not(miri))]
+
use core::cell::*;
use core::default::Default;
use std::mem::drop;
+#![cfg(not(miri))]
+
mod builders;
mod float;
mod num;
+#![cfg(not(miri))]
+
mod sip;
use std::hash::{Hash, Hasher};
}
#[test]
+#[cfg(not(miri))]
fn test_iterator_step_by_nth() {
let mut it = (0..16).step_by(5);
assert_eq!(it.nth(0), Some(0));
}
#[test]
+#[cfg(not(miri))]
fn test_iterator_step_by_nth_overflow() {
#[cfg(target_pointer_width = "8")]
type Bigger = u16;
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_iterator_step_by_zero() {
let mut it = (0..).step_by(0);
it.next();
}
#[test]
+#[cfg(not(miri))]
fn test_iterator_step_by_size_hint() {
struct StubSizeHint(usize, Option<usize>);
impl Iterator for StubSizeHint {
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_rposition_panic() {
let v: [(Box<_>, Box<_>); 4] =
[(box 0, box 0), (box 0, box 0),
}
#[test]
+#[cfg(not(miri))]
fn test_range_step() {
#![allow(deprecated)]
}
#[test]
+#[cfg(not(miri))]
fn test_step_by_skip() {
assert_eq!((0..640).step_by(128).skip(1).collect::<Vec<_>>(), [128, 256, 384, 512]);
assert_eq!((0..=50).step_by(10).nth(3), Some(30));
}
#[test]
+#[cfg(not(miri))]
fn test_range_inclusive_step() {
assert_eq!((0..=50).step_by(10).collect::<Vec<_>>(), [0, 10, 20, 30, 40, 50]);
assert_eq!((0..=5).step_by(1).collect::<Vec<_>>(), [0, 1, 2, 3, 4, 5]);
+#![cfg(not(miri))]
+
use core::convert::{TryFrom, TryInto};
use core::cmp::PartialEq;
use core::fmt::Debug;
}
#[test] #[should_panic]
+#[cfg(not(miri))]
fn test_option_too_much_dance() {
struct A;
let mut y = Some(A);
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_unwrap_panic1() {
let x: Option<isize> = None;
x.unwrap();
#[test]
#[should_panic]
+#[cfg(not(miri))]
fn test_unwrap_panic2() {
let x: Option<String> = None;
x.unwrap();
+#![cfg(not(miri))]
+
use core::ptr::*;
use core::cell::RefCell;
#[test]
#[should_panic]
+#[cfg(not(miri))]
pub fn test_unwrap_or_else_panic() {
fn handler(msg: &'static str) -> isize {
if msg == "I got this." {
}
#[test]
#[should_panic(expected="Got expected error: \"All good\"")]
+#[cfg(not(miri))]
pub fn test_expect_err() {
let err: Result<isize, &'static str> = Err("All good");
err.expect("Got expected error");
}
#[test]
#[should_panic(expected="Got expected ok: \"All good\"")]
+#[cfg(not(miri))]
pub fn test_expect_err_ok() {
let err: Result<&'static str, isize> = Ok("All good");
err.expect_err("Got expected ok");
// to be used in `should_panic`)
#[test]
#[should_panic(expected = "out of range")]
+ #[cfg(not(miri))]
fn assert_range_eq_can_fail_by_panic() {
assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]);
}
// to be used in `should_panic`)
#[test]
#[should_panic(expected = "==")]
+ #[cfg(not(miri))]
fn assert_range_eq_can_fail_by_inequality() {
assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]);
}
#[test]
#[should_panic(expected = $expect_msg)]
+ #[cfg(not(miri))]
fn index_fail() {
let v = $data;
let v: &[_] = &v;
#[test]
#[should_panic(expected = $expect_msg)]
+ #[cfg(not(miri))]
fn index_mut_fail() {
let mut v = $data;
let v: &mut [_] = &mut v;
#[test]
#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(miri))]
fn sort_unstable() {
use core::cmp::Ordering::{Equal, Greater, Less};
use core::slice::heapsort;
}
#[test]
+#[cfg(not(miri))]
fn test_align_to_simple() {
let bytes = [1u8, 2, 3, 4, 5, 6, 7];
let (prefix, aligned, suffix) = unsafe { bytes.align_to::<u16>() };
}
#[test]
+#[cfg(not(miri))]
fn test_align_to_zst() {
let bytes = [1, 2, 3, 4, 5, 6, 7];
let (prefix, aligned, suffix) = unsafe { bytes.align_to::<()>() };
}
#[test]
+#[cfg(not(miri))]
fn test_align_to_non_trivial() {
#[repr(align(8))] struct U64(u64, u64);
#[repr(align(8))] struct U64U64U32(u64, u64, u32);
}
#[test]
+#[cfg(not(miri))]
fn test_align_to_empty_mid() {
use core::mem;
#[test]
#[should_panic(expected = "src is out of bounds")]
+#[cfg(not(miri))]
fn test_copy_within_panics_src_too_long() {
let mut bytes = *b"Hello, World!";
// The length is only 13, so 14 is out of bounds.
#[test]
#[should_panic(expected = "dest is out of bounds")]
+#[cfg(not(miri))]
fn test_copy_within_panics_dest_too_long() {
let mut bytes = *b"Hello, World!";
// The length is only 13, so a slice of length 4 starting at index 10 is out of bounds.
}
#[test]
#[should_panic(expected = "src end is before src start")]
+#[cfg(not(miri))]
fn test_copy_within_panics_src_inverted() {
let mut bytes = *b"Hello, World!";
// 2 is greater than 1, so this range is invalid.
+#![cfg(not(miri))]
+
use core::time::Duration;
#[test]
AssociatedExistential(DefId),
PrimTy(hir::PrimTy),
TyParam(DefId),
+ ConstParam(DefId),
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) |
Def::TyAlias(id) | Def::TraitAlias(id) |
- Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
+ Def::AssociatedTy(id) | Def::TyParam(id) | Def::ConstParam(id) | Def::Struct(id) |
+ Def::StructCtor(id, ..) |
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
Def::AssociatedConst(id) | Def::Macro(id, ..) |
Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) => {
Def::Const(..) => "constant",
Def::AssociatedConst(..) => "associated constant",
Def::TyParam(..) => "type parameter",
+ Def::ConstParam(..) => "const parameter",
Def::PrimTy(..) => "builtin type",
Def::Local(..) => "local variable",
Def::Upvar(..) => "closure capture",
match arg {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)),
ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty_direct(&ty, itctx)),
+ ast::GenericArg::Const(ct) => {
+ // FIXME(const_generics): const generics are not yet defined in the HIR.
+ self.sess.struct_span_err(
+ ct.value.span,
+ "const generics in any position are currently unsupported",
+ ).emit();
+ self.sess.abort_if_errors();
+ bug!();
+ }
}
}
|this| this.lower_param_bounds(¶m.bounds, itctx.reborrow()),
);
- match param.kind {
+ let (name, kind) = match param.kind {
GenericParamKind::Lifetime => {
let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
self.is_collecting_in_band_lifetimes = false;
| hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
hir::LifetimeName::Error => ParamName::Error,
};
- let param = hir::GenericParam {
- id: lt.id,
- hir_id: lt.hir_id,
- name: param_name,
- span: lt.span,
- pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"),
- attrs: self.lower_attrs(¶m.attrs),
- bounds,
- kind: hir::GenericParamKind::Lifetime {
- kind: hir::LifetimeParamKind::Explicit,
- }
+
+ let kind = hir::GenericParamKind::Lifetime {
+ kind: hir::LifetimeParamKind::Explicit
};
self.is_collecting_in_band_lifetimes = was_collecting_in_band;
- param
+ (param_name, kind)
}
GenericParamKind::Type { ref default, .. } => {
// Don't expose `Self` (recovered "keyword used as ident" parse error).
.chain(params)
.collect();
}
- let LoweredNodeId { node_id, hir_id } = self.lower_node_id(param.id);
- hir::GenericParam {
- id: node_id,
- hir_id,
- name: hir::ParamName::Plain(ident),
- pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"),
- attrs: self.lower_attrs(¶m.attrs),
- bounds,
- span: ident.span,
- kind: hir::GenericParamKind::Type {
- default: default.as_ref().map(|x| {
- self.lower_ty(x, ImplTraitContext::disallowed())
- }),
- synthetic: param.attrs.iter()
- .filter(|attr| attr.check_name("rustc_synthetic"))
- .map(|_| hir::SyntheticTyParamKind::ImplTrait)
- .next(),
- }
- }
+ let kind = hir::GenericParamKind::Type {
+ default: default.as_ref().map(|x| {
+ self.lower_ty(x, ImplTraitContext::disallowed())
+ }),
+ synthetic: param.attrs.iter()
+ .filter(|attr| attr.check_name("rustc_synthetic"))
+ .map(|_| hir::SyntheticTyParamKind::ImplTrait)
+ .next(),
+ };
+
+ (hir::ParamName::Plain(ident), kind)
}
+ GenericParamKind::Const { .. } => {
+ // FIXME(const_generics): const generics are not yet defined in the HIR.
+ self.sess.struct_span_err(
+ param.ident.span,
+ "const generics in any position are currently unsupported",
+ ).emit();
+ self.sess.abort_if_errors();
+ bug!();
+ }
+ };
+
+ let LoweredNodeId { node_id, hir_id } = self.lower_node_id(param.id);
+
+ hir::GenericParam {
+ id: node_id,
+ hir_id,
+ name,
+ span: param.ident.span,
+ pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"),
+ attrs: self.lower_attrs(¶m.attrs),
+ bounds,
+ kind,
}
}
let def_path_data = match param.kind {
GenericParamKind::Lifetime { .. } => DefPathData::LifetimeParam(name),
GenericParamKind::Type { .. } => DefPathData::TypeParam(name),
+ GenericParamKind::Const { .. } => DefPathData::ConstParam(name),
};
self.create_def(param.id, def_path_data, REGULAR_SPACE, param.ident.span);
/// A closure expression
ClosureExpr,
// Subportions of items
- /// A type parameter (generic parameter)
+ /// A type (generic) parameter
TypeParam(InternedString),
- /// A lifetime definition
+ /// A lifetime (generic) parameter
LifetimeParam(InternedString),
+ /// A const (generic) parameter
+ ConstParam(InternedString),
/// A variant of a enum
EnumVariant(InternedString),
/// A struct field
MacroDef(name) |
TypeParam(name) |
LifetimeParam(name) |
+ ConstParam(name) |
EnumVariant(name) |
Field(name) |
GlobalMetaData(name) => Some(name),
MacroDef(name) |
TypeParam(name) |
LifetimeParam(name) |
+ ConstParam(name) |
EnumVariant(name) |
Field(name) |
GlobalMetaData(name) => {
AssociatedExistential(def_id),
PrimTy(prim_ty),
TyParam(def_id),
+ ConstParam(def_id),
SelfTy(trait_def_id, impl_def_id),
ForeignTy(def_id),
Fn(def_id),
"outlives requirements can be inferred"
}
+declare_lint! {
+ pub DUPLICATE_MATCHER_BINDING_NAME,
+ Warn,
+ "duplicate macro matcher binding name"
+}
+
/// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`.
pub mod parser {
declare_lint! {
use crate::hir::def_id::{CrateNum, LOCAL_CRATE};
use crate::hir::intravisit;
use crate::hir;
-use crate::lint::builtin::BuiltinLintDiagnostics;
+use crate::lint::builtin::{BuiltinLintDiagnostics, DUPLICATE_MATCHER_BINDING_NAME};
use crate::lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT};
use crate::session::{Session, DiagnosticMessageId};
use std::{hash, ptr};
match lint_id {
BufferedEarlyLintId::QuestionMarkMacroSep => QUESTION_MARK_MACRO_SEP,
BufferedEarlyLintId::IllFormedAttributeInput => ILL_FORMED_ATTRIBUTE_INPUT,
+ BufferedEarlyLintId::DuplicateMacroMatcherBindingName => DUPLICATE_MATCHER_BINDING_NAME,
}
}
span,
ty,
user_ty: None,
- literal: tcx.intern_lazy_const(
+ literal: tcx.mk_lazy_const(
ty::LazyConst::Evaluated(ty::Const::zero_sized(ty)),
),
})
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let substs = tcx.lift_to_global(&substs).unwrap();
let evaluated = evaluated.subst(tcx, substs);
- return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
} else {
promoted: None
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
- return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
}
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let substs = tcx.lift_to_global(&substs).unwrap();
let evaluated = evaluated.subst(tcx, substs);
- return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
} else {
promoted: None,
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
- return tcx.intern_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
}
}
}
where D: TyDecoder<'a, 'tcx>,
'tcx: 'a,
{
- Ok(decoder.tcx().intern_lazy_const(Decodable::decode(decoder)?))
+ Ok(decoder.tcx().mk_lazy_const(Decodable::decode(decoder)?))
}
#[inline]
goal: InternedSet<'tcx, GoalKind<'tcx>>,
goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind<'tcx>>>,
+ lazy_const: InternedSet<'tcx, LazyConst<'tcx>>,
}
impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
goal: Default::default(),
goal_list: Default::default(),
projs: Default::default(),
+ lazy_const: Default::default(),
}
}
self.global_arenas.adt_def.alloc(def)
}
- pub fn intern_const_alloc(
- self,
- alloc: Allocation,
- ) -> &'gcx Allocation {
+ pub fn intern_const_alloc(self, alloc: Allocation) -> &'gcx Allocation {
self.allocation_interner.borrow_mut().intern(alloc, |alloc| {
self.global_arenas.const_allocs.alloc(alloc)
})
})
}
- pub fn intern_lazy_const(self, c: ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- self.global_interners.arena.alloc(c)
- }
-
pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
self.layout_interner.borrow_mut().intern(layout, |layout| {
self.global_arenas.layout.alloc(layout)
}
}
+impl<'tcx: 'lcx, 'lcx> Borrow<LazyConst<'lcx>> for Interned<'tcx, LazyConst<'tcx>> {
+ fn borrow<'a>(&'a self) -> &'a LazyConst<'lcx> {
+ &self.0
+ }
+}
+
impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]>
for Interned<'tcx, List<ExistentialPredicate<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] {
direct_interners!('tcx,
region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
- goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>
+ goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>,
+ lazy_const: mk_lazy_const(|c: &LazyConst<'_>| keep_local(&c)) -> LazyConst<'tcx>
);
macro_rules! slice_interners {
#[inline]
pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
- self.mk_ty(Array(ty, self.intern_lazy_const(
+ self.mk_ty(Array(ty, self.mk_lazy_const(
ty::LazyConst::Evaluated(ty::Const::from_usize(self.global_tcx(), n))
)))
}
data @ DefPathData::Module(..) |
data @ DefPathData::TypeParam(..) |
data @ DefPathData::LifetimeParam(..) |
+ data @ DefPathData::ConstParam(..) |
data @ DefPathData::EnumVariant(..) |
data @ DefPathData::Field(..) |
data @ DefPathData::AnonConst |
ty::LazyConst::Unevaluated(*def_id, substs.fold_with(folder))
}
};
- folder.tcx().intern_lazy_const(new)
+ folder.tcx().mk_lazy_const(new)
}
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
DefPathData::ClosureExpr |
DefPathData::TypeParam(_) |
DefPathData::LifetimeParam(_) |
+ DefPathData::ConstParam(_) |
DefPathData::Field(_) |
DefPathData::StructCtor |
DefPathData::AnonConst |
authors = ["The Rust Project Developers"]
name = "rustc_allocator"
version = "0.0.0"
+edition = "2018"
[lib]
path = "lib.rs"
+use log::debug;
use rustc::middle::allocator::AllocatorKind;
-use rustc_errors;
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
use syntax::{
ast::{
self, Arg, Attribute, Crate, Expr, FnHeader, Generics, Ident, Item, ItemKind,
};
use syntax_pos::Span;
-use {AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
+use crate::{AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
pub fn modify(
sess: &ParseSess,
in_submod: isize,
}
-impl<'a> MutVisitor for ExpandAllocatorDirectives<'a> {
+impl MutVisitor for ExpandAllocatorDirectives<'_> {
fn flat_map_item(&mut self, item: P<Item>) -> SmallVec<[P<Item>; 1]> {
debug!("in submodule {}", self.in_submod);
cx: ExtCtxt<'a>,
}
-impl<'a> AllocFnFactory<'a> {
+impl AllocFnFactory<'_> {
fn allocator_fn(&self, method: &AllocatorMethod) -> P<Item> {
let mut abi_args = Vec::new();
let mut i = 0;
-#![feature(nll)]
#![feature(rustc_private)]
-#[macro_use] extern crate log;
-extern crate rustc;
-extern crate rustc_data_structures;
-extern crate rustc_errors;
-extern crate rustc_target;
-extern crate syntax;
-extern crate syntax_pos;
-#[macro_use]
-extern crate smallvec;
+#![deny(rust_2018_idioms)]
pub mod expand;
authors = ["The Rust Project Developers"]
name = "rustc_borrowck"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_borrowck"
log = "0.4"
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
-graphviz = { path = "../libgraphviz" }
+# for "clarity", rename the graphviz crate to dot; graphviz within `borrowck`
+# refers to the borrowck-specific graphviz adapter traits.
+dot = { path = "../libgraphviz", package = "graphviz" }
rustc = { path = "../librustc" }
rustc_mir = { path = "../librustc_mir" }
-rustc_errors = { path = "../librustc_errors" }
-rustc_data_structures = { path = "../librustc_data_structures" }
\ No newline at end of file
+errors = { path = "../librustc_errors", package = "rustc_errors" }
+rustc_data_structures = { path = "../librustc_data_structures" }
// 3. assignments do not affect things loaned out as immutable
// 4. moves do not affect things loaned out in any way
-use self::UseError::*;
+use UseError::*;
-use borrowck::*;
-use borrowck::InteriorKind::{InteriorElement, InteriorField};
+use crate::borrowck::*;
+use crate::borrowck::InteriorKind::{InteriorElement, InteriorField};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::expr_use_visitor::MutateMode;
use rustc::middle::mem_categorization as mc;
use rustc::hir;
use rustc::hir::Node;
use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
+use log::debug;
use std::rc::Rc;
fn matched_pat(&mut self,
_matched_pat: &hir::Pat,
- _cmt: &mc::cmt_,
+ _cmt: &mc::cmt_<'_>,
_mode: euv::MatchMode) { }
fn consume_pat(&mut self,
pub fn report_illegal_mutation(&self,
span: Span,
loan_path: &LoanPath<'tcx>,
- loan: &Loan) {
+ loan: &Loan<'_>) {
self.bccx.cannot_assign_to_borrowed(
span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast)
.emit();
//! Computes moves.
-use borrowck::*;
-use borrowck::gather_loans::move_error::MovePlace;
-use borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector};
-use borrowck::move_data::*;
+use crate::borrowck::*;
+use crate::borrowck::gather_loans::move_error::MovePlace;
+use crate::borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector};
+use crate::borrowck::move_data::*;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use syntax_pos::Span;
use rustc::hir::*;
use rustc::hir::Node;
+use log::debug;
struct GatherMoveInfo<'c, 'tcx: 'c> {
id: hir::ItemLocalId,
//! This module implements the check that the lifetime of a borrow
//! does not exceed the lifetime of the value being borrowed.
-use borrowck::*;
+use crate::borrowck::*;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use syntax::ast;
use syntax_pos::Span;
+use log::debug;
type R = Result<(),()>;
// their associated scopes. In phase two, checking loans, we will then make
// sure that all of these loans are honored.
-use borrowck::*;
-use borrowck::move_data::MoveData;
+use crate::borrowck::*;
+use crate::borrowck::move_data::MoveData;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use syntax::ast;
use syntax_pos::Span;
use rustc::hir;
+use log::debug;
-use self::restrictions::RestrictionResult;
+use restrictions::RestrictionResult;
mod lifetime;
mod restrictions;
// }
}
- pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath) {
+ pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath<'_>) {
//! For mutable loans of content whose mutability derives
//! from a local variable, mark the mutability decl as necessary.
-use borrowck::BorrowckCtxt;
+use crate::borrowck::BorrowckCtxt;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::middle::mem_categorization::NoteClosureEnv;
use syntax::ast;
use syntax_pos;
use errors::{DiagnosticBuilder, Applicability};
-use borrowck::gather_loans::gather_moves::PatternSource;
+use crate::borrowck::gather_loans::gather_moves::PatternSource;
+use log::debug;
pub struct MoveErrorCollector<'tcx> {
errors: Vec<MoveError<'tcx>>
}
}
-fn note_move_destination(mut err: DiagnosticBuilder,
+fn note_move_destination(mut err: DiagnosticBuilder<'_>,
move_to_span: syntax_pos::Span,
pat_name: ast::Name,
- is_first_note: bool) -> DiagnosticBuilder {
+ is_first_note: bool) -> DiagnosticBuilder<'_> {
if is_first_note {
err.span_label(
move_to_span,
//! Computes the restrictions that result from a borrow.
-use borrowck::*;
+use crate::borrowck::*;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
use rustc::ty;
use syntax_pos::Span;
+use log::debug;
-use borrowck::ToInteriorKind;
+use crate::borrowck::ToInteriorKind;
use std::rc::Rc;
#![allow(non_camel_case_types)]
-pub use self::LoanPathKind::*;
-pub use self::LoanPathElem::*;
-pub use self::bckerr_code::*;
-pub use self::AliasableViolationKind::*;
-pub use self::MovedValueUseKind::*;
+pub use LoanPathKind::*;
+pub use LoanPathElem::*;
+pub use bckerr_code::*;
+pub use AliasableViolationKind::*;
+pub use MovedValueUseKind::*;
-use self::InteriorKind::*;
+use InteriorKind::*;
use rustc::hir::HirId;
use rustc::hir::Node;
use syntax::ast;
use syntax_pos::{MultiSpan, Span};
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use log::debug;
use rustc::hir;
-use dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom};
+use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom};
pub mod check_loans;
});
}
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
borrowck,
..*providers
}
fn closure_to_block(closure_id: LocalDefId,
- tcx: TyCtxt) -> ast::NodeId {
+ tcx: TyCtxt<'_, '_, '_>) -> ast::NodeId {
let closure_id = tcx.hir().local_def_id_to_node_id(closure_id);
match tcx.hir().get(closure_id) {
Node::Expr(expr) => match expr.node {
}
fn note_immutability_blame(&self,
- db: &mut DiagnosticBuilder,
- blame: Option<ImmutabilityBlame>,
+ db: &mut DiagnosticBuilder<'_>,
+ blame: Option<ImmutabilityBlame<'_>>,
error_node_id: ast::NodeId) {
match blame {
None => {}
// binding: either to make the binding mutable (if its type is
// not a mutable reference) or to avoid borrowing altogether
fn note_immutable_local(&self,
- db: &mut DiagnosticBuilder,
+ db: &mut DiagnosticBuilder<'_>,
borrowed_node_id: ast::NodeId,
binding_node_id: ast::NodeId) {
let let_span = self.tcx.hir().span(binding_node_id);
}
}
- fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder, err: &BckError<'a, 'tcx>,
+ fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder<'_>, err: &BckError<'a, 'tcx>,
error_span: &Span) {
match err.cmt.note {
mc::NoteClosureEnv(upvar_id) | mc::NoteUpvarRef(upvar_id) => {
}
impl<'tcx> fmt::Debug for InteriorKind {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
InteriorField(mc::FieldIndex(_, info)) => write!(f, "{}", info),
InteriorElement => write!(f, "[]"),
}
impl<'tcx> fmt::Debug for Loan<'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Loan_{}({:?}, {:?}, {:?}-{:?}, {:?})",
self.index,
self.loan_path,
}
impl<'tcx> fmt::Debug for LoanPath<'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
LpVar(id) => {
write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_string(id)))
}
impl<'tcx> fmt::Display for LoanPath<'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
LpVar(id) => {
write!(f, "$({})", ty::tls::with(|tcx| tcx.hir().node_to_user_string(id)))
//! Data structures used for tracking moves. Please see the extensive
//! comments in the section "Moves and initialization" in `README.md`.
-pub use self::MoveKind::*;
+pub use MoveKind::*;
-use dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom};
+use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom};
-use borrowck::*;
+use crate::borrowck::*;
use rustc::cfg;
use rustc::ty::{self, TyCtxt};
use rustc::util::nodemap::FxHashMap;
use std::usize;
use syntax_pos::Span;
use rustc::hir;
+use log::debug;
#[derive(Default)]
pub struct MoveData<'tcx> {
pub type AssignDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, AssignDataFlowOperator>;
-fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
+fn loan_path_is_precise(loan_path: &LoanPath<'_>) -> bool {
match loan_path.kind {
LpVar(_) | LpUpvar(_) => {
true
/// killed by scoping. See `README.md` for more details.
fn add_gen_kills(&self,
bccx: &BorrowckCtxt<'a, 'tcx>,
- dfcx_moves: &mut MoveDataFlow,
- dfcx_assign: &mut AssignDataFlow) {
+ dfcx_moves: &mut MoveDataFlow<'_, '_>,
+ dfcx_assign: &mut AssignDataFlow<'_, '_>) {
for (i, the_move) in self.moves.borrow().iter().enumerate() {
dfcx_moves.add_gen(the_move.id, i);
}
path: MovePathIndex,
kill_id: hir::ItemLocalId,
kill_kind: KillFrom,
- dfcx_moves: &mut MoveDataFlow) {
+ dfcx_moves: &mut MoveDataFlow<'_, '_>) {
// We can only perform kills for paths that refer to a unique location,
// since otherwise we may kill a move from one location with an
// assignment referring to another location.
use std::slice;
use syntax::ptr::P;
-use borrowck::BorrowckCtxt;
+use crate::borrowck::BorrowckCtxt;
pub fn check<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, body: &'tcx hir::Body) {
let mut used_mut = bccx.used_mut_nodes.borrow().clone();
use std::mem;
use std::usize;
use syntax::print::pprust::PrintState;
+use log::debug;
use rustc_data_structures::graph::implementation::OUTGOING;
fn initial_value(&self) -> bool;
}
-struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
+struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O> {
dfcx: &'a mut DataFlowContext<'b, 'tcx, O>,
changed: bool
}
}
impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> {
- fn nested(&self, state: &mut pprust::State, nested: pprust::Nested) -> io::Result<()> {
+ fn nested(&self, state: &mut pprust::State<'_>, nested: pprust::Nested) -> io::Result<()> {
pprust::PpAnn::nested(self.tcx.hir(), state, nested)
}
fn pre(&self,
- ps: &mut pprust::State,
- node: pprust::AnnNode) -> io::Result<()> {
+ ps: &mut pprust::State<'_>,
+ node: pprust::AnnNode<'_>) -> io::Result<()> {
let id = match node {
pprust::AnnNode::Name(_) => return Ok(()),
pprust::AnnNode::Expr(expr) => expr.hir_id.local_id,
//! libgraphviz traits, specialized to attaching borrowck analysis
//! data to rendered labels.
-pub use self::Variant::*;
+pub use Variant::*;
pub use rustc::cfg::graphviz::{Node, Edge};
use rustc::cfg::graphviz as cfg_dot;
-use borrowck;
-use borrowck::{BorrowckCtxt, LoanPath};
-use dot;
+use crate::borrowck::{self, BorrowckCtxt, LoanPath};
+use crate::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
+use log::debug;
use rustc::cfg::CFGIndex;
-use dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
use std::rc::Rc;
#[derive(Debug, Copy, Clone)]
sets
}
- fn dataflow_for_variant(&self, e: EntryOrExit, n: &Node, v: Variant) -> String {
+ fn dataflow_for_variant(&self, e: EntryOrExit, n: &Node<'_>, v: Variant) -> String {
let cfgidx = n.0;
match v {
Loans => self.dataflow_loans_for(e, cfgidx),
let dfcx = &self.analysis_data.loans;
let loan_index_to_path = |loan_index| {
let all_loans = &self.analysis_data.all_loans;
- let l: &borrowck::Loan = &all_loans[loan_index];
+ let l: &borrowck::Loan<'_> = &all_loans[loan_index];
l.loan_path()
};
self.build_set(e, cfgidx, dfcx, loan_index_to_path)
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![allow(non_camel_case_types)]
+#![deny(rust_2018_idioms)]
#![feature(nll)]
#![recursion_limit="256"]
-#[macro_use] extern crate log;
-extern crate syntax;
-extern crate syntax_pos;
-extern crate rustc_errors as errors;
-extern crate rustc_data_structures;
-
-// for "clarity", rename the graphviz crate to dot; graphviz within `borrowck`
-// refers to the borrowck-specific graphviz adapter traits.
-extern crate graphviz as dot;
#[macro_use]
extern crate rustc;
-extern crate rustc_mir;
pub use borrowck::check_crate;
pub use borrowck::build_borrowck_dataflow_data_for_fn;
authors = ["The Rust Project Developers"]
name = "rustc_codegen_utils"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_codegen_utils"
use rustc::middle::cstore::MetadataLoader;
use rustc::dep_graph::DepGraph;
use rustc_target::spec::Target;
-use link::out_filename;
+use crate::link::out_filename;
pub use rustc_data_structures::sync::MetadataRef;
fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
- fn provide(&self, _providers: &mut Providers);
- fn provide_extern(&self, _providers: &mut Providers);
+ fn provide(&self, _providers: &mut Providers<'_>);
+ fn provide_extern(&self, _providers: &mut Providers<'_>);
fn codegen_crate<'a, 'tcx>(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
box NoLlvmMetadataLoader
}
- fn provide(&self, providers: &mut Providers) {
- ::symbol_names::provide(providers);
+ fn provide(&self, providers: &mut Providers<'_>) {
+ crate::symbol_names::provide(providers);
providers.target_features_whitelist = |_tcx, _cnum| {
Default::default() // Just a dummy
providers.is_reachable_non_generic = |_tcx, _defid| true;
providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
}
- fn provide_extern(&self, providers: &mut Providers) {
+ fn provide_extern(&self, providers: &mut Providers<'_>) {
providers.is_reachable_non_generic = |_tcx, _defid| true;
}
) -> Box<dyn Any> {
use rustc_mir::monomorphize::item::MonoItem;
- ::check_for_rustc_errors_attr(tcx);
- ::symbol_names_test::report_symbol_names(tcx);
- ::rustc_incremental::assert_dep_graph(tcx);
- ::rustc_incremental::assert_module_sources::assert_module_sources(tcx);
+ crate::check_for_rustc_errors_attr(tcx);
+ crate::symbol_names_test::report_symbol_names(tcx);
+ rustc_incremental::assert_dep_graph(tcx);
+ rustc_incremental::assert_module_sources::assert_module_sources(tcx);
// FIXME: Fix this
- // ::rustc::middle::dependency_format::calculate(tcx);
+ // rustc::middle::dependency_format::calculate(tcx);
let _ = tcx.link_args(LOCAL_CRATE);
let _ = tcx.native_libraries(LOCAL_CRATE);
let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
#![recursion_limit="256"]
-extern crate flate2;
-#[macro_use]
-extern crate log;
+#![deny(rust_2018_idioms)]
#[macro_use]
extern crate rustc;
-extern crate rustc_target;
-extern crate rustc_metadata;
-extern crate rustc_mir;
-extern crate rustc_incremental;
-extern crate syntax;
-extern crate syntax_pos;
#[macro_use] extern crate rustc_data_structures;
use rustc::ty::TyCtxt;
/// error in codegen. This is used to write compile-fail tests
/// that actually test that compilation succeeds without
/// reporting an error.
-pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
+pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_, '_, '_>) {
if let Some((def_id, _)) = tcx.entry_fn(LOCAL_CRATE) {
if tcx.has_attr(def_id, "rustc_error") {
tcx.sess.span_fatal(tcx.def_span(def_id), "compilation successful");
attrs: &[ast::Attribute],
input: &Input) -> String {
let validate = |s: String, span: Option<Span>| {
- ::rustc_metadata::validate_crate_name(sess, &s, span);
+ rustc_metadata::validate_crate_name(sess, &s, span);
s
};
use syntax_pos::symbol::Symbol;
+use log::debug;
+
use std::fmt::Write;
use std::mem::discriminant;
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
def_symbol_name,
symbol_name,
authors = ["The Rust Project Developers"]
name = "rustc_cratesio_shim"
version = "0.0.0"
+edition = "2018"
[lib]
crate-type = ["dylib"]
+#![deny(rust_2018_idioms)]
+
// See Cargo.toml for a comment explaining this crate.
#![allow(unused_extern_crates)]
authors = ["The Rust Project Developers"]
name = "rustc_data_structures"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_data_structures"
graphviz = { path = "../libgraphviz" }
cfg-if = "0.1.2"
stable_deref_trait = "1.0.0"
-rustc-rayon = "0.1.1"
-rustc-rayon-core = "0.1.1"
+rayon = { version = "0.1.1", package = "rustc-rayon" }
+rayon-core = { version = "0.1.1", package = "rustc-rayon-core" }
rustc-hash = "1.0.1"
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
-use indexed_vec::{Idx, IndexVec};
+use crate::indexed_vec::{Idx, IndexVec};
use smallvec::SmallVec;
use std::fmt;
use std::iter;
}
impl<T: Idx> fmt::Debug for BitSet<T> {
- fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
w.debug_list()
.entries(self.iter())
.finish()
dense
}
- fn iter(&self) -> slice::Iter<T> {
+ fn iter(&self) -> slice::Iter<'_, T> {
self.elems.iter()
}
}
}
}
- pub fn iter(&self) -> HybridIter<T> {
+ pub fn iter(&self) -> HybridIter<'_, T> {
match self {
HybridBitSet::Sparse(sparse) => HybridIter::Sparse(sparse.iter()),
HybridBitSet::Dense(dense) => HybridIter::Dense(dense.iter()),
+use crate::stable_hasher;
use std::mem;
-use stable_hasher;
use serialize;
use serialize::opaque::{EncodeResult, Encoder, Decoder};
}
impl ::std::fmt::Display for Fingerprint {
- fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fn fmt(&self, formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(formatter, "{:x}-{:x}", self.0, self.1)
}
}
if #[cfg(unix)] {
use std::ffi::{CString, OsStr};
use std::os::unix::prelude::*;
- use libc;
#[cfg(any(target_os = "linux", target_os = "android"))]
mod os {
- use libc;
-
#[repr(C)]
pub struct flock {
pub l_type: libc::c_short,
#[cfg(target_os = "freebsd")]
mod os {
- use libc;
-
#[repr(C)]
pub struct flock {
pub l_start: libc::off_t,
target_os = "netbsd",
target_os = "openbsd"))]
mod os {
- use libc;
-
#[repr(C)]
pub struct flock {
pub l_start: libc::off_t,
#[cfg(target_os = "haiku")]
mod os {
- use libc;
-
#[repr(C)]
pub struct flock {
pub l_type: libc::c_short,
#[cfg(any(target_os = "macos", target_os = "ios"))]
mod os {
- use libc;
-
#[repr(C)]
pub struct flock {
pub l_start: libc::off_t,
#[cfg(target_os = "solaris")]
mod os {
- use libc;
-
#[repr(C)]
pub struct flock {
pub l_type: libc::c_short,
self.immediate_dominators[node].unwrap()
}
- pub fn dominators(&self, node: Node) -> Iter<Node> {
+ pub fn dominators(&self, node: Node) -> Iter<'_, Node> {
assert!(self.is_reachable(node), "node {:?} is not reachable", node);
Iter {
dominators: self,
}
}
-pub struct Iter<'dom, Node: Idx + 'dom> {
+pub struct Iter<'dom, Node: Idx> {
dominators: &'dom Dominators<Node>,
node: Option<Node>,
}
}
impl<Node: Idx> fmt::Debug for DominatorTree<Node> {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(
&DominatorTreeNode {
tree: self,
}
impl<'tree, Node: Idx> fmt::Debug for DominatorTreeNode<'tree, Node> {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let subtrees: Vec<_> = self.tree
.children(self.node)
.iter()
//! the field `next_edge`). Each of those fields is an array that should
//! be indexed by the direction (see the type `Direction`).
-use bit_set::BitSet;
+use crate::bit_set::BitSet;
+use crate::snapshot_vec::{SnapshotVec, SnapshotVecDelegate};
use std::fmt::Debug;
use std::usize;
-use snapshot_vec::{SnapshotVec, SnapshotVecDelegate};
#[cfg(test)]
mod tests;
.all(|(edge_idx, edge)| f(edge_idx, edge))
}
- pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
+ pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<'_, N, E> {
self.adjacent_edges(source, OUTGOING)
}
- pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
+ pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<'_, N, E> {
self.adjacent_edges(source, INCOMING)
}
- pub fn adjacent_edges(&self, source: NodeIndex, direction: Direction) -> AdjacentEdges<N, E> {
+ pub fn adjacent_edges(
+ &self,
+ source: NodeIndex,
+ direction: Direction
+ ) -> AdjacentEdges<'_, N, E> {
let first_edge = self.node(source).first_edge[direction.repr];
AdjacentEdges {
graph: self,
// # Iterators
-pub struct AdjacentEdges<'g, N, E>
-where
- N: 'g,
- E: 'g,
-{
+pub struct AdjacentEdges<'g, N, E> {
graph: &'g Graph<N, E>,
direction: Direction,
next: EdgeIndex,
}
}
-pub struct DepthFirstTraversal<'g, N, E>
-where
- N: 'g,
- E: 'g,
-{
+pub struct DepthFirstTraversal<'g, N, E> {
graph: &'g Graph<N, E>,
stack: Vec<NodeIndex>,
visited: BitSet<usize>,
-use graph::implementation::*;
+use crate::graph::implementation::*;
use std::fmt::Debug;
type TestGraph = Graph<&'static str, &'static str>;
//! node in the graph. This uses Tarjan's algorithm that completes in
//! O(n) time.
-use fx::FxHashSet;
-use graph::{DirectedGraph, WithNumNodes, WithSuccessors};
-use indexed_vec::{Idx, IndexVec};
+use crate::fx::FxHashSet;
+use crate::graph::{DirectedGraph, WithNumNodes, WithSuccessors};
+use crate::indexed_vec::{Idx, IndexVec};
use std::ops::Range;
mod test;
}
}
-struct SccsConstruction<'c, G: DirectedGraph + WithNumNodes + WithSuccessors + 'c, S: Idx> {
+struct SccsConstruction<'c, G: DirectedGraph + WithNumNodes + WithSuccessors, S: Idx> {
graph: &'c G,
/// The state of each node; used during walk to record the stack
#![cfg(test)]
-use graph::test::TestGraph;
+use crate::graph::test::TestGraph;
use super::*;
#[test]
-use fx::FxHashMap;
+use crate::fx::FxHashMap;
use std::cmp::max;
use std::slice;
use std::iter;
@type [$type:ident]
@debug_format [$debug_format:tt]) => (
impl ::std::fmt::Debug for $type {
- fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(fmt, $debug_format, self.as_u32())
}
}
}
impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.raw, fmt)
}
}
}
#[inline]
- pub fn iter(&self) -> slice::Iter<T> {
+ pub fn iter(&self) -> slice::Iter<'_, T> {
self.raw.iter()
}
}
#[inline]
- pub fn iter_mut(&mut self) -> slice::IterMut<T> {
+ pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
self.raw.iter_mut()
}
#![cfg_attr(unix, feature(libc))]
#![cfg_attr(test, feature(test))]
-extern crate core;
-extern crate ena;
+#![deny(rust_2018_idioms)]
+
#[macro_use]
extern crate log;
+#[allow(unused_extern_crates)]
extern crate serialize as rustc_serialize; // used by deriving
#[cfg(unix)]
extern crate libc;
-extern crate parking_lot;
#[macro_use]
extern crate cfg_if;
-extern crate stable_deref_trait;
-extern crate rustc_rayon as rayon;
-extern crate rustc_rayon_core as rayon_core;
-extern crate rustc_hash;
-extern crate serialize;
-extern crate graphviz;
-extern crate smallvec;
// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
#[allow(unused_extern_crates)]
+use crate::obligation_forest::{ForestObligation, ObligationForest};
use graphviz as dot;
-use obligation_forest::{ForestObligation, ObligationForest};
use std::env::var_os;
use std::fs::File;
use std::path::Path;
type Node = usize;
type Edge = (usize, usize);
- fn graph_id(&self) -> dot::Id {
+ fn graph_id(&self) -> dot::Id<'_> {
dot::Id::new("trait_obligation_forest").unwrap()
}
- fn node_id(&self, index: &Self::Node) -> dot::Id {
+ fn node_id(&self, index: &Self::Node) -> dot::Id<'_> {
dot::Id::new(format!("obligation_{}", index)).unwrap()
}
- fn node_label(&self, index: &Self::Node) -> dot::LabelText {
+ fn node_label(&self, index: &Self::Node) -> dot::LabelText<'_> {
let node = &self.nodes[*index];
let label = format!("{:?} ({:?})", node.obligation.as_predicate(), node.state.get());
dot::LabelText::LabelStr(label.into())
}
- fn edge_label(&self, (_index_source, _index_target): &Self::Edge) -> dot::LabelText {
+ fn edge_label(&self, (_index_source, _index_target): &Self::Edge) -> dot::LabelText<'_> {
dot::LabelText::LabelStr("".into())
}
}
type Node = usize;
type Edge = (usize, usize);
- fn nodes(&self) -> dot::Nodes<Self::Node> {
+ fn nodes(&self) -> dot::Nodes<'_, Self::Node> {
(0..self.nodes.len()).collect()
}
- fn edges(&self) -> dot::Edges<Self::Edge> {
+ fn edges(&self) -> dot::Edges<'_, Self::Edge> {
(0..self.nodes.len())
.flat_map(|i| {
let node = &self.nodes[i];
//! processing step, we compress the vector to remove completed and error
//! nodes, which aren't needed anymore.
-use fx::{FxHashMap, FxHashSet};
+use crate::fx::{FxHashMap, FxHashSet};
use std::cell::Cell;
use std::collections::hash_map::Entry;
// I need a Clone closure
#[derive(Clone)]
-struct GetObligation<'a, O: 'a>(&'a [Node<O>]);
+struct GetObligation<'a, O>(&'a [Node<O>]);
impl<'a, 'b, O> FnOnce<(&'b usize,)> for GetObligation<'a, O> {
type Output = &'a O;
where O: Debug,
T: Debug,
{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f,
"OwningRef {{ owner: {:?}, reference: {:?} }}",
self.owner(),
where O: Debug,
T: Debug,
{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f,
"OwningRefMut {{ owner: {:?}, reference: {:?} }}",
self.owner(),
where O: Sync, for<'a> (&'a mut T): Sync {}
impl Debug for dyn Erased {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<Erased>",)
}
}
/// A wrapper around reference that compares and hashes like a pointer.
/// Can be used as a key in sets/maps indexed by pointers to avoid `unsafe`.
#[derive(Debug)]
-pub struct PtrKey<'a, T: 'a>(pub &'a T);
+pub struct PtrKey<'a, T>(pub &'a T);
impl<'a, T> Clone for PtrKey<'a, T> {
fn clone(&self) -> Self { *self }
-use fx::FxHashMap;
+use crate::fx::FxHashMap;
use std::hash::Hash;
use std::ops;
use std::mem;
/// Iterate over elements, sorted by key
#[inline]
- pub fn iter(&self) -> ::std::slice::Iter<(K, V)> {
+ pub fn iter(&self) -> ::std::slice::Iter<'_, (K, V)> {
self.data.iter()
}
use std::hash::{Hash, Hasher, BuildHasher};
use std::marker::PhantomData;
use std::mem;
-use sip128::SipHasher128;
+use crate::sip128::SipHasher128;
+use crate::indexed_vec;
+use crate::bit_set;
/// When hashing something that ends up affecting properties like symbol names,
/// we want these symbol names to be calculated independently of other factors
}
impl<W: StableHasherResult> ::std::fmt::Debug for StableHasher<W> {
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(f, "{:?}", self.state)
}
}
}
}
-impl<I: ::indexed_vec::Idx, T, CTX> HashStable<CTX> for ::indexed_vec::IndexVec<I, T>
+impl<I: indexed_vec::Idx, T, CTX> HashStable<CTX> for indexed_vec::IndexVec<I, T>
where T: HashStable<CTX>,
{
fn hash_stable<W: StableHasherResult>(&self,
}
-impl<I: ::indexed_vec::Idx, CTX> HashStable<CTX> for ::bit_set::BitSet<I>
+impl<I: indexed_vec::Idx, CTX> HashStable<CTX> for bit_set::BitSet<I>
{
fn hash_stable<W: StableHasherResult>(&self,
ctx: &mut CTX,
use std::hash::{Hash, Hasher};
use serialize::{Encodable, Decodable, Encoder, Decoder};
-use stable_hasher;
+use crate::stable_hasher;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Svh {
}
impl fmt::Display for Svh {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(&self.to_string())
}
}
use std::hash::{Hash, BuildHasher};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
-use owning_ref::{Erased, OwningRef};
+use crate::owning_ref::{Erased, OwningRef};
pub fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
where A: FnOnce() -> RA,
}
#[inline(always)]
- pub fn lock(&self) -> LockGuard<T> {
+ pub fn lock(&self) -> LockGuard<'_, T> {
self.0.lock()
}
#[inline(always)]
- pub fn lock_mut(&self) -> LockGuard<T> {
+ pub fn lock_mut(&self) -> LockGuard<'_, T> {
self.lock()
}
}
#[cfg(parallel_compiler)]
#[inline(always)]
- pub fn try_lock(&self) -> Option<LockGuard<T>> {
+ pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
self.0.try_lock()
}
#[cfg(not(parallel_compiler))]
#[inline(always)]
- pub fn try_lock(&self) -> Option<LockGuard<T>> {
+ pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
self.0.try_borrow_mut().ok()
}
#[cfg(parallel_compiler)]
#[inline(always)]
- pub fn lock(&self) -> LockGuard<T> {
+ pub fn lock(&self) -> LockGuard<'_, T> {
if ERROR_CHECKING {
self.0.try_lock().expect("lock was already held")
} else {
#[cfg(not(parallel_compiler))]
#[inline(always)]
- pub fn lock(&self) -> LockGuard<T> {
+ pub fn lock(&self) -> LockGuard<'_, T> {
self.0.borrow_mut()
}
}
#[inline(always)]
- pub fn borrow(&self) -> LockGuard<T> {
+ pub fn borrow(&self) -> LockGuard<'_, T> {
self.lock()
}
#[inline(always)]
- pub fn borrow_mut(&self) -> LockGuard<T> {
+ pub fn borrow_mut(&self) -> LockGuard<'_, T> {
self.lock()
}
}
#[cfg(not(parallel_compiler))]
#[inline(always)]
- pub fn read(&self) -> ReadGuard<T> {
+ pub fn read(&self) -> ReadGuard<'_, T> {
self.0.borrow()
}
#[cfg(parallel_compiler)]
#[inline(always)]
- pub fn read(&self) -> ReadGuard<T> {
+ pub fn read(&self) -> ReadGuard<'_, T> {
if ERROR_CHECKING {
self.0.try_read().expect("lock was already held")
} else {
#[cfg(not(parallel_compiler))]
#[inline(always)]
- pub fn try_write(&self) -> Result<WriteGuard<T>, ()> {
+ pub fn try_write(&self) -> Result<WriteGuard<'_, T>, ()> {
self.0.try_borrow_mut().map_err(|_| ())
}
#[cfg(parallel_compiler)]
#[inline(always)]
- pub fn try_write(&self) -> Result<WriteGuard<T>, ()> {
+ pub fn try_write(&self) -> Result<WriteGuard<'_, T>, ()> {
self.0.try_write().ok_or(())
}
#[cfg(not(parallel_compiler))]
#[inline(always)]
- pub fn write(&self) -> WriteGuard<T> {
+ pub fn write(&self) -> WriteGuard<'_, T> {
self.0.borrow_mut()
}
#[cfg(parallel_compiler)]
#[inline(always)]
- pub fn write(&self) -> WriteGuard<T> {
+ pub fn write(&self) -> WriteGuard<'_, T> {
if ERROR_CHECKING {
self.0.try_write().expect("lock was already held")
} else {
}
#[inline(always)]
- pub fn borrow(&self) -> ReadGuard<T> {
+ pub fn borrow(&self) -> ReadGuard<'_, T> {
self.read()
}
#[inline(always)]
- pub fn borrow_mut(&self) -> WriteGuard<T> {
+ pub fn borrow_mut(&self) -> WriteGuard<'_, T> {
self.write()
}
}
mod test {
use super::*;
extern crate test;
- use self::test::Bencher;
+ use test::Bencher;
#[test]
fn test_contains_and_insert() {
-use bit_set::BitMatrix;
-use fx::FxHashMap;
-use sync::Lock;
+use crate::bit_set::BitMatrix;
+use crate::fx::FxHashMap;
+use crate::stable_hasher::{HashStable, StableHasher, StableHasherResult};
+use crate::sync::Lock;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
-use stable_hasher::{HashStable, StableHasher, StableHasherResult};
use std::fmt::Debug;
use std::hash::Hash;
use std::mem;
-use indexed_vec::{Idx, IndexVec};
+use crate::indexed_vec::{Idx, IndexVec};
pub fn iter<Ls>(
first: Option<Ls::LinkIndex>,
-use bit_set::BitSet;
-use indexed_vec::Idx;
+use crate::bit_set::BitSet;
+use crate::indexed_vec::Idx;
use std::collections::VecDeque;
/// A work queue is a handy data structure for tracking work left to
// | | something about `foo`
// | something about `fn foo()`
annotations_position.sort_by(|a, b| {
- // Decreasing order
- a.1.len().cmp(&b.1.len()).reverse()
+ // Decreasing order. When `a` and `b` are the same length, prefer `Primary`.
+ (a.1.len(), !a.1.is_primary).cmp(&(b.1.len(), !b.1.is_primary)).reverse()
});
// Write the underlines.
authors = ["The Rust Project Developers"]
name = "rustc_incremental"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_incremental"
}
}
-fn dump_graph(tcx: TyCtxt) {
+fn dump_graph(tcx: TyCtxt<'_, '_, '_>) {
let path: String = env::var("RUST_DEP_GRAPH").unwrap_or_else(|_| "dep_graph".to_string());
let query = tcx.dep_graph.query();
impl<'a, 'tcx, 'q> dot::GraphWalk<'a> for GraphvizDepGraph<'q> {
type Node = &'q DepNode;
type Edge = (&'q DepNode, &'q DepNode);
- fn nodes(&self) -> dot::Nodes<&'q DepNode> {
+ fn nodes(&self) -> dot::Nodes<'_, &'q DepNode> {
let nodes: Vec<_> = self.0.iter().cloned().collect();
nodes.into()
}
- fn edges(&self) -> dot::Edges<(&'q DepNode, &'q DepNode)> {
+ fn edges(&self) -> dot::Edges<'_, (&'q DepNode, &'q DepNode)> {
self.1[..].into()
}
fn source(&self, edge: &(&'q DepNode, &'q DepNode)) -> &'q DepNode {
impl<'a, 'tcx, 'q> dot::Labeller<'a> for GraphvizDepGraph<'q> {
type Node = &'q DepNode;
type Edge = (&'q DepNode, &'q DepNode);
- fn graph_id(&self) -> dot::Id {
+ fn graph_id(&self) -> dot::Id<'_> {
dot::Id::new("DependencyGraph").unwrap()
}
- fn node_id(&self, n: &&'q DepNode) -> dot::Id {
+ fn node_id(&self, n: &&'q DepNode) -> dot::Id<'_> {
let s: String =
format!("{:?}", n).chars()
.map(|c| if c == '_' || c.is_alphanumeric() { c } else { '_' })
debug!("n={:?} s={:?}", n, s);
dot::Id::new(s).unwrap()
}
- fn node_label(&self, n: &&'q DepNode) -> dot::LabelText {
+ fn node_label(&self, n: &&'q DepNode) -> dot::LabelText<'_> {
dot::LabelText::label(format!("{:?}", n))
}
}
#![recursion_limit="256"]
-extern crate graphviz;
+#![deny(rust_2018_idioms)]
+
#[macro_use] extern crate rustc;
-extern crate rustc_data_structures;
-extern crate serialize as rustc_serialize;
-extern crate rand;
-extern crate rustc_fs_util;
+#[allow(unused_extern_crates)]
+extern crate serialize as rustc_serialize; // used by deriving
#[macro_use] extern crate log;
-extern crate syntax;
-extern crate syntax_pos;
mod assert_dep_graph;
pub mod assert_module_sources;
///
/// Also make sure that the `label` and `except` fields do not
/// both exist.
-fn check_config(tcx: TyCtxt, attr: &Attribute) -> bool {
+fn check_config(tcx: TyCtxt<'_, '_, '_>, attr: &Attribute) -> bool {
debug!("check_config(attr={:?})", attr);
let config = &tcx.sess.parse_sess.config;
debug!("check_config: config={:?}", config);
}
}
-fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> ast::Name {
+fn expect_associated_value(tcx: TyCtxt<'_, '_, '_>, item: &NestedMetaItem) -> ast::Name {
if let Some(value) = item.value_str() {
value
} else {
use rustc_serialize::Decodable as RustcDecodable;
use rustc_serialize::opaque::Decoder;
use std::path::Path;
-use std;
use super::data::*;
use super::fs::*;
mod work_product;
mod file_format;
-pub use self::fs::finalize_session_directory;
-pub use self::fs::garbage_collect_session_directories;
-pub use self::fs::in_incr_comp_dir;
-pub use self::fs::in_incr_comp_dir_sess;
-pub use self::fs::prepare_session_directory;
-pub use self::load::dep_graph_tcx_init;
-pub use self::load::load_dep_graph;
-pub use self::load::load_query_result_cache;
-pub use self::load::LoadResult;
-pub use self::save::save_dep_graph;
-pub use self::save::save_work_product_index;
-pub use self::work_product::copy_cgu_workproducts_to_incr_comp_cache_dir;
-pub use self::work_product::delete_workproduct_files;
+pub use fs::finalize_session_directory;
+pub use fs::garbage_collect_session_directories;
+pub use fs::in_incr_comp_dir;
+pub use fs::in_incr_comp_dir_sess;
+pub use fs::prepare_session_directory;
+pub use load::dep_graph_tcx_init;
+pub use load::load_dep_graph;
+pub use load::load_query_result_cache;
+pub use load::LoadResult;
+pub use save::save_dep_graph;
+pub use save::save_work_product_index;
+pub use work_product::copy_cgu_workproducts_to_incr_comp_cache_dir;
+pub use work_product::delete_workproduct_files;
}
}
-fn encode_dep_graph(tcx: TyCtxt,
+fn encode_dep_graph(tcx: TyCtxt<'_, '_, '_>,
encoder: &mut Encoder) {
// First encode the commandline arguments hash
tcx.sess.opts.dep_tracking_hash().encode(encoder).unwrap();
serialized_products.encode(encoder).unwrap();
}
-fn encode_query_cache(tcx: TyCtxt,
+fn encode_query_cache(tcx: TyCtxt<'_, '_, '_>,
encoder: &mut Encoder) {
time(tcx.sess, "serialize query result cache", || {
tcx.serialize_query_result_cache(encoder).unwrap();
//! This module contains files for saving intermediate work-products.
-use persist::fs::*;
+use crate::persist::fs::*;
use rustc::dep_graph::{WorkProduct, WorkProductId, WorkProductFileKind};
use rustc::session::Session;
use rustc_fs_util::link_or_copy;
authors = ["The Rust Project Developers"]
name = "rustc_lint"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_lint"
use rustc::hir::def::Def;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::ty::{self, Ty};
+use rustc::{lint, util};
use hir::Node;
use util::nodemap::NodeSet;
use lint::{LateContext, LintContext, LintArray};
use syntax::errors::{Applicability, DiagnosticBuilder};
use syntax::print::pprust::expr_to_string;
use syntax::visit::FnKind;
+use syntax::struct_span_err;
use rustc::hir::{self, GenericParamKind, PatKind};
-use nonstandard_style::{MethodLateContext, method_context};
+use crate::nonstandard_style::{MethodLateContext, method_context};
+
+use log::debug;
// hardwired lints from librustc
pub use lint::builtin::*;
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue {
- fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
+ fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
if let hir::ExprKind::While(ref cond, ..) = e.node {
if let hir::ExprKind::Lit(ref lit) = cond.node {
if let ast::LitKind::Bool(true) = lit.node {
pub struct BoxPointers;
impl BoxPointers {
- fn check_heap_type<'a, 'tcx>(&self, cx: &LateContext, span: Span, ty: Ty) {
+ fn check_heap_type<'a, 'tcx>(&self, cx: &LateContext<'_, '_>, span: Span, ty: Ty<'_>) {
for leaf_ty in ty.walk() {
if leaf_ty.is_box() {
let m = format!("type uses owned (Box type) pointers: {}", ty);
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {
hir::ItemKind::Fn(..) |
hir::ItemKind::Ty(..) |
}
}
- fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
+ fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
let ty = cx.tables.node_id_to_type(e.hir_id);
self.check_heap_type(cx, e.span, ty);
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
- fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) {
+ fn check_pat(&mut self, cx: &LateContext<'_, '_>, pat: &hir::Pat) {
if let PatKind::Struct(ref qpath, ref field_pats, _) = pat.node {
let variant = cx.tables.pat_ty(pat).ty_adt_def()
.expect("struct pattern type is not an ADT")
}
impl UnsafeCode {
- fn report_unsafe(&self, cx: &EarlyContext, span: Span, desc: &'static str) {
+ fn report_unsafe(&self, cx: &EarlyContext<'_>, span: Span, desc: &'static str) {
// This comes from a macro that has #[allow_internal_unsafe].
if span.allows_unsafe() {
return;
}
impl EarlyLintPass for UnsafeCode {
- fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
+ fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
if attr.check_name("allow_internal_unsafe") {
self.report_unsafe(cx, attr.span, "`allow_internal_unsafe` allows defining \
macros using unsafe without triggering \
}
}
- fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
+ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
if let ast::ExprKind::Block(ref blk, _) = e.node {
// Don't warn about generated blocks, that'll just pollute the output.
if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) {
}
}
- fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
+ fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
match it.node {
ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => {
self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
}
fn check_fn(&mut self,
- cx: &EarlyContext,
- fk: FnKind,
+ cx: &EarlyContext<'_>,
+ fk: FnKind<'_>,
_: &ast::FnDecl,
span: Span,
_: ast::NodeId) {
}
}
- fn check_trait_item(&mut self, cx: &EarlyContext, item: &ast::TraitItem) {
+ fn check_trait_item(&mut self, cx: &EarlyContext<'_>, item: &ast::TraitItem) {
if let ast::TraitItemKind::Method(ref sig, None) = item.node {
if sig.header.unsafety == ast::Unsafety::Unsafe {
self.report_unsafe(cx, item.span, "declaration of an `unsafe` method")
}
fn check_missing_docs_attrs(&self,
- cx: &LateContext,
+ cx: &LateContext<'_, '_>,
id: Option<ast::NodeId>,
attrs: &[ast::Attribute],
sp: Span,
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
- fn enter_lint_attrs(&mut self, _: &LateContext, attrs: &[ast::Attribute]) {
+ fn enter_lint_attrs(&mut self, _: &LateContext<'_, '_>, attrs: &[ast::Attribute]) {
let doc_hidden = self.doc_hidden() ||
attrs.iter().any(|attr| {
attr.check_name("doc") &&
self.doc_hidden_stack.push(doc_hidden);
}
- fn exit_lint_attrs(&mut self, _: &LateContext, _attrs: &[ast::Attribute]) {
+ fn exit_lint_attrs(&mut self, _: &LateContext<'_, '_>, _attrs: &[ast::Attribute]) {
self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
}
- fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
+ fn check_crate(&mut self, cx: &LateContext<'_, '_>, krate: &hir::Crate) {
self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate");
for macro_def in &krate.exported_macros {
}
}
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
let desc = match it.node {
hir::ItemKind::Fn(..) => "a function",
hir::ItemKind::Mod(..) => "a module",
self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
}
- fn check_trait_item(&mut self, cx: &LateContext, trait_item: &hir::TraitItem) {
+ fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, trait_item: &hir::TraitItem) {
if self.private_traits.contains(&trait_item.id) {
return;
}
desc);
}
- fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) {
+ fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, impl_item: &hir::ImplItem) {
// If the method is an impl for a trait, don't doc.
if method_context(cx, impl_item.id) == MethodLateContext::TraitImpl {
return;
desc);
}
- fn check_struct_field(&mut self, cx: &LateContext, sf: &hir::StructField) {
+ fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, sf: &hir::StructField) {
if !sf.is_positional() {
self.check_missing_docs_attrs(cx,
Some(sf.id),
}
}
- fn check_variant(&mut self, cx: &LateContext, v: &hir::Variant, _: &hir::Generics) {
+ fn check_variant(&mut self, cx: &LateContext<'_, '_>, v: &hir::Variant, _: &hir::Generics) {
self.check_missing_docs_attrs(cx,
Some(v.node.data.id()),
&v.node.attrs,
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations {
- fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
if !cx.access_levels.is_reachable(item.id) {
return;
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
- fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
if !cx.access_levels.is_reachable(item.id) {
return;
}
}
impl EarlyLintPass for AnonymousParameters {
- fn check_trait_item(&mut self, cx: &EarlyContext, it: &ast::TraitItem) {
+ fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::TraitItem) {
match it.node {
ast::TraitItemKind::Method(ref sig, _) => {
for arg in sig.decl.inputs.iter() {
}
impl EarlyLintPass for DeprecatedAttr {
- fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
+ fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
for &&(n, _, _, ref g) in &self.depr_attrs {
if attr.name() == n {
if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion),
}
impl EarlyLintPass for UnusedDocComment {
- fn check_local(&mut self, cx: &EarlyContext, decl: &ast::Local) {
+ fn check_local(&mut self, cx: &EarlyContext<'_>, decl: &ast::Local) {
self.warn_if_doc(decl.attrs.iter(), cx);
}
- fn check_arm(&mut self, cx: &EarlyContext, arm: &ast::Arm) {
+ fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
self.warn_if_doc(arm.attrs.iter(), cx);
}
- fn check_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr) {
+ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
self.warn_if_doc(expr.attrs.iter(), cx);
}
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PluginAsLibrary {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
if cx.tcx.plugin_registrar_fn(LOCAL_CRATE).is_some() {
// We're compiling a plugin; it's fine to link other plugins.
return;
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {
hir::ItemKind::Fn(.., ref generics, _) => {
if let Some(no_mangle_attr) = attr::find_by_name(&it.attrs, "no_mangle") {
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
- fn check_expr(&mut self, cx: &LateContext, expr: &hir::Expr) {
+ fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &hir::Expr) {
use rustc_target::spec::abi::Abi::RustIntrinsic;
let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \
None
}
- fn def_id_is_transmute(cx: &LateContext, def_id: DefId) -> bool {
+ fn def_id_is_transmute(cx: &LateContext<'_, '_>, def_id: DefId) -> bool {
cx.tcx.fn_sig(def_id).abi() == RustIntrinsic &&
cx.tcx.item_name(def_id) == "transmute"
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnstableFeatures {
- fn check_attribute(&mut self, ctx: &LateContext, attr: &ast::Attribute) {
+ fn check_attribute(&mut self, ctx: &LateContext<'_, '_>, attr: &ast::Attribute) {
if attr.check_name("feature") {
if let Some(items) = attr.meta_item_list() {
for item in items {
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
- fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) {
+ fn check_item(&mut self, ctx: &LateContext<'_, '_>, item: &hir::Item) {
if let hir::ItemKind::Union(ref vdata, _) = item.node {
for field in vdata.fields() {
let field_ty = ctx.tcx.type_of(ctx.tcx.hir().local_def_id(field.id));
}
impl UnreachablePub {
- fn perform_lint(&self, cx: &LateContext, what: &str, id: ast::NodeId,
+ fn perform_lint(&self, cx: &LateContext<'_, '_>, what: &str, id: ast::NodeId,
vis: &hir::Visibility, span: Span, exportable: bool) {
let mut applicability = Applicability::MachineApplicable;
match vis.node {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
- fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
self.perform_lint(cx, "item", item.id, &item.vis, item.span, true);
}
- fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) {
+ fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, foreign_item: &hir::ForeignItem) {
self.perform_lint(cx, "item", foreign_item.id, &foreign_item.vis,
foreign_item.span, true);
}
- fn check_struct_field(&mut self, cx: &LateContext, field: &hir::StructField) {
+ fn check_struct_field(&mut self, cx: &LateContext<'_, '_>, field: &hir::StructField) {
self.perform_lint(cx, "field", field.id, &field.vis, field.span, false);
}
- fn check_impl_item(&mut self, cx: &LateContext, impl_item: &hir::ImplItem) {
+ fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, impl_item: &hir::ImplItem) {
self.perform_lint(cx, "item", impl_item.id, &impl_item.vis, impl_item.span, false);
}
}
}
}
- fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder) {
+ fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder<'_>) {
// Access to associates types should use `<T as Bound>::Assoc`, which does not need a
// bound. Let's see if this type does that.
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
- fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::Item) {
let (ty, type_alias_generics) = match item.node {
hir::ItemKind::Ty(ref ty, ref generics) => (&*ty, generics),
_ => return,
lint_array!()
}
}
-fn check_const(cx: &LateContext, body_id: hir::BodyId) {
+fn check_const(cx: &LateContext<'_, '_>, body_id: hir::BodyId) {
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
let is_static = cx.tcx.is_static(def_id).is_some();
let param_env = if is_static {
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {
hir::ItemKind::Const(_, body_id) => {
check_const(cx, body_id);
}
impl EarlyLintPass for EllipsisInclusiveRangePatterns {
- fn check_pat(&mut self, cx: &EarlyContext, pat: &ast::Pat, visit_subpats: &mut bool) {
+ fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &ast::Pat, visit_subpats: &mut bool) {
use self::ast::{PatKind, RangeEnd, RangeSyntax::DotDotDot};
/// If `pat` is a `...` pattern, return the start and end of the range, as well as the span
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
if self.items_nameable {
if let hir::ItemKind::Mod(..) = it.node {}
else {
}
}
- fn check_item_post(&mut self, _cx: &LateContext, it: &hir::Item) {
+ fn check_item_post(&mut self, _cx: &LateContext<'_, '_>, it: &hir::Item) {
if !self.items_nameable && self.boundary == it.id {
self.items_nameable = true;
}
}
impl KeywordIdents {
- fn check_tokens(&mut self, cx: &EarlyContext, tokens: TokenStream) {
+ fn check_tokens(&mut self, cx: &EarlyContext<'_>, tokens: TokenStream) {
for tt in tokens.into_trees() {
match tt {
TokenTree::Token(span, tok) => match tok.ident() {
}
impl EarlyLintPass for KeywordIdents {
- fn check_mac_def(&mut self, cx: &EarlyContext, mac_def: &ast::MacroDef, _id: ast::NodeId) {
+ fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef, _id: ast::NodeId) {
self.check_tokens(cx, mac_def.stream());
}
- fn check_mac(&mut self, cx: &EarlyContext, mac: &ast::Mac) {
+ fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) {
self.check_tokens(cx, mac.node.tts.clone().into());
}
- fn check_ident(&mut self, cx: &EarlyContext, ident: ast::Ident) {
+ fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) {
let ident_str = &ident.as_str()[..];
let cur_edition = cx.sess.edition();
let is_raw_ident = |ident: ast::Ident| {
impl ExplicitOutlivesRequirements {
fn collect_outlives_bound_spans(
&self,
- cx: &LateContext,
+ cx: &LateContext<'_, '_>,
item_def_id: DefId,
param_name: &str,
bounds: &hir::GenericBounds,
+use syntax::{register_diagnostic, register_diagnostics};
+
register_diagnostics! {
E0721, // `await` keyword
}
#![recursion_limit="256"]
-#[macro_use]
-extern crate syntax;
+#![deny(rust_2018_idioms)]
+
#[macro_use]
extern crate rustc;
-#[macro_use]
-extern crate log;
-extern crate rustc_target;
-extern crate syntax_pos;
-extern crate rustc_data_structures;
mod diagnostics;
mod nonstandard_style;
parser::ILL_FORMED_ATTRIBUTE_INPUT,
};
use rustc::session;
-use rustc::util;
use rustc::hir;
use syntax::ast;
reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
edition: None,
},
+ FutureIncompatibleInfo {
+ id: LintId::of(DUPLICATE_MATCHER_BINDING_NAME),
+ reference: "issue #57593 <https://github.com/rust-lang/rust/issues/57593>",
+ edition: None,
+ },
]);
// Register renamed and removed lints.
use rustc::hir::{self, GenericParamKind, PatKind};
use rustc::hir::def::Def;
use rustc::hir::intravisit::FnKind;
+use rustc::lint;
use rustc::ty;
use rustc_target::spec::abi::Abi;
use lint::{EarlyContext, LateContext, LintContext, LintArray};
PlainImpl,
}
-pub fn method_context(cx: &LateContext, id: ast::NodeId) -> MethodLateContext {
+pub fn method_context(cx: &LateContext<'_, '_>, id: ast::NodeId) -> MethodLateContext {
let def_id = cx.tcx.hir().local_def_id(id);
let item = cx.tcx.associated_item(def_id);
match item.container {
pub struct NonCamelCaseTypes;
impl NonCamelCaseTypes {
- fn check_case(&self, cx: &EarlyContext, sort: &str, ident: &Ident) {
+ fn check_case(&self, cx: &EarlyContext<'_>, sort: &str, ident: &Ident) {
fn char_has_case(c: char) -> bool {
c.is_lowercase() || c.is_uppercase()
}
}
impl EarlyLintPass for NonCamelCaseTypes {
- fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
+ fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
let has_repr_c = it.attrs
.iter()
.any(|attr| {
}
}
- fn check_variant(&mut self, cx: &EarlyContext, v: &ast::Variant, _: &ast::Generics) {
+ fn check_variant(&mut self, cx: &EarlyContext<'_>, v: &ast::Variant, _: &ast::Generics) {
self.check_case(cx, "variant", &v.node.ident);
}
- fn check_generic_param(&mut self, cx: &EarlyContext, param: &ast::GenericParam) {
+ fn check_generic_param(&mut self, cx: &EarlyContext<'_>, param: &ast::GenericParam) {
if let ast::GenericParamKind::Type { .. } = param.kind {
self.check_case(cx, "type parameter", ¶m.ident);
}
}
/// Checks if a given identifier is snake case, and reports a diagnostic if not.
- fn check_snake_case(&self, cx: &LateContext, sort: &str, ident: &Ident) {
+ fn check_snake_case(&self, cx: &LateContext<'_, '_>, sort: &str, ident: &Ident) {
fn is_snake_case(ident: &str) -> bool {
if ident.is_empty() {
return true;
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
- fn check_crate(&mut self, cx: &LateContext, cr: &hir::Crate) {
+ fn check_crate(&mut self, cx: &LateContext<'_, '_>, cr: &hir::Crate) {
let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
Some(Ident::from_str(name))
} else {
}
}
- fn check_generic_param(&mut self, cx: &LateContext, param: &hir::GenericParam) {
+ fn check_generic_param(&mut self, cx: &LateContext<'_, '_>, param: &hir::GenericParam) {
if let GenericParamKind::Lifetime { .. } = param.kind {
self.check_snake_case(cx, "lifetime", ¶m.name.ident());
}
fn check_fn(
&mut self,
- cx: &LateContext,
- fk: FnKind,
+ cx: &LateContext<'_, '_>,
+ fk: FnKind<'_>,
_: &hir::FnDecl,
_: &hir::Body,
_: Span,
}
}
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
if let hir::ItemKind::Mod(_) = it.node {
self.check_snake_case(cx, "module", &it.ident);
}
}
- fn check_trait_item(&mut self, cx: &LateContext, item: &hir::TraitItem) {
+ fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, item: &hir::TraitItem) {
if let hir::TraitItemKind::Method(_, hir::TraitMethod::Required(pnames)) = &item.node {
self.check_snake_case(cx, "trait method", &item.ident);
for param_name in pnames {
}
}
- fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
+ fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) {
if let &PatKind::Binding(_, _, _, ident, _) = &p.node {
self.check_snake_case(cx, "variable", &ident);
}
fn check_struct_def(
&mut self,
- cx: &LateContext,
+ cx: &LateContext<'_, '_>,
s: &hir::VariantData,
_: ast::Name,
_: &hir::Generics,
pub struct NonUpperCaseGlobals;
impl NonUpperCaseGlobals {
- fn check_upper_case(cx: &LateContext, sort: &str, ident: &Ident) {
+ fn check_upper_case(cx: &LateContext<'_, '_>, sort: &str, ident: &Ident) {
let name = &ident.name.as_str();
if name.chars().any(|c| c.is_lowercase()) {
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
match it.node {
hir::ItemKind::Static(..) if !attr::contains_name(&it.attrs, "no_mangle") => {
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
}
}
- fn check_trait_item(&mut self, cx: &LateContext, ti: &hir::TraitItem) {
+ fn check_trait_item(&mut self, cx: &LateContext<'_, '_>, ti: &hir::TraitItem) {
if let hir::TraitItemKind::Const(..) = ti.node {
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ti.ident);
}
}
- fn check_impl_item(&mut self, cx: &LateContext, ii: &hir::ImplItem) {
+ fn check_impl_item(&mut self, cx: &LateContext<'_, '_>, ii: &hir::ImplItem) {
if let hir::ImplItemKind::Const(..) = ii.node {
NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident);
}
}
- fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
+ fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat) {
// Lint for constants that look like binding identifiers (#7526)
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node {
if let Def::Const(..) = path.def {
use rustc::ty::subst::Substs;
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx};
+use rustc::{lint, util};
use rustc_data_structures::indexed_vec::Idx;
use util::nodemap::FxHashSet;
use lint::{LateContext, LintContext, LintArray};
use rustc::mir::interpret::{sign_extend, truncate};
+use log::debug;
+
declare_lint! {
UNUSED_COMPARISONS,
Warn,
}
}
- fn check_limits(cx: &LateContext,
+ fn check_limits(cx: &LateContext<'_, '_>,
binop: hir::BinOp,
l: &hir::Expr,
r: &hir::Expr)
}
}
- fn get_bin_hex_repr(cx: &LateContext, lit: &ast::Lit) -> Option<String> {
+ fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &ast::Lit) -> Option<String> {
let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?;
let firstch = src.chars().next()?;
//
// No suggestion for: `isize`, `usize`.
fn get_type_suggestion<'a>(
- t: &ty::TyKind,
+ t: &ty::TyKind<'_>,
val: u128,
negative: bool,
) -> Option<String> {
}
fn report_bin_hex_error(
- cx: &LateContext,
+ cx: &LateContext<'_, '_>,
expr: &hir::Expr,
- ty: ty::TyKind,
+ ty: ty::TyKind<'_>,
repr_str: String,
val: u128,
negative: bool,
fn check_type_for_ffi(&self,
cache: &mut FxHashSet<Ty<'tcx>>,
ty: Ty<'tcx>) -> FfiResult<'tcx> {
- use self::FfiResult::*;
+ use FfiResult::*;
let cx = self.cx.tcx;
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
- fn check_foreign_item(&mut self, cx: &LateContext, it: &hir::ForeignItem) {
+ fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
let mut vis = ImproperCTypesVisitor { cx };
let abi = cx.tcx.hir().get_foreign_abi(it.id);
if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic {
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+ fn check_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::Item) {
if let hir::ItemKind::Enum(ref enum_definition, _) = it.node {
let item_def_id = cx.tcx.hir().local_def_id(it.id);
let t = cx.tcx.type_of(item_def_id);
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
+use rustc::lint;
use rustc::ty;
use rustc::ty::adjustment;
use lint::{LateContext, EarlyContext, LintContext, LintArray};
use rustc::hir;
+use log::debug;
+
declare_lint! {
pub UNUSED_MUST_USE,
Warn,
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
- fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
+ fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
let expr = match s.node {
hir::StmtKind::Semi(ref expr) => &**expr,
_ => return,
}
fn check_must_use(
- cx: &LateContext,
+ cx: &LateContext<'_, '_>,
def_id: DefId,
sp: Span,
descr_pre_path: &str,
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements {
- fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
+ fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
if let hir::StmtKind::Semi(ref expr) = s.node {
if let hir::ExprKind::Path(_) = expr.node {
cx.span_lint(PATH_STATEMENTS, s.span, "path statement with no effect");
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
- fn check_attribute(&mut self, cx: &LateContext, attr: &ast::Attribute) {
+ fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
debug!("checking attribute: {:?}", attr);
// Note that check_name() marks the attribute as used if it matches.
for &(name, ty, ..) in BUILTIN_ATTRIBUTES {
impl UnusedParens {
fn check_unused_parens_expr(&self,
- cx: &EarlyContext,
+ cx: &EarlyContext<'_>,
value: &ast::Expr,
msg: &str,
followed_by_block: bool) {
}
fn check_unused_parens_pat(&self,
- cx: &EarlyContext,
+ cx: &EarlyContext<'_>,
value: &ast::Pat,
msg: &str) {
if let ast::PatKind::Paren(_) = value.node {
}
}
- fn remove_outer_parens(cx: &EarlyContext, span: Span, pattern: &str, msg: &str) {
+ fn remove_outer_parens(cx: &EarlyContext<'_>, span: Span, pattern: &str, msg: &str) {
let span_msg = format!("unnecessary parentheses around {}", msg);
let mut err = cx.struct_span_lint(UNUSED_PARENS, span, &span_msg);
let mut ate_left_paren = false;
}
impl EarlyLintPass for UnusedParens {
- fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
+ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
use syntax::ast::ExprKind::*;
let (value, msg, followed_by_block) = match e.node {
If(ref cond, ..) => (cond, "`if` condition", true),
self.check_unused_parens_expr(cx, &value, msg, followed_by_block);
}
- fn check_pat(&mut self, cx: &EarlyContext, p: &ast::Pat, _: &mut bool) {
+ fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat, _: &mut bool) {
use ast::PatKind::{Paren, Range};
// The lint visitor will visit each subpattern of `p`. We do not want to lint any range
// pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there
}
}
- fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
+ fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
if let ast::StmtKind::Local(ref local) = s.node {
if let Some(ref value) = local.init {
self.check_unused_parens_expr(cx, &value, "assigned value", false);
pub struct UnusedImportBraces;
impl UnusedImportBraces {
- fn check_use_tree(&self, cx: &EarlyContext, use_tree: &ast::UseTree, item: &ast::Item) {
+ fn check_use_tree(&self, cx: &EarlyContext<'_>, use_tree: &ast::UseTree, item: &ast::Item) {
if let ast::UseTreeKind::Nested(ref items) = use_tree.kind {
// Recursively check nested UseTrees
for &(ref tree, _) in items {
}
impl EarlyLintPass for UnusedImportBraces {
- fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) {
+ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
if let ast::ItemKind::Use(ref use_tree) = item.node {
self.check_use_tree(cx, use_tree, item);
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAllocation {
- fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
+ fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
match e.node {
hir::ExprKind::Box(_) => {}
_ => return,
authors = ["The Rust Project Developers"]
name = "rustc_metadata"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_metadata"
memmap = "0.6"
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
+errors = { path = "../librustc_errors", package = "rustc_errors" }
rustc_target = { path = "../librustc_target" }
serialize = { path = "../libserialize" }
stable_deref_trait = "1.0.0"
//! Validates all used crates and extern libraries and loads their metadata
-use cstore::{self, CStore, CrateSource, MetadataBlob};
-use locator::{self, CratePaths};
-use decoder::proc_macro_def_path_table;
-use schema::CrateRoot;
+use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
+use crate::locator::{self, CratePaths};
+use crate::decoder::proc_macro_def_path_table;
+use crate::schema::CrateRoot;
use rustc_data_structures::sync::{Lrc, RwLock, Lock};
use rustc::hir::def_id::CrateNum;
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
use syntax::visit;
+use syntax::{span_err, span_fatal};
use syntax_pos::{Span, DUMMY_SP};
-use log;
+use log::{debug, info, log_enabled};
pub struct Library {
pub dylib: Option<(PathBuf, PathKind)>,
}
}
- fn load(&mut self, locate_ctxt: &mut locator::Context) -> Option<LoadResult> {
+ fn load(&mut self, locate_ctxt: &mut locator::Context<'_>) -> Option<LoadResult> {
let library = locate_ctxt.maybe_load_library_crate()?;
// In the case that we're loading a crate, but not matching
// The map from crate numbers in the crate we're resolving to local crate numbers.
// We map 0 and all other holes in the map to our parent crate. The "additional"
// self-dependencies should be harmless.
- ::std::iter::once(krate).chain(crate_root.crate_deps
+ std::iter::once(krate).chain(crate_root.crate_deps
.decode(metadata)
.map(|dep| {
info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash,
fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option<PathBuf>, span: Span)
-> Vec<(ast::Name, Lrc<SyntaxExtension>)> {
use std::{env, mem};
- use dynamic_lib::DynamicLibrary;
+ use crate::dynamic_lib::DynamicLibrary;
use proc_macro::bridge::client::ProcMacro;
use syntax_ext::deriving::custom::ProcMacroDerive;
use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro};
item.ident, orig_name);
let orig_name = match orig_name {
Some(orig_name) => {
- ::validate_crate_name(Some(self.sess), &orig_name.as_str(),
+ crate::validate_crate_name(Some(self.sess), &orig_name.as_str(),
Some(item.span));
orig_name
}
// The crate store - a central repo for information collected about external
// crates and libraries
-use schema;
+use crate::schema;
use rustc::hir::def_id::{CrateNum, DefIndex};
use rustc::hir::map::definitions::DefPathTable;
use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
pub use rustc::middle::cstore::NativeLibraryKind::*;
pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule};
-pub use cstore_impl::{provide, provide_extern};
+pub use crate::cstore_impl::{provide, provide_extern};
// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external
-use cstore::{self, LoadedMacro};
-use encoder;
-use link_args;
-use native_libs;
-use foreign_modules;
-use schema;
+use crate::cstore::{self, LoadedMacro};
+use crate::encoder;
+use crate::link_args;
+use crate::native_libs;
+use crate::foreign_modules;
+use crate::schema;
use rustc::ty::query::QueryConfig;
use rustc::middle::cstore::{CrateStore, DepKind,
use syntax::source_map;
use syntax::edition::Edition;
use syntax::parse::source_file_to_stream;
+use syntax::parse::parser::emit_unclosed_delims;
use syntax::symbol::Symbol;
use syntax_pos::{Span, NO_EXPANSION, FileName};
use rustc_data_structures::bit_set::BitSet;
index: CRATE_DEF_INDEX
});
let dep_node = def_path_hash
- .to_dep_node(::rustc::dep_graph::DepKind::CrateMetadata);
+ .to_dep_node(rustc::dep_graph::DepKind::CrateMetadata);
// The DepNodeIndex of the DepNode::CrateMetadata should be
// cached somewhere, so that we can use read_index().
$tcx.dep_graph.read(dep_node);
use syntax::ext::base::SyntaxExtension;
use syntax_ext::proc_macro_impl::BangProcMacro;
- let client = ::proc_macro::bridge::client::Client::expand1(::proc_macro::quote);
+ let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
let ext = SyntaxExtension::ProcMacro {
expander: Box::new(BangProcMacro { client }),
allow_internal_unstable: true,
let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
- let body = source_file_to_stream(&sess.parse_sess, source_file, None);
+ let (body, errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
+ emit_unclosed_delims(&errors, &sess.diagnostic());
// Mark the attrs as used
let attrs = data.get_item_attrs(id.index, sess);
// Decoding metadata from a single crate's metadata
-use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
-use schema::*;
+use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
+use crate::schema::*;
use rustc_data_structures::sync::{Lrc, ReadGuard};
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, Definitions};
use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::hygiene::Mark;
use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
+use log::debug;
pub struct DecodeContext<'a, 'tcx: 'a> {
opaque: opaque::Decoder<'a>,
fn get_variant(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- item: &Entry,
+ item: &Entry<'_>,
index: DefIndex,
adt_kind: ty::AdtKind)
-> ty::VariantDef
#![allow(non_snake_case)]
+use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics};
+
register_long_diagnostics! {
E0454: r##"
A link name was given with an empty name. Erroneous code example:
#[cfg(test)]
mod tests {
use super::*;
- use libc;
use std::mem;
#[test]
#[cfg(unix)]
mod dl {
- use libc;
use std::ffi::{CStr, OsStr, CString};
use std::os::unix::prelude::*;
use std::ptr;
-use index::Index;
-use index_builder::{FromId, IndexBuilder, Untracked};
-use isolated_encoder::IsolatedEncoder;
-use schema::*;
+use crate::index::Index;
+use crate::index_builder::{FromId, IndexBuilder, Untracked};
+use crate::isolated_encoder::IsolatedEncoder;
+use crate::schema::*;
use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
EncodedMetadata, ForeignModule};
use syntax::source_map::Spanned;
use syntax::symbol::keywords;
use syntax_pos::{self, hygiene, FileName, SourceFile, Span};
+use log::{debug, trace};
use rustc::hir::{self, PatKind};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
// symbol associated with them (they weren't translated) or if they're an FFI
// definition (as that's not defined in this crate).
fn encode_exported_symbols(&mut self,
- exported_symbols: &[(ExportedSymbol, SymbolExportLevel)])
+ exported_symbols: &[(ExportedSymbol<'_>, SymbolExportLevel)])
-> EncodedExportedSymbols {
// The metadata symbol name is special. It should not show up in
// downstream crates.
-use schema::*;
+use crate::schema::*;
use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
use rustc_serialize::opaque::Encoder;
use std::slice;
use std::u32;
+use log::debug;
/// While we are generating the metadata, we also track the position
/// of each DefIndex. It is not required that all definitions appear
}
}
- pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry>) {
+ pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry<'_>>) {
assert!(def_id.is_local());
self.record_index(def_id.index, entry);
}
- pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry>) {
+ pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'_>>) {
assert!(entry.position < (u32::MAX as usize));
let position = entry.position as u32;
let space_index = item.address_space().index();
//! give a callback fn, rather than taking a closure: it allows us to
//! easily control precisely what data is given to that fn.
-use encoder::EncodeContext;
-use index::Index;
-use schema::*;
-use isolated_encoder::IsolatedEncoder;
+use crate::encoder::EncodeContext;
+use crate::index::Index;
+use crate::schema::*;
+use crate::isolated_encoder::IsolatedEncoder;
use rustc::hir;
use rustc::hir::def_id::DefId;
/// `DefId` index, or implement the `read` method so that it can add
/// a read of whatever dep-graph nodes are appropriate.
pub trait DepGraphRead {
- fn read(&self, tcx: TyCtxt);
+ fn read(&self, tcx: TyCtxt<'_, '_, '_>);
}
impl DepGraphRead for DefId {
- fn read(&self, _tcx: TyCtxt) {}
+ fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {}
}
impl DepGraphRead for ast::NodeId {
- fn read(&self, _tcx: TyCtxt) {}
+ fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {}
}
impl<T> DepGraphRead for Option<T>
where T: DepGraphRead
{
- fn read(&self, tcx: TyCtxt) {
+ fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
match *self {
Some(ref v) => v.read(tcx),
None => (),
impl<T> DepGraphRead for [T]
where T: DepGraphRead
{
- fn read(&self, tcx: TyCtxt) {
+ fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
for i in self {
i.read(tcx);
}
where $($name: DepGraphRead),*
{
#[allow(non_snake_case)]
- fn read(&self, tcx: TyCtxt) {
+ fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
let &($(ref $name),*) = self;
$($name.read(tcx);)*
}
macro_rules! read_hir {
($t:ty) => {
impl<'tcx> DepGraphRead for &'tcx $t {
- fn read(&self, tcx: TyCtxt) {
+ fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
tcx.hir().read(self.id);
}
}
pub struct Untracked<T>(pub T);
impl<T> DepGraphRead for Untracked<T> {
- fn read(&self, _tcx: TyCtxt) {}
+ fn read(&self, _tcx: TyCtxt<'_, '_, '_>) {}
}
/// Newtype that can be used to package up misc data extracted from a
pub struct FromId<T>(pub ast::NodeId, pub T);
impl<T> DepGraphRead for FromId<T> {
- fn read(&self, tcx: TyCtxt) {
+ fn read(&self, tcx: TyCtxt<'_, '_, '_>) {
tcx.hir().read(self.0);
}
}
-use encoder::EncodeContext;
-use schema::{Lazy, LazySeq};
+use crate::encoder::EncodeContext;
+use crate::schema::{Lazy, LazySeq};
use rustc::ty::TyCtxt;
use rustc_serialize::Encodable;
#![recursion_limit="256"]
+#![deny(rust_2018_idioms)]
+
extern crate libc;
-#[macro_use]
-extern crate log;
-extern crate memmap;
-extern crate stable_deref_trait;
-#[macro_use]
-extern crate syntax;
-extern crate syntax_pos;
-extern crate flate2;
+#[allow(unused_extern_crates)]
extern crate serialize as rustc_serialize; // used by deriving
-extern crate rustc_errors as errors;
-extern crate syntax_ext;
extern crate proc_macro;
#[macro_use]
extern crate rustc;
-extern crate rustc_target;
#[macro_use]
extern crate rustc_data_structures;
//! no means all of the necessary details. Take a look at the rest of
//! metadata::locator or metadata::creader for all the juicy details!
-use cstore::{MetadataRef, MetadataBlob};
-use creader::Library;
-use schema::{METADATA_HEADER, rustc_version};
+use crate::cstore::{MetadataRef, MetadataBlob};
+use crate::creader::Library;
+use crate::schema::{METADATA_HEADER, rustc_version};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
use errors::DiagnosticBuilder;
use syntax::symbol::Symbol;
+use syntax::struct_span_err;
use syntax_pos::Span;
use rustc_target::spec::{Target, TargetTriple};
use rustc_data_structures::owning_ref::OwningRef;
+use log::{debug, info, warn};
+
pub struct CrateMismatch {
path: PathBuf,
got: String,
}
impl fmt::Display for CrateFlavor {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match *self {
CrateFlavor::Rlib => "rlib",
CrateFlavor::Rmeta => "rmeta",
}
}
- let mut err: Option<DiagnosticBuilder> = None;
+ let mut err: Option<DiagnosticBuilder<'_>> = None;
for (lib, kind) in m {
info!("{} reading metadata from: {}", flavor, lib.display());
let (hash, metadata) =
use syntax::source_map::Span;
use syntax::feature_gate::{self, GateIssue};
use syntax::symbol::Symbol;
+use syntax::{span_err, struct_span_err};
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec<NativeLibrary> {
let mut collector = Collector {
-use index;
+use crate::index;
use rustc::hir;
use rustc::hir::def::{self, CtorKind};
ImplFinal,
}
-impl_stable_hash_for!(enum ::schema::AssociatedContainer {
+impl_stable_hash_for!(enum crate::schema::AssociatedContainer {
TraitRequired,
TraitWithDefault,
ImplDefault,
authors = ["The Rust Project Developers"]
name = "rustc_mir"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_mir"
arena = { path = "../libarena" }
bitflags = "1.0"
either = "1.5.0"
-graphviz = { path = "../libgraphviz" }
+dot = { path = "../libgraphviz", package = "graphviz" }
log = "0.4"
log_settings = "0.1.1"
polonius-engine = "0.6.2"
-use borrow_check::place_ext::PlaceExt;
-use borrow_check::nll::ToRegionVid;
-use dataflow::indexes::BorrowIndex;
-use dataflow::move_paths::MoveData;
+use crate::borrow_check::place_ext::PlaceExt;
+use crate::borrow_check::nll::ToRegionVid;
+use crate::dataflow::indexes::BorrowIndex;
+use crate::dataflow::move_paths::MoveData;
use rustc::mir::traversal;
use rustc::mir::visit::{
PlaceContext, Visitor, NonUseContext, MutatingUseContext, NonMutatingUseContext
}
impl<'tcx> fmt::Display for BorrowData<'tcx> {
- fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
let kind = match self.kind {
mir::BorrowKind::Shared => "",
mir::BorrowKind::Shallow => "shallow ",
-use borrow_check::nll::explain_borrow::BorrowExplanation;
-use borrow_check::nll::region_infer::{RegionName, RegionNameSource};
-use borrow_check::prefixes::IsPrefixOf;
-use borrow_check::WriteKind;
+use crate::borrow_check::nll::explain_borrow::BorrowExplanation;
+use crate::borrow_check::nll::region_infer::{RegionName, RegionNameSource};
+use crate::borrow_check::prefixes::IsPrefixOf;
+use crate::borrow_check::WriteKind;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::middle::region::ScopeTree;
use super::borrow_set::BorrowData;
use super::{Context, MirBorrowckCtxt};
use super::{InitializationRequiringAction, PrefixSet};
-use dataflow::drop_flag_effects;
-use dataflow::move_paths::indexes::MoveOutIndex;
-use dataflow::move_paths::MovePathIndex;
-use util::borrowck_errors::{BorrowckErrors, Origin};
+use crate::dataflow::drop_flag_effects;
+use crate::dataflow::move_paths::indexes::MoveOutIndex;
+use crate::dataflow::move_paths::MovePathIndex;
+use crate::util::borrowck_errors::{BorrowckErrors, Origin};
#[derive(Debug)]
struct MoveSite {
}
/// End-user visible description of the `field`nth field of `base`
- fn describe_field(&self, base: &Place, field: Field) -> String {
+ fn describe_field(&self, base: &Place<'_>, field: Field) -> String {
match *base {
Place::Local(local) => {
let local = &self.mir.local_decls[local];
}
/// End-user visible description of the `field_index`nth field of `ty`
- fn describe_field_from_ty(&self, ty: &ty::Ty, field: Field) -> String {
+ fn describe_field_from_ty(&self, ty: &ty::Ty<'_>, field: Field) -> String {
if ty.is_box() {
// If the type is a box, the field is described from the boxed type
self.describe_field_from_ty(&ty.boxed_ty(), field)
fn annotate_argument_and_return_for_borrow(
&self,
borrow: &BorrowData<'tcx>,
- ) -> Option<AnnotatedBorrowFnSignature> {
+ ) -> Option<AnnotatedBorrowFnSignature<'_>> {
// Define a fallback for when we can't match a closure.
let fallback = || {
let is_closure = self.infcx.tcx.is_closure(self.mir_def_id);
&self,
did: DefId,
sig: ty::PolyFnSig<'tcx>,
- ) -> Option<AnnotatedBorrowFnSignature> {
+ ) -> Option<AnnotatedBorrowFnSignature<'_>> {
debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig);
let is_closure = self.infcx.tcx.is_closure(did);
let fn_node_id = self.infcx.tcx.hir().as_local_node_id(did)?;
}
// Add a span label to the arguments of the closure, if it exists.
- pub(super) fn args_span_label(self, err: &mut DiagnosticBuilder, message: impl Into<String>) {
+ pub(super) fn args_span_label(
+ self,
+ err: &mut DiagnosticBuilder<'_>,
+ message: impl Into<String>,
+ ) {
if let UseSpans::ClosureUse { args_span, .. } = self {
err.span_label(args_span, message);
}
}
// Add a span label to the use of the captured variable, if it exists.
- pub(super) fn var_span_label(self, err: &mut DiagnosticBuilder, message: impl Into<String>) {
+ pub(super) fn var_span_label(
+ self,
+ err: &mut DiagnosticBuilder<'_>,
+ message: impl Into<String>,
+ ) {
if let UseSpans::ClosureUse { var_span, .. } = self {
err.span_label(var_span, message);
}
/// Helper to retrieve span(s) of given borrow from the current MIR
/// representation
- pub(super) fn retrieve_borrow_spans(&self, borrow: &BorrowData) -> UseSpans {
+ pub(super) fn retrieve_borrow_spans(&self, borrow: &BorrowData<'_>) -> UseSpans {
let span = self.mir.source_info(borrow.reserve_location).span;
self.borrow_spans(span, borrow.reserve_location)
}
use rustc::ty::RegionVid;
use rustc_data_structures::bit_set::BitIter;
-use borrow_check::location::LocationIndex;
+use crate::borrow_check::location::LocationIndex;
use polonius_engine::Output;
-use dataflow::move_paths::indexes::BorrowIndex;
-use dataflow::move_paths::HasMoveData;
-use dataflow::Borrows;
-use dataflow::EverInitializedPlaces;
-use dataflow::{FlowAtLocation, FlowsAtLocation};
-use dataflow::MaybeUninitializedPlaces;
+use crate::dataflow::move_paths::indexes::BorrowIndex;
+use crate::dataflow::move_paths::HasMoveData;
+use crate::dataflow::Borrows;
+use crate::dataflow::EverInitializedPlaces;
+use crate::dataflow::{FlowAtLocation, FlowsAtLocation};
+use crate::dataflow::MaybeUninitializedPlaces;
use either::Either;
use std::fmt;
use std::rc::Rc;
}
}
- crate fn with_outgoing_borrows(&self, op: impl FnOnce(BitIter<BorrowIndex>)) {
+ crate fn with_outgoing_borrows(&self, op: impl FnOnce(BitIter<'_, BorrowIndex>)) {
self.borrows.with_iter_outgoing(op)
}
}
}
impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = String::new();
s.push_str("borrows in effect: [");
//! This query borrow-checks the MIR to (further) ensure it is not broken.
-use borrow_check::nll::region_infer::RegionInferenceContext;
+use crate::borrow_check::nll::region_infer::RegionInferenceContext;
use rustc::hir;
use rustc::hir::Node;
use rustc::hir::def_id::DefId;
use syntax_pos::Span;
-use dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex};
-use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MoveError};
-use dataflow::Borrows;
-use dataflow::DataflowResultsConsumer;
-use dataflow::FlowAtLocation;
-use dataflow::MoveDataParamEnv;
-use dataflow::{do_dataflow, DebugFormatted};
-use dataflow::EverInitializedPlaces;
-use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
-use util::borrowck_errors::{BorrowckErrors, Origin};
+use crate::dataflow::indexes::{BorrowIndex, InitIndex, MoveOutIndex, MovePathIndex};
+use crate::dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MoveError};
+use crate::dataflow::Borrows;
+use crate::dataflow::DataflowResultsConsumer;
+use crate::dataflow::FlowAtLocation;
+use crate::dataflow::MoveDataParamEnv;
+use crate::dataflow::{do_dataflow, DebugFormatted};
+use crate::dataflow::EverInitializedPlaces;
+use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
+use crate::util::borrowck_errors::{BorrowckErrors, Origin};
use self::borrow_set::{BorrowData, BorrowSet};
use self::flows::Flows;
pub(crate) mod nll;
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
mir_borrowck,
..*providers
}
let opt_closure_req = tcx.infer_ctxt().enter(|infcx| {
- let input_mir: &Mir = &input_mir.borrow();
+ let input_mir: &Mir<'_> = &input_mir.borrow();
do_mir_borrowck(&infcx, input_mir, def_id)
});
debug!("mir_borrowck done");
use rustc_errors::{DiagnosticBuilder,Applicability};
use syntax_pos::Span;
-use borrow_check::MirBorrowckCtxt;
-use borrow_check::prefixes::PrefixSet;
-use dataflow::move_paths::{
+use crate::borrow_check::MirBorrowckCtxt;
+use crate::borrow_check::prefixes::PrefixSet;
+use crate::dataflow::move_paths::{
IllegalMoveOrigin, IllegalMoveOriginKind, InitLocation,
LookupResult, MoveError, MovePathIndex,
};
-use util::borrowck_errors::{BorrowckErrors, Origin};
+use crate::util::borrowck_errors::{BorrowckErrors, Origin};
// Often when desugaring a pattern match we may have many individual moves in
// MIR that are all part of one operation from the user's point-of-view. For
}
impl Display for BorrowedContentSource {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
BorrowedContentSource::Arc => write!(f, "an `Arc`"),
BorrowedContentSource::Rc => write!(f, "an `Rc`"),
fn report(&mut self, error: GroupedMoveError<'tcx>) {
let (mut err, err_span) = {
- let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind) =
+ let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind<'_>) =
match error {
GroupedMoveError::MovesFromPlace {
span,
use syntax_pos::Span;
use syntax_pos::symbol::keywords;
-use dataflow::move_paths::InitLocation;
-use borrow_check::MirBorrowckCtxt;
-use util::borrowck_errors::{BorrowckErrors, Origin};
-use util::collect_writes::FindAssignments;
-use util::suggest_ref_mut;
+use crate::dataflow::move_paths::InitLocation;
+use crate::borrow_check::MirBorrowckCtxt;
+use crate::util::borrowck_errors::{BorrowckErrors, Origin};
+use crate::util::collect_writes::FindAssignments;
+use crate::util::suggest_ref_mut;
use rustc_errors::Applicability;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
})
}
-fn is_closure_or_generator(ty: ty::Ty) -> bool {
+fn is_closure_or_generator(ty: ty::Ty<'_>) -> bool {
ty.is_closure() || ty.is_generator()
}
-use borrow_check::borrow_set::BorrowSet;
-use borrow_check::location::LocationTable;
-use borrow_check::nll::ToRegionVid;
-use borrow_check::nll::facts::AllFacts;
-use borrow_check::nll::region_infer::values::LivenessValues;
+use crate::borrow_check::borrow_set::BorrowSet;
+use crate::borrow_check::location::LocationTable;
+use crate::borrow_check::nll::ToRegionVid;
+use crate::borrow_check::nll::facts::AllFacts;
+use crate::borrow_check::nll::region_infer::values::LivenessValues;
use rustc::infer::InferCtxt;
use rustc::mir::visit::TyContext;
use rustc::mir::visit::Visitor;
-use borrow_check::nll::type_check::Locations;
-use borrow_check::nll::constraints::ConstraintIndex;
-use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
+use crate::borrow_check::nll::type_check::Locations;
+use crate::borrow_check::nll::constraints::ConstraintIndex;
+use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
use rustc::mir::ConstraintCategory;
use rustc::ty::RegionVid;
use rustc_data_structures::graph;
use rustc::ty::RegionVid;
use rustc_data_structures::graph::scc::Sccs;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use borrow_check::nll::type_check::Locations;
+use crate::borrow_check::nll::type_check::Locations;
use std::fmt;
use std::ops::Deref;
}
impl fmt::Debug for OutlivesConstraint {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"({:?}: {:?}) due to {:?}",
use std::collections::VecDeque;
use std::rc::Rc;
-use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
-use borrow_check::nll::ToRegionVid;
+use crate::borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
+use crate::borrow_check::nll::ToRegionVid;
+use crate::util::liveness::{self, DefUse};
use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
use rustc::mir::{Local, Location, Mir};
use rustc::ty::{RegionVid, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
-use util::liveness::{self, DefUse};
crate fn find<'tcx>(
mir: &Mir<'tcx>,
-use borrow_check::borrow_set::BorrowData;
-use borrow_check::error_reporting::UseSpans;
-use borrow_check::nll::ConstraintDescription;
-use borrow_check::nll::region_infer::{Cause, RegionName};
-use borrow_check::{Context, MirBorrowckCtxt, WriteKind};
+use crate::borrow_check::borrow_set::BorrowData;
+use crate::borrow_check::error_reporting::UseSpans;
+use crate::borrow_check::nll::ConstraintDescription;
+use crate::borrow_check::nll::region_infer::{Cause, RegionName};
+use crate::borrow_check::{Context, MirBorrowckCtxt, WriteKind};
use rustc::ty::{self, TyCtxt};
use rustc::mir::{
CastKind, ConstraintCategory, FakeReadCause, Local, Location, Mir, Operand,
mod find_use;
-pub(in borrow_check) enum BorrowExplanation {
+pub(in crate::borrow_check) enum BorrowExplanation {
UsedLater(LaterUseKind, Span),
UsedLaterInLoop(LaterUseKind, Span),
UsedLaterWhenDropped {
}
#[derive(Clone, Copy)]
-pub(in borrow_check) enum LaterUseKind {
+pub(in crate::borrow_check) enum LaterUseKind {
TraitCapture,
ClosureCapture,
Call,
}
impl BorrowExplanation {
- pub(in borrow_check) fn is_explained(&self) -> bool {
+ pub(in crate::borrow_check) fn is_explained(&self) -> bool {
match self {
BorrowExplanation::Unexplained => false,
_ => true,
}
}
- pub(in borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>(
+ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>(
&self,
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
/// - second half is the place being accessed
///
/// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
- pub(in borrow_check) fn explain_why_borrow_contains_point(
+ pub(in crate::borrow_check) fn explain_why_borrow_contains_point(
&self,
context: Context,
borrow: &BorrowData<'tcx>,
-use borrow_check::location::{LocationIndex, LocationTable};
-use dataflow::indexes::BorrowIndex;
+use crate::borrow_check::location::{LocationIndex, LocationTable};
+use crate::dataflow::indexes::BorrowIndex;
use polonius_engine::AllFacts as PoloniusAllFacts;
use polonius_engine::Atom;
use rustc::ty::{RegionVid, TyCtxt};
-use borrow_check::borrow_set::BorrowSet;
-use borrow_check::location::LocationTable;
-use borrow_check::{JustWrite, WriteAndRead};
-use borrow_check::{AccessDepth, Deep, Shallow};
-use borrow_check::{ReadOrWrite, Activation, Read, Reservation, Write};
-use borrow_check::{Context, ContextKind};
-use borrow_check::{LocalMutationIsAllowed, MutateMode};
-use borrow_check::ArtificialField;
-use borrow_check::{ReadKind, WriteKind};
-use borrow_check::nll::facts::AllFacts;
-use borrow_check::path_utils::*;
-use dataflow::move_paths::indexes::BorrowIndex;
+use crate::borrow_check::borrow_set::BorrowSet;
+use crate::borrow_check::location::LocationTable;
+use crate::borrow_check::{JustWrite, WriteAndRead};
+use crate::borrow_check::{AccessDepth, Deep, Shallow};
+use crate::borrow_check::{ReadOrWrite, Activation, Read, Reservation, Write};
+use crate::borrow_check::{Context, ContextKind};
+use crate::borrow_check::{LocalMutationIsAllowed, MutateMode};
+use crate::borrow_check::ArtificialField;
+use crate::borrow_check::{ReadKind, WriteKind};
+use crate::borrow_check::nll::facts::AllFacts;
+use crate::borrow_check::path_utils::*;
+use crate::dataflow::move_paths::indexes::BorrowIndex;
use rustc::ty::TyCtxt;
use rustc::mir::visit::Visitor;
use rustc::mir::{BasicBlock, Location, Mir, Place, Rvalue};
-use borrow_check::borrow_set::BorrowSet;
-use borrow_check::location::{LocationIndex, LocationTable};
-use borrow_check::nll::facts::AllFactsExt;
-use borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
-use borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap;
-use borrow_check::nll::region_infer::values::RegionValueElements;
-use dataflow::indexes::BorrowIndex;
-use dataflow::move_paths::MoveData;
-use dataflow::FlowAtLocation;
-use dataflow::MaybeInitializedPlaces;
+use crate::borrow_check::borrow_set::BorrowSet;
+use crate::borrow_check::location::{LocationIndex, LocationTable};
+use crate::borrow_check::nll::facts::AllFactsExt;
+use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
+use crate::borrow_check::nll::type_check::liveness::liveness_map::NllLivenessMap;
+use crate::borrow_check::nll::region_infer::values::RegionValueElements;
+use crate::dataflow::indexes::BorrowIndex;
+use crate::dataflow::move_paths::MoveData;
+use crate::dataflow::FlowAtLocation;
+use crate::dataflow::MaybeInitializedPlaces;
+use crate::transform::MirSource;
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir};
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
-use transform::MirSource;
use self::mir_util::PassWhere;
use polonius_engine::{Algorithm, Output};
-use util as mir_util;
-use util::pretty;
+use crate::util as mir_util;
+use crate::util::pretty;
mod constraint_generation;
pub mod explain_borrow;
/// scraping out the set of universal regions (e.g., region parameters)
/// declared on the function. That set will need to be given to
/// `compute_regions`.
-pub(in borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
+pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
def_id: DefId,
param_env: ty::ParamEnv<'tcx>,
/// Computes the (non-lexical) regions from the input MIR.
///
/// This may result in errors being reported.
-pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
+pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
def_id: DefId,
universal_regions: UniversalRegions<'tcx>,
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
source: MirSource,
mir: &Mir<'tcx>,
- regioncx: &RegionInferenceContext,
- closure_region_requirements: &Option<ClosureRegionRequirements>,
+ regioncx: &RegionInferenceContext<'_>,
+ closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
) {
if !mir_util::dump_enabled(infcx.tcx, "nll", source) {
return;
);
// Also dump the inference graph constraints as a graphviz file.
- let _: io::Result<()> = try_block! {
+ let _: io::Result<()> = try {
let mut file =
pretty::create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, source)?;
regioncx.dump_graphviz_raw_constraints(&mut file)?;
};
// Also dump the inference graph constraints as a graphviz file.
- let _: io::Result<()> = try_block! {
+ let _: io::Result<()> = try {
let mut file =
pretty::create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, source)?;
regioncx.dump_graphviz_scc_constraints(&mut file)?;
mir: &Mir<'tcx>,
mir_def_id: DefId,
regioncx: &RegionInferenceContext<'tcx>,
- closure_region_requirements: &Option<ClosureRegionRequirements>,
+ closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
errors_buffer: &mut Vec<Diagnostic>,
) {
let tcx = infcx.tcx;
}
fn for_each_region_constraint(
- closure_region_requirements: &ClosureRegionRequirements,
+ closure_region_requirements: &ClosureRegionRequirements<'_>,
with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
) -> io::Result<()> {
for req in &closure_region_requirements.outlives_requirements {
-use borrow_check::nll::constraints::OutlivesConstraint;
-use borrow_check::nll::region_infer::RegionInferenceContext;
-use borrow_check::nll::type_check::Locations;
-use borrow_check::nll::universal_regions::DefiningTy;
-use borrow_check::nll::ConstraintDescription;
+use crate::borrow_check::nll::constraints::OutlivesConstraint;
+use crate::borrow_check::nll::region_infer::RegionInferenceContext;
+use crate::borrow_check::nll::type_check::Locations;
+use crate::borrow_check::nll::universal_regions::DefiningTy;
+use crate::borrow_check::nll::ConstraintDescription;
+use crate::util::borrowck_errors::{BorrowckErrors, Origin};
use rustc::hir::def_id::DefId;
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc::infer::InferCtxt;
use syntax::errors::Applicability;
use syntax::symbol::keywords;
use syntax_pos::Span;
-use util::borrowck_errors::{BorrowckErrors, Origin};
mod region_name;
mod var_name;
use std::fmt::{self, Display};
-use borrow_check::nll::region_infer::RegionInferenceContext;
-use borrow_check::nll::universal_regions::DefiningTy;
-use borrow_check::nll::ToRegionVid;
+use crate::borrow_check::nll::region_infer::RegionInferenceContext;
+use crate::borrow_check::nll::universal_regions::DefiningTy;
+use crate::borrow_check::nll::ToRegionVid;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
}
impl Display for RegionName {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name)
}
}
-use borrow_check::nll::region_infer::RegionInferenceContext;
-use borrow_check::nll::ToRegionVid;
+use crate::borrow_check::nll::region_infer::RegionInferenceContext;
+use crate::borrow_check::nll::ToRegionVid;
use rustc::mir::{Local, Mir};
use rustc::ty::{RegionVid, TyCtxt};
use rustc_data_structures::indexed_vec::Idx;
//! data to rendered labels.
use super::*;
-use borrow_check::nll::constraints::OutlivesConstraint;
-use dot;
+use crate::borrow_check::nll::constraints::OutlivesConstraint;
use std::borrow::Cow;
use std::io::{self, Write};
use super::universal_regions::UniversalRegions;
-use borrow_check::nll::constraints::graph::NormalConstraintGraph;
-use borrow_check::nll::constraints::{ConstraintSccIndex, ConstraintSet, OutlivesConstraint};
-use borrow_check::nll::region_infer::values::{PlaceholderIndices, RegionElement, ToElementIndex};
-use borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations;
-use borrow_check::nll::type_check::Locations;
+use crate::borrow_check::nll::constraints::graph::NormalConstraintGraph;
+use crate::borrow_check::nll::constraints::{ConstraintSccIndex, ConstraintSet, OutlivesConstraint};
+use crate::borrow_check::nll::region_infer::values::{
+ PlaceholderIndices, RegionElement, ToElementIndex
+};
+use crate::borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations;
+use crate::borrow_check::nll::type_check::Locations;
use rustc::hir::def_id::DefId;
use rustc::infer::canonical::QueryRegionConstraint;
use rustc::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
-use borrow_check::nll::constraints::OutlivesConstraint;
-use borrow_check::nll::region_infer::TypeTest;
-use borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
-use borrow_check::nll::universal_regions::UniversalRegions;
-use borrow_check::nll::ToRegionVid;
+use crate::borrow_check::nll::constraints::OutlivesConstraint;
+use crate::borrow_check::nll::region_infer::TypeTest;
+use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
+use crate::borrow_check::nll::universal_regions::UniversalRegions;
+use crate::borrow_check::nll::ToRegionVid;
use rustc::infer::canonical::QueryRegionConstraint;
use rustc::infer::outlives::env::RegionBoundPairs;
use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
-use borrow_check::nll::type_check::constraint_conversion;
-use borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
-use borrow_check::nll::universal_regions::UniversalRegions;
-use borrow_check::nll::ToRegionVid;
+use crate::borrow_check::nll::type_check::constraint_conversion;
+use crate::borrow_check::nll::type_check::{Locations, MirTypeckRegionConstraints};
+use crate::borrow_check::nll::universal_regions::UniversalRegions;
+use crate::borrow_check::nll::ToRegionVid;
use rustc::infer::canonical::QueryRegionConstraint;
use rustc::infer::outlives::free_region_map::FreeRegionRelations;
use rustc::infer::region_constraints::GenericKind;
//! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
//! contain revealed `impl Trait` values).
-use borrow_check::nll::universal_regions::UniversalRegions;
+use crate::borrow_check::nll::universal_regions::UniversalRegions;
use rustc::infer::LateBoundRegionConversionTime;
use rustc::mir::*;
use rustc::ty::Ty;
//! liveness code so that it only operates over variables with regions in their
//! types, instead of all variables.
-use borrow_check::nll::ToRegionVid;
-use borrow_check::nll::facts::{AllFacts, AllFactsExt};
+use crate::borrow_check::nll::ToRegionVid;
+use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt};
+use crate::util::liveness::LiveVariableMap;
use rustc::mir::{Local, Mir};
use rustc::ty::{RegionVid, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use util::liveness::LiveVariableMap;
/// Map between Local and LiveVar indices: the purpose of this
/// map is to define the subset of local variables for which we need
-use borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
-use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
+use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
+use crate::borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
+use crate::util::liveness::{categorize, DefUse, LiveVariableMap};
use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{Local, Location, Mir};
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::vec_linked_list as vll;
-use util::liveness::{categorize, DefUse, LiveVariableMap};
/// A map that cross references each local with the locations where it
/// is defined (assigned), used, or dropped. Used during liveness
-use borrow_check::location::LocationTable;
-use borrow_check::nll::region_infer::values::RegionValueElements;
-use borrow_check::nll::constraints::ConstraintSet;
-use borrow_check::nll::NllLivenessMap;
-use borrow_check::nll::universal_regions::UniversalRegions;
-use dataflow::move_paths::MoveData;
-use dataflow::MaybeInitializedPlaces;
-use dataflow::FlowAtLocation;
+use crate::borrow_check::location::LocationTable;
+use crate::borrow_check::nll::region_infer::values::RegionValueElements;
+use crate::borrow_check::nll::constraints::ConstraintSet;
+use crate::borrow_check::nll::NllLivenessMap;
+use crate::borrow_check::nll::universal_regions::UniversalRegions;
+use crate::dataflow::move_paths::MoveData;
+use crate::dataflow::MaybeInitializedPlaces;
+use crate::dataflow::FlowAtLocation;
use rustc::mir::Mir;
use rustc::ty::RegionVid;
use rustc_data_structures::fx::FxHashSet;
-use borrow_check::location::LocationTable;
-use borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
-use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
-use borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
-use borrow_check::nll::type_check::NormalizeLocation;
-use borrow_check::nll::type_check::TypeChecker;
-use dataflow::move_paths::indexes::MovePathIndex;
-use dataflow::move_paths::MoveData;
-use dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
+use crate::borrow_check::location::LocationTable;
+use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
+use crate::borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
+use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
+use crate::borrow_check::nll::type_check::NormalizeLocation;
+use crate::borrow_check::nll::type_check::TypeChecker;
+use crate::dataflow::move_paths::indexes::MovePathIndex;
+use crate::dataflow::move_paths::MoveData;
+use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
+use crate::util::liveness::LiveVariableMap;
use rustc::infer::canonical::QueryRegionConstraint;
use rustc::mir::{BasicBlock, ConstraintCategory, Local, Location, Mir};
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
use rustc_data_structures::bit_set::HybridBitSet;
use rustc_data_structures::fx::FxHashMap;
use std::rc::Rc;
-use util::liveness::LiveVariableMap;
/// This is the heart of the liveness computation. For each variable X
/// that requires a liveness computation, it walks over all the uses
#![allow(unreachable_code)]
-use borrow_check::borrow_set::BorrowSet;
-use borrow_check::location::LocationTable;
-use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
-use borrow_check::nll::facts::AllFacts;
-use borrow_check::nll::region_infer::values::LivenessValues;
-use borrow_check::nll::region_infer::values::PlaceholderIndex;
-use borrow_check::nll::region_infer::values::PlaceholderIndices;
-use borrow_check::nll::region_infer::values::RegionValueElements;
-use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
-use borrow_check::nll::renumber;
-use borrow_check::nll::type_check::free_region_relations::{
+use crate::borrow_check::borrow_set::BorrowSet;
+use crate::borrow_check::location::LocationTable;
+use crate::borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
+use crate::borrow_check::nll::facts::AllFacts;
+use crate::borrow_check::nll::region_infer::values::LivenessValues;
+use crate::borrow_check::nll::region_infer::values::PlaceholderIndex;
+use crate::borrow_check::nll::region_infer::values::PlaceholderIndices;
+use crate::borrow_check::nll::region_infer::values::RegionValueElements;
+use crate::borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
+use crate::borrow_check::nll::renumber;
+use crate::borrow_check::nll::type_check::free_region_relations::{
CreateResult, UniversalRegionRelations,
};
-use borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
-use borrow_check::nll::ToRegionVid;
-use dataflow::move_paths::MoveData;
-use dataflow::FlowAtLocation;
-use dataflow::MaybeInitializedPlaces;
+use crate::borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
+use crate::borrow_check::nll::ToRegionVid;
+use crate::dataflow::move_paths::MoveData;
+use crate::dataflow::FlowAtLocation;
+use crate::dataflow::MaybeInitializedPlaces;
+use crate::transform::{MirPass, MirSource};
use either::Either;
use rustc::hir;
use rustc::hir::def_id::DefId;
use std::rc::Rc;
use std::{fmt, iter};
use syntax_pos::{Span, DUMMY_SP};
-use transform::{MirPass, MirSource};
macro_rules! span_mirbug {
($context:expr, $elem:expr, $($message:tt)*) => ({
extra(&mut checker)
}
-fn translate_outlives_facts(cx: &mut BorrowCheckContext) {
+fn translate_outlives_facts(cx: &mut BorrowCheckContext<'_, '_>) {
if let Some(facts) = cx.all_facts {
let location_table = cx.location_table;
facts
}
}
-fn mirbug(tcx: TyCtxt, span: Span, msg: &str) {
+fn mirbug(tcx: TyCtxt<'_, '_, '_>, span: Span, msg: &str) {
// We sometimes see MIR failures (notably predicate failures) due to
// the fact that we check rvalue sized predicates here. So use `delay_span_bug`
// to avoid reporting bugs in those cases.
}
}
- fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
+ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext<'_>, location: Location) {
self.sanitize_place(place, location, context);
}
&mut self,
place: &Place<'tcx>,
location: Location,
- context: PlaceContext,
+ context: PlaceContext<'_>,
) -> PlaceTy<'tcx> {
debug!("sanitize_place: {:?}", place);
let place_ty = match *place {
-use borrow_check::nll::constraints::OutlivesConstraint;
-use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
+use crate::borrow_check::nll::constraints::OutlivesConstraint;
+use crate::borrow_check::nll::type_check::{BorrowCheckContext, Locations};
use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate, NormalizationStrategy};
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
use rustc::mir::ConstraintCategory;
-use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation};
-use borrow_check::places_conflict;
-use borrow_check::Context;
-use borrow_check::AccessDepth;
-use dataflow::indexes::BorrowIndex;
+use crate::borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation};
+use crate::borrow_check::places_conflict;
+use crate::borrow_check::Context;
+use crate::borrow_check::AccessDepth;
+use crate::dataflow::indexes::BorrowIndex;
use rustc::mir::{BasicBlock, Location, Mir, Place};
use rustc::mir::{ProjectionElem, BorrowKind};
use rustc::ty::TyCtxt;
use rustc::mir::ProjectionElem;
use rustc::mir::{Local, Mir, Place, Mutability};
use rustc::ty::{self, TyCtxt};
-use borrow_check::borrow_set::LocalsStateAtExit;
+use crate::borrow_check::borrow_set::LocalsStateAtExit;
/// Extension methods for the `Place` type.
crate trait PlaceExt<'tcx> {
-use borrow_check::ArtificialField;
-use borrow_check::Overlap;
-use borrow_check::{Deep, Shallow, AccessDepth};
+use crate::borrow_check::ArtificialField;
+use crate::borrow_check::Overlap;
+use crate::borrow_check::{Deep, Shallow, AccessDepth};
use rustc::hir;
use rustc::mir::{BorrowKind, Mir, Place};
use rustc::mir::{Projection, ProjectionElem};
use rustc_data_structures::fx::FxHashSet;
-use borrow_check::MirBorrowckCtxt;
+use crate::borrow_check::MirBorrowckCtxt;
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
/// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes
-use build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
-use build::ForGuard::OutsideGuard;
-use build::matches::ArmHasGuard;
-use hair::*;
+use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
+use crate::build::ForGuard::OutsideGuard;
+use crate::build::matches::ArmHasGuard;
+use crate::hair::*;
use rustc::mir::*;
use rustc::hir;
use syntax_pos::Span;
//! Routines for manipulating the control-flow graph.
-use build::CFG;
+use crate::build::CFG;
use rustc::mir::*;
impl<'tcx> CFG<'tcx> {
//! See docs in build/expr/mod.rs
-use build::Builder;
-use hair::*;
+use crate::build::Builder;
+use crate::hair::*;
use rustc::mir::*;
use rustc::ty::CanonicalUserTypeAnnotation;
//! See docs in build/expr/mod.rs
-use build::expr::category::Category;
-use build::{BlockAnd, BlockAndExtension, Builder};
-use hair::*;
+use crate::build::expr::category::Category;
+use crate::build::{BlockAnd, BlockAndExtension, Builder};
+use crate::hair::*;
use rustc::middle::region;
use rustc::mir::*;
//! See docs in build/expr/mod.rs
-use build::expr::category::Category;
-use build::ForGuard::{OutsideGuard, RefWithinGuard};
-use build::{BlockAnd, BlockAndExtension, Builder};
-use hair::*;
+use crate::build::expr::category::Category;
+use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
+use crate::build::{BlockAnd, BlockAndExtension, Builder};
+use crate::hair::*;
use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
use rustc::mir::*;
use rustc::ty::{CanonicalUserTypeAnnotation, Variance};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
-use build::expr::category::{Category, RvalueFunc};
-use build::{BlockAnd, BlockAndExtension, Builder};
-use hair::*;
+use crate::build::expr::category::{Category, RvalueFunc};
+use crate::build::{BlockAnd, BlockAndExtension, Builder};
+use crate::hair::*;
use rustc::middle::region;
use rustc::mir::interpret::EvalErrorKind;
use rustc::mir::*;
span: expr_span,
ty: this.hir.tcx().types.u32,
user_ty: None,
- literal: this.hir.tcx().intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: this.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::from_bits(
this.hir.tcx(),
0,
//! See docs in build/expr/mod.rs
-use build::{BlockAnd, BlockAndExtension, Builder};
-use hair::*;
+use crate::build::{BlockAnd, BlockAndExtension, Builder};
+use crate::hair::*;
use rustc::middle::region;
use rustc::mir::*;
-use hair::*;
+use crate::hair::*;
#[derive(Debug, PartialEq)]
pub enum Category {
//! See docs in build/expr/mod.rs
-use build::expr::category::{Category, RvalueFunc};
-use build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
-use hair::*;
+use crate::build::expr::category::{Category, RvalueFunc};
+use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
+use crate::hair::*;
use rustc::mir::*;
use rustc::ty;
-use build::scope::BreakableScope;
-use build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
-use hair::*;
+use crate::build::scope::BreakableScope;
+use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
+use crate::hair::*;
use rustc::mir::*;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
//! wrapped up as expressions (e.g., blocks). To make this ergonomic, we use this
//! latter `EvalInto` trait.
-use build::{BlockAnd, Builder};
-use hair::*;
+use crate::build::{BlockAnd, Builder};
+use crate::hair::*;
use rustc::mir::*;
-pub(in build) trait EvalInto<'tcx> {
+pub(in crate::build) trait EvalInto<'tcx> {
fn eval_into<'a, 'gcx>(self,
builder: &mut Builder<'a, 'gcx, 'tcx>,
destination: &Place<'tcx>,
//! includes the high-level algorithm, the submodules contain the
//! details.
-use build::scope::{CachedBlock, DropKind};
-use build::ForGuard::{self, OutsideGuard, RefWithinGuard, ValWithinGuard};
-use build::{BlockAnd, BlockAndExtension, Builder};
-use build::{GuardFrame, GuardFrameLocal, LocalsForNode};
-use hair::*;
+use crate::build::scope::{CachedBlock, DropKind};
+use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard, ValWithinGuard};
+use crate::build::{BlockAnd, BlockAndExtension, Builder};
+use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode};
+use crate::hair::*;
use rustc::mir::*;
use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty};
use rustc::ty::layout::VariantIdx;
//! sort of test: for example, testing which variant an enum is, or
//! testing a value against a constant.
-use build::Builder;
-use build::matches::{Ascription, Binding, MatchPair, Candidate};
-use hair::*;
+use crate::build::Builder;
+use crate::build::matches::{Ascription, Binding, MatchPair, Candidate};
+use crate::hair::*;
use rustc::ty;
use rustc::ty::layout::{Integer, IntegerExt, Size};
use syntax::attr::{SignedInt, UnsignedInt};
// identify what tests are needed, perform the tests, and then filter
// the candidates based on the result.
-use build::Builder;
-use build::matches::{Candidate, MatchPair, Test, TestKind};
-use hair::*;
-use hair::pattern::compare_const_vals;
+use crate::build::Builder;
+use crate::build::matches::{Candidate, MatchPair, Test, TestKind};
+use crate::hair::*;
+use crate::hair::pattern::compare_const_vals;
use rustc_data_structures::bit_set::BitSet;
use rustc_data_structures::fx::FxHashMap;
use rustc::ty::{self, Ty};
}
let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap();
let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty.into()]);
- let method = self.hir.tcx().intern_lazy_const(ty::LazyConst::Evaluated(method));
+ let method = self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(method));
let re_erased = self.hir.tcx().types.re_erased;
// take the argument by reference
-use build::Builder;
-use build::matches::MatchPair;
-use hair::*;
+use crate::build::Builder;
+use crate::build::matches::MatchPair;
+use crate::hair::*;
use rustc::mir::*;
use std::u32;
use std::convert::TryInto;
//! Miscellaneous builder routines that are not specific to building any particular
//! kind of thing.
-use build::Builder;
+use crate::build::Builder;
use rustc::ty::{self, Ty};
span,
ty,
user_ty: None,
- literal: self.hir.tcx().intern_lazy_const(ty::LazyConst::Evaluated(literal)),
+ literal: self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(literal)),
};
Operand::Constant(constant)
}
-use build;
-use build::scope::{CachedBlock, DropKind};
-use hair::cx::Cx;
-use hair::{LintLevel, BindingMode, PatternKind};
+use crate::build;
+use crate::build::scope::{CachedBlock, DropKind};
+use crate::hair::cx::Cx;
+use crate::hair::{LintLevel, BindingMode, PatternKind};
+use crate::shim;
+use crate::transform::MirSource;
+use crate::util as mir_util;
use rustc::hir;
use rustc::hir::Node;
use rustc::hir::def_id::DefId;
use rustc::util::nodemap::NodeMap;
use rustc_target::spec::PanicStrategy;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use shim;
use std::mem;
use std::u32;
use rustc_target::spec::abi::Abi;
use syntax::attr::{self, UnwindAttr};
use syntax::symbol::keywords;
use syntax_pos::Span;
-use transform::MirSource;
-use util as mir_util;
use super::lints;
};
globalizer.visit_mir(&mut mir);
let mir = unsafe {
- mem::transmute::<Mir, Mir<'tcx>>(mir)
+ mem::transmute::<Mir<'_>, Mir<'tcx>>(mir)
};
mir_util::dump_mir(tcx, None, "mir_map", &0,
};
globalizer.visit_mir(&mut mir);
let mir = unsafe {
- mem::transmute::<Mir, Mir<'tcx>>(mir)
+ mem::transmute::<Mir<'_>, Mir<'tcx>>(mir)
};
mir_util::dump_mir(tcx, None, "mir_map", &0,
*/
-use build::{BlockAnd, BlockAndExtension, Builder, CFG};
-use hair::LintLevel;
+use crate::build::{BlockAnd, BlockAndExtension, Builder, CFG};
+use crate::hair::LintLevel;
use rustc::middle::region;
use rustc::ty::Ty;
use rustc::hir;
}
impl fmt::Display for ConstEvalError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use self::ConstEvalError::*;
match *self {
NeedsRfc(ref msg) => {
use rustc::mir::{BasicBlock, Location};
use rustc_data_structures::bit_set::{BitIter, BitSet, HybridBitSet};
-use dataflow::{BitDenotation, BlockSets, DataflowResults};
-use dataflow::move_paths::{HasMoveData, MovePathIndex};
+use crate::dataflow::{BitDenotation, BlockSets, DataflowResults};
+use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
use std::iter;
}
/// Returns an iterator over the elements present in the current state.
- pub fn iter_incoming(&self) -> iter::Peekable<BitIter<BD::Idx>> {
+ pub fn iter_incoming(&self) -> iter::Peekable<BitIter<'_, BD::Idx>> {
self.curr_state.iter().peekable()
}
/// Invokes `f` with an iterator over the resulting state.
pub fn with_iter_outgoing<F>(&self, f: F)
where
- F: FnOnce(BitIter<BD::Idx>),
+ F: FnOnce(BitIter<'_, BD::Idx>),
{
let mut curr_state = self.curr_state.clone();
curr_state.union(&self.stmt_gen);
use rustc::mir::{self, Mir, Location};
use rustc::ty::{self, TyCtxt};
-use util::elaborate_drops::DropFlagState;
+use crate::util::elaborate_drops::DropFlagState;
use super::{MoveDataParamEnv};
use super::indexes::MovePathIndex;
use syntax::ast::NodeId;
use rustc::mir::{BasicBlock, Mir};
-use dot;
-
use std::fs;
use std::io;
use std::marker::PhantomData;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Edge { source: BasicBlock, index: usize }
-fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec<Edge> {
+fn outgoing(mir: &Mir<'_>, bb: BasicBlock) -> Vec<Edge> {
(0..mir[bb].terminator().successors().count())
.map(|index| Edge { source: bb, index: index}).collect()
}
{
type Node = Node;
type Edge = Edge;
- fn graph_id(&self) -> dot::Id {
+ fn graph_id(&self) -> dot::Id<'_> {
dot::Id::new(format!("graph_for_node_{}",
self.mbcx.node_id()))
.unwrap()
}
- fn node_id(&self, n: &Node) -> dot::Id {
+ fn node_id(&self, n: &Node) -> dot::Id<'_> {
dot::Id::new(format!("bb_{}", n.index()))
.unwrap()
}
- fn node_label(&self, n: &Node) -> dot::LabelText {
+ fn node_label(&self, n: &Node) -> dot::LabelText<'_> {
// Node label is something like this:
// +---------+----------------------------------+------------------+------------------+
// | ENTRY | MIR | GEN | KILL |
}
- fn node_shape(&self, _n: &Node) -> Option<dot::LabelText> {
+ fn node_shape(&self, _n: &Node) -> Option<dot::LabelText<'_>> {
Some(dot::LabelText::label("none"))
}
n: &Node,
w: &mut W,
block: BasicBlock,
- mir: &Mir) -> io::Result<()> {
+ mir: &Mir<'_>) -> io::Result<()> {
// Header rows
const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"];
const HDR_FMT: &str = "bgcolor=\"grey\"";
n: &Node,
w: &mut W,
block: BasicBlock,
- mir: &Mir)
+ mir: &Mir<'_>)
-> io::Result<()> {
let i = n.index();
n: &Node,
w: &mut W,
block: BasicBlock,
- mir: &Mir)
+ mir: &Mir<'_>)
-> io::Result<()> {
let i = n.index();
{
type Node = Node;
type Edge = Edge;
- fn nodes(&self) -> dot::Nodes<Node> {
+ fn nodes(&self) -> dot::Nodes<'_, Node> {
self.mbcx.mir()
.basic_blocks()
.indices()
.into()
}
- fn edges(&self) -> dot::Edges<Edge> {
+ fn edges(&self) -> dot::Edges<'_, Edge> {
let mir = self.mbcx.mir();
mir.basic_blocks()
use rustc::mir::*;
use rustc::mir::visit::Visitor;
-use dataflow::BitDenotation;
+use crate::dataflow::BitDenotation;
/// This calculates if any part of a MIR local could have previously been borrowed.
/// This means that once a local has been borrowed, its bit will be set
}
fn statement_effect(&self,
- sets: &mut BlockSets<Local>,
+ sets: &mut BlockSets<'_, Local>,
loc: Location) {
let stmt = &self.mir[loc.block].statements[loc.statement_index];
}
fn terminator_effect(&self,
- sets: &mut BlockSets<Local>,
+ sets: &mut BlockSets<'_, Local>,
loc: Location) {
BorrowedLocalsVisitor {
sets,
-use borrow_check::borrow_set::{BorrowSet, BorrowData};
-use borrow_check::place_ext::PlaceExt;
+use crate::borrow_check::borrow_set::{BorrowSet, BorrowData};
+use crate::borrow_check::place_ext::PlaceExt;
use rustc::mir::{self, Location, Place, Mir};
use rustc::ty::TyCtxt;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use dataflow::{BitDenotation, BlockSets, InitialFlow};
-pub use dataflow::indexes::BorrowIndex;
-use borrow_check::nll::region_infer::RegionInferenceContext;
-use borrow_check::nll::ToRegionVid;
-use borrow_check::places_conflict;
+use crate::dataflow::{BitDenotation, BlockSets, InitialFlow};
+pub use crate::dataflow::indexes::BorrowIndex;
+use crate::borrow_check::nll::region_infer::RegionInferenceContext;
+use crate::borrow_check::nll::ToRegionVid;
+use crate::borrow_check::places_conflict;
use std::rc::Rc;
/// Add all borrows to the kill set, if those borrows are out of scope at `location`.
/// That means they went out of a nonlexical scope
fn kill_loans_out_of_scope_at_location(&self,
- sets: &mut BlockSets<BorrowIndex>,
+ sets: &mut BlockSets<'_, BorrowIndex>,
location: Location) {
// NOTE: The state associated with a given `location`
// reflects the dataflow on entry to the statement.
/// Kill any borrows that conflict with `place`.
fn kill_borrows_on_place(
&self,
- sets: &mut BlockSets<BorrowIndex>,
+ sets: &mut BlockSets<'_, BorrowIndex>,
place: &Place<'tcx>
) {
debug!("kill_borrows_on_place: place={:?}", place);
}
fn before_statement_effect(&self,
- sets: &mut BlockSets<BorrowIndex>,
+ sets: &mut BlockSets<'_, BorrowIndex>,
location: Location) {
debug!("Borrows::before_statement_effect sets: {:?} location: {:?}", sets, location);
self.kill_loans_out_of_scope_at_location(sets, location);
}
- fn statement_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location) {
+ fn statement_effect(&self, sets: &mut BlockSets<'_, BorrowIndex>, location: Location) {
debug!("Borrows::statement_effect: sets={:?} location={:?}", sets, location);
let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| {
}
fn before_terminator_effect(&self,
- sets: &mut BlockSets<BorrowIndex>,
+ sets: &mut BlockSets<'_, BorrowIndex>,
location: Location) {
debug!("Borrows::before_terminator_effect sets: {:?} location: {:?}", sets, location);
self.kill_loans_out_of_scope_at_location(sets, location);
}
- fn terminator_effect(&self, _: &mut BlockSets<BorrowIndex>, _: Location) {}
+ fn terminator_effect(&self, _: &mut BlockSets<'_, BorrowIndex>, _: Location) {}
fn propagate_call_return(
&self,
use super::MoveDataParamEnv;
-use util::elaborate_drops::DropFlagState;
+use crate::util::elaborate_drops::DropFlagState;
use super::move_paths::{HasMoveData, MoveData, MovePathIndex, InitIndex};
use super::move_paths::{LookupResult, InitKind};
impl<'a, 'gcx, 'tcx> MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
- fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
+ fn update_bits(sets: &mut BlockSets<'_, MovePathIndex>, path: MovePathIndex,
state: DropFlagState)
{
match state {
}
impl<'a, 'gcx, 'tcx> MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
- fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
+ fn update_bits(sets: &mut BlockSets<'_, MovePathIndex>, path: MovePathIndex,
state: DropFlagState)
{
match state {
}
impl<'a, 'gcx, 'tcx> DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
- fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
+ fn update_bits(sets: &mut BlockSets<'_, MovePathIndex>, path: MovePathIndex,
state: DropFlagState)
{
match state {
}
fn statement_effect(&self,
- sets: &mut BlockSets<MovePathIndex>,
+ sets: &mut BlockSets<'_, MovePathIndex>,
location: Location)
{
drop_flag_effects_for_location(
}
fn terminator_effect(&self,
- sets: &mut BlockSets<MovePathIndex>,
+ sets: &mut BlockSets<'_, MovePathIndex>,
location: Location)
{
drop_flag_effects_for_location(
}
fn statement_effect(&self,
- sets: &mut BlockSets<MovePathIndex>,
+ sets: &mut BlockSets<'_, MovePathIndex>,
location: Location)
{
drop_flag_effects_for_location(
}
fn terminator_effect(&self,
- sets: &mut BlockSets<MovePathIndex>,
+ sets: &mut BlockSets<'_, MovePathIndex>,
location: Location)
{
drop_flag_effects_for_location(
}
fn statement_effect(&self,
- sets: &mut BlockSets<MovePathIndex>,
+ sets: &mut BlockSets<'_, MovePathIndex>,
location: Location)
{
drop_flag_effects_for_location(
}
fn terminator_effect(&self,
- sets: &mut BlockSets<MovePathIndex>,
+ sets: &mut BlockSets<'_, MovePathIndex>,
location: Location)
{
drop_flag_effects_for_location(
}
fn statement_effect(&self,
- sets: &mut BlockSets<InitIndex>,
+ sets: &mut BlockSets<'_, InitIndex>,
location: Location) {
let (_, mir, move_data) = (self.tcx, self.mir, self.move_data());
let stmt = &mir[location.block].statements[location.statement_index];
}
fn terminator_effect(&self,
- sets: &mut BlockSets<InitIndex>,
+ sets: &mut BlockSets<'_, InitIndex>,
location: Location)
{
let (mir, move_data) = (self.mir, self.move_data());
pub use super::*;
use rustc::mir::*;
-use dataflow::BitDenotation;
+use crate::dataflow::BitDenotation;
#[derive(Copy, Clone)]
pub struct MaybeStorageLive<'a, 'tcx: 'a> {
}
fn statement_effect(&self,
- sets: &mut BlockSets<Local>,
+ sets: &mut BlockSets<'_, Local>,
loc: Location) {
let stmt = &self.mir[loc.block].statements[loc.statement_index];
}
fn terminator_effect(&self,
- _sets: &mut BlockSets<Local>,
+ _sets: &mut BlockSets<'_, Local>,
_loc: Location) {
// Terminators have no effect
}
}
impl fmt::Debug for DebugFormatted {
- fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(w, "{}", self.0)
}
}
impl<E:Idx> AllSets<E> {
pub fn bits_per_block(&self) -> usize { self.bits_per_block }
- pub fn for_block(&mut self, block_idx: usize) -> BlockSets<E> {
+ pub fn for_block(&mut self, block_idx: usize) -> BlockSets<'_, E> {
BlockSets {
on_entry: &mut self.on_entry_sets[block_idx],
gen_set: &mut self.gen_sets[block_idx],
/// applied, in that order, before moving for the next
/// statement.
fn before_statement_effect(&self,
- _sets: &mut BlockSets<Self::Idx>,
+ _sets: &mut BlockSets<'_, Self::Idx>,
_location: Location) {}
/// Mutates the block-sets (the flow sets for the given
/// `bb_data` is the sequence of statements identified by `bb` in
/// the MIR.
fn statement_effect(&self,
- sets: &mut BlockSets<Self::Idx>,
+ sets: &mut BlockSets<'_, Self::Idx>,
location: Location);
/// Similar to `terminator_effect`, except it applies
/// applied, in that order, before moving for the next
/// terminator.
fn before_terminator_effect(&self,
- _sets: &mut BlockSets<Self::Idx>,
+ _sets: &mut BlockSets<'_, Self::Idx>,
_location: Location) {}
/// Mutates the block-sets (the flow sets for the given
/// The effects applied here cannot depend on which branch the
/// terminator took.
fn terminator_effect(&self,
- sets: &mut BlockSets<Self::Idx>,
+ sets: &mut BlockSets<'_, Self::Idx>,
location: Location);
/// Mutates the block-sets according to the (flow-dependent)
}
impl fmt::Debug for $Index {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}{}", $debug_name, self.index())
}
}
pub use self::indexes::InitIndex;
impl MoveOutIndex {
- pub fn move_path_index(&self, move_data: &MoveData) -> MovePathIndex {
+ pub fn move_path_index(&self, move_data: &MoveData<'_>) -> MovePathIndex {
move_data.moves[*self].path
}
}
}
impl<'tcx> MovePath<'tcx> {
- pub fn parents(&self, move_paths: &IndexVec<MovePathIndex, MovePath>) -> Vec<MovePathIndex> {
+ pub fn parents(
+ &self,
+ move_paths: &IndexVec<MovePathIndex, MovePath<'_>>,
+ ) -> Vec<MovePathIndex> {
let mut parents = Vec::new();
let mut curr_parent = self.parent;
}
impl<'tcx> fmt::Debug for MovePath<'tcx> {
- fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(w, "MovePath {{")?;
if let Some(parent) = self.parent {
write!(w, " parent: {:?},", parent)?;
}
impl<'tcx> fmt::Display for MovePath<'tcx> {
- fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(w, "{:?}", self.place)
}
}
}
impl<T> LocationMap<T> where T: Default + Clone {
- fn new(mir: &Mir) -> Self {
+ fn new(mir: &Mir<'_>) -> Self {
LocationMap {
map: mir.basic_blocks().iter().map(|block| {
vec![T::default(); block.statements.len()+1]
}
impl fmt::Debug for MoveOut {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{:?}@{:?}", self.path, self.source)
}
}
}
impl fmt::Debug for Init {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{:?}@{:?} ({:?})", self.path, self.location, self.kind)
}
}
-use hair::*;
-use hair::cx::Cx;
-use hair::cx::to_ref::ToRef;
+use crate::hair::*;
+use crate::hair::cx::Cx;
+use crate::hair::cx::to_ref::ToRef;
use rustc::middle::region;
use rustc::hir;
use rustc::ty;
-use hair::*;
+use crate::hair::*;
+use crate::hair::cx::Cx;
+use crate::hair::cx::block;
+use crate::hair::cx::to_ref::ToRef;
+use crate::hair::util::UserAnnotatedTyHelpers;
use rustc_data_structures::indexed_vec::Idx;
-use hair::cx::Cx;
-use hair::cx::block;
-use hair::cx::to_ref::ToRef;
-use hair::util::UserAnnotatedTyHelpers;
use rustc::hir::def::{Def, CtorKind};
use rustc::mir::interpret::{GlobalId, ErrorHandled};
use rustc::ty::{self, AdtKind, Ty};
}
hir::ExprKind::Lit(ref lit) => ExprKind::Literal {
- literal: cx.tcx.intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
cx.const_eval_literal(&lit.node, expr_ty, lit.span, false)
)),
user_ty: None,
} else {
if let hir::ExprKind::Lit(ref lit) = arg.node {
ExprKind::Literal {
- literal: cx.tcx.intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
cx.const_eval_literal(&lit.node, expr_ty, lit.span, true)
)),
user_ty: None,
ty: var_ty,
span: expr.span,
kind: ExprKind::Literal {
- literal: cx.tcx.intern_lazy_const(literal),
+ literal: cx.tcx.mk_lazy_const(literal),
user_ty: None
},
}.to_ref();
ty,
span,
kind: ExprKind::Literal {
- literal: cx.tcx().intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: cx.tcx().mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::zero_sized(ty)
)),
user_ty,
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
debug!("convert_path_expr: user_ty={:?}", user_ty);
ExprKind::Literal {
- literal: cx.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized(
+ literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized(
cx.tables().node_id_to_type(expr.hir_id),
))),
user_ty,
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
ExprKind::Literal {
- literal: cx.tcx.intern_lazy_const(ty::LazyConst::Unevaluated(def_id, substs)),
+ literal: cx.tcx.mk_lazy_const(ty::LazyConst::Unevaluated(def_id, substs)),
user_ty,
}
},
//! work.
//!
-use hair::*;
-use hair::util::UserAnnotatedTyHelpers;
+use crate::hair::*;
+use crate::hair::util::UserAnnotatedTyHelpers;
use rustc_data_structures::indexed_vec::Idx;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use syntax::symbol::Symbol;
use rustc::hir;
use rustc_data_structures::sync::Lrc;
-use hair::constant::{lit_to_const, LitToConstError};
+use crate::hair::constant::{lit_to_const, LitToConstError};
#[derive(Clone)]
pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
}
pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::LazyConst<'tcx> {
- self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_usize(self.tcx, value)))
+ self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_usize(self.tcx, value)))
}
pub fn bool_ty(&mut self) -> Ty<'tcx> {
}
pub fn true_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> {
- self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, true)))
+ self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, true)))
}
pub fn false_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> {
- self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, false)))
+ self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, false)))
}
pub fn const_eval_literal(
}
}
-fn lint_level_for_hir_id(tcx: TyCtxt, mut id: ast::NodeId) -> ast::NodeId {
+fn lint_level_for_hir_id(tcx: TyCtxt<'_, '_, '_>, mut id: ast::NodeId) -> ast::NodeId {
// Right now we insert a `with_ignore` node in the dep graph here to
// ignore the fact that `lint_levels` below depends on the entire crate.
// For now this'll prevent false positives of recompiling too much when
-use hair::*;
+use crate::hair::*;
use rustc::hir;
use syntax::ptr::P;
/// + _ + [_, _, ..tail] +
/// ++++++++++++++++++++++++++
impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\n")?;
let &Matrix(ref m) = self;
VariantIdx::new(0)
}
&ConstantValue(c) => {
- ::const_eval::const_variant_index(
+ crate::const_eval::const_variant_index(
cx.tcx,
cx.param_env,
c,
} else {
debug!("is_useful - expanding wildcard");
- let used_ctors: Vec<Constructor> = rows.iter().flat_map(|row| {
+ let used_ctors: Vec<Constructor<'_>> = rows.iter().flat_map(|row| {
pat_constructors(cx, row[0], pcx).unwrap_or(vec![])
}).collect();
debug!("used_ctors = {:#?}", used_ctors);
/// Returns None in case of a catch-all, which can't be specialized.
fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
pat: &Pattern<'tcx>,
- pcx: PatternContext)
+ pcx: PatternContext<'_>)
-> Option<Vec<Constructor<'tcx>>>
{
match *pat.kind {
return;
}
- let matrix: Matrix = inlined_arms
+ let matrix: Matrix<'_, '_> = inlined_arms
.iter()
.filter(|&&(_, guard)| guard.is_none())
.flat_map(|arm| &arm.0)
self.tables);
let pattern = patcx.lower_pattern(pat);
let pattern_ty = pattern.ty;
- let pats: Matrix = vec![smallvec![
+ let pats: Matrix<'_, '_> = vec![smallvec![
expand_pattern(cx, pattern)
]].into_iter().collect();
}
}
-fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor, pat: &Pat) {
+fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
pat.walk(|p| {
if let PatKind::Binding(_, _, _, ident, None) = p.node {
if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
}
// Legality of move bindings checking
-fn check_legality_of_move_bindings(cx: &MatchVisitor,
+fn check_legality_of_move_bindings(cx: &MatchVisitor<'_, '_>,
has_guard: bool,
pats: &[P<Pat>]) {
let mut by_ref_span = None;
/// assign.
///
/// FIXME: this should be done by borrowck.
-fn check_for_mutation_in_guard(cx: &MatchVisitor, guard: &hir::Guard) {
+fn check_for_mutation_in_guard(cx: &MatchVisitor<'_, '_>, guard: &hir::Guard) {
let mut checker = MutationChecker {
cx,
};
}
impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
- fn matched_pat(&mut self, _: &Pat, _: &cmt_, _: euv::MatchMode) {}
- fn consume(&mut self, _: ast::NodeId, _: Span, _: &cmt_, _: ConsumeMode) {}
- fn consume_pat(&mut self, _: &Pat, _: &cmt_, _: ConsumeMode) {}
+ fn matched_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: euv::MatchMode) {}
+ fn consume(&mut self, _: ast::NodeId, _: Span, _: &cmt_<'_>, _: ConsumeMode) {}
+ fn consume_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: ConsumeMode) {}
fn borrow(&mut self,
_: ast::NodeId,
span: Span,
- _: &cmt_,
+ _: &cmt_<'_>,
_: ty::Region<'tcx>,
kind:ty:: BorrowKind,
_: LoanCause) {
}
}
fn decl_without_init(&mut self, _: ast::NodeId, _: Span) {}
- fn mutate(&mut self, _: ast::NodeId, span: Span, _: &cmt_, mode: MutateMode) {
+ fn mutate(&mut self, _: ast::NodeId, span: Span, _: &cmt_<'_>, mode: MutateMode) {
match mode {
MutateMode::JustWrite | MutateMode::WriteAndRead => {
struct_span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard")
/// Forbids bindings in `@` patterns. This is necessary for memory safety,
/// because of the way rvalues are handled in the borrow check. (See issue
/// #14587.)
-fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor, pat: &Pat) {
+fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
AtBindingPatternVisitor { cx: cx, bindings_allowed: true }.visit_pat(pat);
}
pub use self::check_match::check_crate;
pub(crate) use self::check_match::check_match;
-use const_eval::{const_field, const_variant_index};
+use crate::const_eval::{const_field, const_variant_index};
-use hair::util::UserAnnotatedTyHelpers;
-use hair::constant::*;
+use crate::hair::util::UserAnnotatedTyHelpers;
+use crate::hair::constant::*;
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
},
}
+impl<'tcx> PatternKind<'tcx> {
+ /// If this is a `PatternKind::AscribeUserType` then return the subpattern kind, otherwise
+ /// return this pattern kind.
+ fn with_user_type_ascription_subpattern(self) -> Self {
+ match self {
+ PatternKind::AscribeUserType { subpattern: Pattern { box kind, .. }, .. } => kind,
+ kind => kind,
+ }
+ }
+}
+
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PatternRange<'tcx> {
pub lo: ty::Const<'tcx>,
}
impl<'tcx> fmt::Display for Pattern<'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self.kind {
PatternKind::Wild => write!(f, "_"),
PatternKind::AscribeUserType { ref subpattern, .. } =>
PatKind::Lit(ref value) => self.lower_lit(value),
PatKind::Range(ref lo_expr, ref hi_expr, end) => {
- match (self.lower_lit(lo_expr), self.lower_lit(hi_expr)) {
- (PatternKind::Constant { value: lo },
- PatternKind::Constant { value: hi }) => {
+ match (
+ // Look for `PatternKind::Constant` patterns inside of any
+ // `PatternKind::AscribeUserType` patterns. Type ascriptions can be safely
+ // ignored for the purposes of lowering a range correctly - these are checked
+ // elsewhere for well-formedness.
+ self.lower_lit(lo_expr).with_user_type_ascription_subpattern(),
+ self.lower_lit(hi_expr).with_user_type_ascription_subpattern(),
+ ) {
+ (PatternKind::Constant { value: lo }, PatternKind::Constant { value: hi }) => {
use std::cmp::Ordering;
let cmp = compare_const_vals(
self.tcx,
}
}
}
- _ => PatternKind::Wild
+ ref pats => {
+ self.tcx.sess.delay_span_bug(
+ pat.span,
+ &format!("found bad range pattern `{:?}` outside of error recovery",
+ pats),
+ );
+
+ PatternKind::Wild
+ }
}
}
) -> EvalResult<'tcx, TyLayout<'tcx>> {
match frame.locals[local].layout.get() {
None => {
- let layout = ::interpret::operand::from_known_layout(layout, || {
+ let layout = crate::interpret::operand::from_known_layout(layout, || {
let local_ty = frame.mir.local_decls[local].ty;
let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs);
self.layout_of(local_ty)
use super::eval_context::{LocalState, StackPopCleanup};
use super::{Frame, Memory, Operand, MemPlace, Place, Immediate, ScalarMaybeUndef, LocalValue};
-use const_eval::CompileTimeInterpreter;
+use crate::const_eval::CompileTimeInterpreter;
#[derive(Default)]
pub(crate) struct InfiniteLoopDetector<'a, 'mir, 'tcx: 'a + 'mir> {
Undef,
});
-impl_stable_hash_for!(struct ::interpret::MemPlace {
+impl_stable_hash_for!(struct crate::interpret::MemPlace {
ptr,
align,
meta,
align -> *align, // just copy alignment verbatim
});
-impl_stable_hash_for!(enum ::interpret::Place {
+impl_stable_hash_for!(enum crate::interpret::Place {
Ptr(mem_place),
Local { frame, local },
});
}
}
-impl_stable_hash_for!(enum ::interpret::Immediate {
+impl_stable_hash_for!(enum crate::interpret::Immediate {
Scalar(x),
ScalarPair(x, y),
});
ScalarPair(s, t),
});
-impl_stable_hash_for!(enum ::interpret::Operand {
+impl_stable_hash_for!(enum crate::interpret::Operand {
Immediate(x),
Indirect(x),
});
Indirect(m),
});
-impl_stable_hash_for!(enum ::interpret::LocalValue {
+impl_stable_hash_for!(enum crate::interpret::LocalValue {
Dead,
Live(x),
});
}
}
-impl_stable_hash_for!(enum ::interpret::eval_context::StackPopCleanup {
+impl_stable_hash_for!(enum crate::interpret::eval_context::StackPopCleanup {
Goto(block),
None { cleanup },
});
let ty = place.layout.ty;
trace!("TerminatorKind::drop: {:?}, type {}", location, ty);
- let instance = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
+ let instance = crate::monomorphize::resolve_drop_in_place(*self.tcx, ty);
self.drop_in_place(
place,
instance,
// last incoming argument. These two iterators do not have the same type,
// so to keep the code paths uniform we accept an allocation
// (for RustCall ABI only).
- let caller_args : Cow<[OpTy<'tcx, M::PointerTag>]> =
+ let caller_args : Cow<'_, [OpTy<'tcx, M::PointerTag>]> =
if caller_abi == Abi::RustCall && !args.is_empty() {
// Untuple
let (&untuple_arg, args) = args.split_last().unwrap();
.chain((0..untuple_arg.layout.fields.count()).into_iter()
.map(|i| self.operand_field(untuple_arg, i as u64))
)
- .collect::<EvalResult<Vec<OpTy<'tcx, M::PointerTag>>>>()?)
+ .collect::<EvalResult<'_, Vec<OpTy<'tcx, M::PointerTag>>>>()?)
} else {
// Plain arg passing
Cow::from(args)
).with_default_tag();
let tcx = &*self.tcx;
- let drop = ::monomorphize::resolve_drop_in_place(*tcx, ty);
+ let drop = crate::monomorphize::resolve_drop_in_place(*tcx, ty);
let drop = self.memory.create_fn_alloc(drop).with_default_tag();
// no need to do any alignment checks on the memory accesses below, because we know the
// allocation is correctly aligned as we created it above. Also we're only offsetting by
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>>;
/// Create this from an `MPlaceTy`.
- fn from_mem_place(MPlaceTy<'tcx, M::PointerTag>) -> Self;
+ fn from_mem_place(mplace: MPlaceTy<'tcx, M::PointerTag>) -> Self;
/// Project to the given enum variant.
fn project_downcast(
#![feature(slice_concat_ext)]
#![feature(try_from)]
#![feature(reverse_bits)]
+#![feature(try_blocks)]
#![recursion_limit="256"]
-extern crate arena;
+#![deny(rust_2018_idioms)]
+#![allow(explicit_outlives_requirements)]
-#[macro_use]
-extern crate bitflags;
#[macro_use] extern crate log;
-extern crate either;
-extern crate graphviz as dot;
-extern crate polonius_engine;
#[macro_use]
extern crate rustc;
#[macro_use] extern crate rustc_data_structures;
-extern crate serialize as rustc_serialize;
-extern crate rustc_errors;
+#[allow(unused_extern_crates)]
+extern crate serialize as rustc_serialize; // used by deriving
#[macro_use]
extern crate syntax;
-extern crate syntax_pos;
-extern crate rustc_target;
-extern crate log_settings;
-extern crate rustc_apfloat;
-extern crate byteorder;
-extern crate core;
-extern crate smallvec;
-
-// Once we can use edition 2018 in the compiler,
-// replace this with real try blocks.
-macro_rules! try_block {
- ($($inside:tt)*) => (
- (||{ ::std::ops::Try::from_ok({ $($inside)* }) })()
- )
-}
mod diagnostics;
pub use hair::pattern::check_crate as matchck_crate;
use rustc::ty::query::Providers;
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
borrow_check::provide(providers);
shim::provide(providers);
transform::provide(providers);
}
fn check_fn_for_unconditional_recursion(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- fn_kind: FnKind,
+ fn_kind: FnKind<'_>,
mir: &Mir<'tcx>,
def_id: DefId) {
if let FnKind::Closure(_) = fn_kind {
use rustc::mir::mono::MonoItem;
use rustc::mir::interpret::{Scalar, GlobalId, AllocKind, ErrorHandled};
-use monomorphize::{self, Instance};
+use crate::monomorphize::{self, Instance};
use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
use rustc::util::common::time;
-use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode};
+use crate::monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode};
use rustc_data_structures::bit_set::GrowableBitSet;
use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter};
-use monomorphize::Instance;
+use crate::monomorphize::Instance;
use rustc::hir;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::session::config::OptLevel;
use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet};
use rustc::mir::mono::MonoItem;
-use monomorphize::collector::InliningMap;
-use monomorphize::collector::{self, MonoItemCollectionMode};
-use monomorphize::item::{MonoItemExt, InstantiationMode};
+use crate::monomorphize::collector::InliningMap;
+use crate::monomorphize::collector::{self, MonoItemCollectionMode};
+use crate::monomorphize::item::{MonoItemExt, InstantiationMode};
pub use rustc::mir::mono::CodegenUnit;
WorkProductId::from_cgu_name(&self.name().as_str())
}
- fn work_product(&self, tcx: TyCtxt) -> WorkProduct {
+ fn work_product(&self, tcx: TyCtxt<'_, '_, '_>) -> WorkProduct {
let work_product_id = self.work_product_id();
tcx.dep_graph
.previous_work_product(&work_product_id)
}
// Anything we can't find a proper codegen unit for goes into this.
-fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder) -> InternedString {
+fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>) -> InternedString {
name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu"))
}
}
}
-fn default_visibility(tcx: TyCtxt, id: DefId, is_generic: bool) -> Visibility {
+fn default_visibility(tcx: TyCtxt<'_, '_, '_>, id: DefId, is_generic: bool) -> Visibility {
if !tcx.sess.target.target.options.default_hidden_visibility {
return Visibility::Default
}
type CguNameCache = FxHashMap<(DefId, bool), InternedString>;
-fn compute_codegen_unit_name(tcx: TyCtxt,
- name_builder: &mut CodegenUnitNameBuilder,
+fn compute_codegen_unit_name(tcx: TyCtxt<'_, '_, '_>,
+ name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>,
def_id: DefId,
volatile: bool,
cache: &mut CguNameCache)
}).clone()
}
-fn numbered_codegen_unit_name(name_builder: &mut CodegenUnitNameBuilder,
+fn numbered_codegen_unit_name(name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>,
index: usize)
-> InternedString {
name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index))
tcx.sess.abort_if_errors();
- ::monomorphize::assert_symbols_are_distinct(tcx, items.iter());
+ crate::monomorphize::assert_symbols_are_distinct(tcx, items.iter());
let strategy = if tcx.sess.opts.incremental.is_some() {
PartitioningStrategy::PerModule
(Arc::new(mono_items), Arc::new(codegen_units))
}
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
providers.collect_and_partition_mono_items =
collect_and_partition_mono_items;
use std::fmt;
use std::iter;
-use transform::{add_moves_for_packed_drops, add_call_guards};
-use transform::{remove_noop_landing_pads, no_landing_pads, simplify};
-use util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
-use util::patch::MirPatch;
+use crate::transform::{add_moves_for_packed_drops, add_call_guards};
+use crate::transform::{remove_noop_landing_pads, no_landing_pads, simplify};
+use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
+use crate::util::patch::MirPatch;
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
providers.mir_shims = make_shim;
}
Direct(DefId),
}
-fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl {
+fn temp_decl(mutability: Mutability, ty: Ty<'_>, span: Span) -> LocalDecl<'_> {
let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span };
LocalDecl {
mutability,
}
impl<'a, 'tcx> fmt::Debug for DropShimElaborator<'a, 'tcx> {
- fn fmt(&self, _f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
Ok(())
}
}
span: self.span,
ty: func_ty,
user_ty: None,
- literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::zero_sized(func_ty),
)),
});
span: self.span,
ty: self.tcx.types.usize,
user_ty: None,
- literal: self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::from_usize(self.tcx, value),
)),
}
span,
ty,
user_ty: None,
- literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::zero_sized(ty)
)),
}),
use rustc::ty::TyCtxt;
use rustc::mir::*;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
#[derive(PartialEq)]
pub enum AddCallGuards {
}
impl AddCallGuards {
- pub fn add_call_guards(&self, mir: &mut Mir) {
+ pub fn add_call_guards(&self, mir: &mut Mir<'_>) {
let pred_count: IndexVec<_, _> =
mir.predecessors().iter().map(|ps| ps.len()).collect();
use rustc::mir::*;
use rustc::ty::TyCtxt;
-use transform::{MirPass, MirSource};
-use util::patch::MirPatch;
-use util;
+use crate::transform::{MirPass, MirSource};
+use crate::util::patch::MirPatch;
+use crate::util;
// This pass moves values being dropped that are within a packed
// struct to a separate local before dropping them, to ensure that
use rustc::ty::{self, Ty, TyCtxt};
use rustc::mir::*;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
pub struct AddRetag;
use std::ops::Bound;
-use util;
+use crate::util;
pub struct UnsafetyChecker<'a, 'tcx: 'a> {
mir: &'a Mir<'tcx>,
}
}
-pub(crate) fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
unsafety_check_result,
unsafe_derive_on_repr_packed,
}
/// Return the NodeId for an enclosing scope that is also `unsafe`
-fn is_enclosed(tcx: TyCtxt,
+fn is_enclosed(tcx: TyCtxt<'_, '_, '_>,
used_unsafe: &FxHashSet<ast::NodeId>,
id: ast::NodeId) -> Option<(String, ast::NodeId)> {
let parent_id = tcx.hir().get_parent_node(id);
}
}
-fn report_unused_unsafe(tcx: TyCtxt, used_unsafe: &FxHashSet<ast::NodeId>, id: ast::NodeId) {
+fn report_unused_unsafe(tcx: TyCtxt<'_, '_, '_>,
+ used_unsafe: &FxHashSet<ast::NodeId>,
+ id: ast::NodeId) {
let span = tcx.sess.source_map().def_span(tcx.hir().span(id));
let msg = "unnecessary `unsafe` block";
let mut db = tcx.struct_span_lint_node(UNUSED_UNSAFE, id, span, msg);
use rustc::mir::{Statement, StatementKind};
use rustc::mir::visit::MutVisitor;
use rustc::ty::TyCtxt;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
pub struct CleanAscribeUserType;
HasTyCtxt, TargetDataLayout, HasDataLayout,
};
-use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind};
-use const_eval::{
+use crate::interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind};
+use crate::const_eval::{
CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
lazy_const_to_op,
};
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
pub struct ConstProp;
impl CanConstProp {
/// returns true if `local` can be propagated
- fn check(mir: &Mir) -> IndexVec<Local, bool> {
+ fn check(mir: &Mir<'_>) -> IndexVec<Local, bool> {
let mut cpv = CanConstProp {
can_const_prop: IndexVec::from_elem(true, &mir.local_decls),
found_assignment: IndexVec::from_elem(false, &mir.local_decls),
use rustc::mir::{Constant, Local, LocalKind, Location, Place, Mir, Operand, Rvalue, StatementKind};
use rustc::mir::visit::MutVisitor;
use rustc::ty::TyCtxt;
-use transform::{MirPass, MirSource};
-use util::def_use::DefUseAnalysis;
+use crate::transform::{MirPass, MirSource};
+use crate::util::def_use::DefUseAnalysis;
pub struct CopyPropagation;
}
impl<'tcx> Action<'tcx> {
- fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis, src_place: &Place<'tcx>)
+ fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis<'_>, src_place: &Place<'tcx>)
-> Option<Action<'tcx>> {
// The source must be a local.
let src_local = if let Place::Local(local) = *src_place {
use rustc::ty::TyCtxt;
use rustc::mir::*;
use rustc_data_structures::indexed_vec::Idx;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
pub struct Deaggregator;
use rustc::mir::Mir;
use rustc::session::config::{OutputFilenames, OutputType};
use rustc::ty::TyCtxt;
-use transform::{MirPass, MirSource};
-use util as mir_util;
+use crate::transform::{MirPass, MirSource};
+use crate::util as mir_util;
pub struct Marker(pub &'static str);
}
impl fmt::Display for Disambiguator {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let title = if self.is_after { "after" } else { "before" };
write!(formatter, "{}", title)
}
-use dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex, LookupResult};
-use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
-use dataflow::{DataflowResults};
-use dataflow::{on_all_children_bits, on_all_drop_children_bits};
-use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
-use dataflow::MoveDataParamEnv;
-use dataflow::{self, do_dataflow, DebugFormatted};
+use crate::dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex, LookupResult};
+use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
+use crate::dataflow::{DataflowResults};
+use crate::dataflow::{on_all_children_bits, on_all_drop_children_bits};
+use crate::dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
+use crate::dataflow::MoveDataParamEnv;
+use crate::dataflow::{self, do_dataflow, DebugFormatted};
+use crate::transform::{MirPass, MirSource};
+use crate::util::patch::MirPatch;
+use crate::util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop};
+use crate::util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode};
use rustc::ty::{self, TyCtxt};
use rustc::ty::layout::VariantIdx;
use rustc::mir::*;
use std::fmt;
use syntax::ast;
use syntax_pos::Span;
-use transform::{MirPass, MirSource};
-use util::patch::MirPatch;
-use util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop};
-use util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode};
pub struct ElaborateDrops;
}
impl<'a, 'b, 'tcx> fmt::Debug for Elaborator<'a, 'b, 'tcx> {
- fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}
span,
ty: self.tcx.types.bool,
user_ty: None,
- literal: self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::from_bool(self.tcx, val),
)),
})))
use rustc::ty::{self, Ty, TyCtxt};
use rustc::mir::*;
use rustc::mir::visit::{MutVisitor, TyContext};
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
struct EraseRegionsVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
use rustc::ty::{self, TyCtxt, AdtDef, Ty};
use rustc::ty::layout::VariantIdx;
use rustc::ty::subst::Substs;
-use util::dump_mir;
-use util::liveness::{self, IdentityMap};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::bit_set::BitSet;
use std::borrow::Cow;
use std::iter::once;
use std::mem;
-use transform::{MirPass, MirSource};
-use transform::simplify;
-use transform::no_landing_pads::no_landing_pads;
-use dataflow::{do_dataflow, DebugFormatted, state_for_location};
-use dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals};
+use crate::transform::{MirPass, MirSource};
+use crate::transform::simplify;
+use crate::transform::no_landing_pads::no_landing_pads;
+use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location};
+use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals};
+use crate::util::dump_mir;
+use crate::util::liveness::{self, IdentityMap};
pub struct StateTransform;
span: source_info.span,
ty: self.tcx.types.u32,
user_ty: None,
- literal: self.tcx.intern_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits(
+ literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits(
self.tcx,
state_disc.into(),
ty::ParamEnv::empty().and(self.tcx.types.u32)
fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
mir: &mut Mir<'tcx>) {
- use util::elaborate_drops::{elaborate_drop, Unwind};
- use util::patch::MirPatch;
- use shim::DropShimElaborator;
+ use crate::util::elaborate_drops::{elaborate_drop, Unwind};
+ use crate::util::patch::MirPatch;
+ use crate::shim::DropShimElaborator;
// Note that `elaborate_drops` only drops the upvars of a generator, and
// this is ok because `open_drop` can only be reached within that own
span: mir.span,
ty: tcx.types.bool,
user_ty: None,
- literal: tcx.intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::from_bool(tcx, false),
)),
}),
use std::collections::VecDeque;
use std::iter;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
use super::simplify::{remove_dead_blocks, CfgSimplifier};
-use syntax::{attr};
+use syntax::attr;
use rustc_target::spec::abi::Abi;
const DEFAULT_THRESHOLD: usize = 50;
// Place could result in two different locations if `f`
// writes to `i`. To prevent this we need to create a temporary
// borrow of the place and pass the destination as `*temp` instead.
- fn dest_needs_borrow(place: &Place) -> bool {
+ fn dest_needs_borrow(place: &Place<'_>) -> bool {
match *place {
Place::Projection(ref p) => {
match p.elem {
use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_vec::Idx;
use std::mem;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
pub struct InstCombine;
use rustc::mir::*;
use rustc::ty::{List, Ty, TyCtxt, TyKind};
use rustc_data_structures::indexed_vec::{Idx};
-use transform::{MirPass, MirSource};
-use syntax;
+use crate::transform::{MirPass, MirSource};
pub struct Lower128Bit;
}
}
-fn sign_of_128bit(ty: Ty) -> Option<bool> {
+fn sign_of_128bit(ty: Ty<'_>) -> Option<bool> {
match ty.sty {
TyKind::Int(syntax::ast::IntTy::I128) => Some(true),
TyKind::Uint(syntax::ast::UintTy::U128) => Some(false),
-use borrow_check::nll::type_check;
-use build;
+use crate::borrow_check::nll::type_check;
+use crate::build;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::mir::{Mir, MirPhase, Promoted};
use rustc::ty::TyCtxt;
pub mod lower_128bit;
pub mod uniform_array_move_out;
-pub(crate) fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers<'_>) {
self::qualify_consts::provide(providers);
self::check_unsafety::provide(providers);
*providers = Providers {
use rustc::ty::TyCtxt;
use rustc::mir::*;
use rustc::mir::visit::MutVisitor;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
pub struct NoLandingPads;
}
}
-pub fn collect_temps(mir: &Mir, rpo: &mut ReversePostorder) -> IndexVec<Local, TempState> {
+pub fn collect_temps(mir: &Mir<'_>,
+ rpo: &mut ReversePostorder<'_, '_>) -> IndexVec<Local, TempState> {
let mut collector = TempCollector {
temps: IndexVec::from_elem(TempState::Undefined, &mir.local_decls),
span: mir.span,
use std::fmt;
use std::usize;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
use super::promote_consts::{self, Candidate, TempState};
-bitflags! {
+bitflags::bitflags! {
// Borrows of temporaries can be promoted only if
// they have none of these qualifications, with
// the exception of `STATIC_REF` (in statics only).
}
impl fmt::Display for Mode {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Mode::Const => write!(f, "constant"),
Mode::Static | Mode::StaticMut => write!(f, "static"),
}
}
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
mir_const_qualif,
..*providers
}
}
-fn args_required_const(tcx: TyCtxt, def_id: DefId) -> Option<FxHashSet<usize>> {
+fn args_required_const(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option<FxHashSet<usize>> {
let attrs = tcx.get_attrs(def_id);
let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?;
let mut ret = FxHashSet::default();
use rustc::ty::TyCtxt;
use rustc::mir::*;
use rustc_data_structures::bit_set::BitSet;
-use transform::{MirPass, MirSource};
-use util::patch::MirPatch;
+use crate::transform::{MirPass, MirSource};
+use crate::util::patch::MirPatch;
/// A pass that removes no-op landing pads and replaces jumps to them with
/// `None`. This is important because otherwise LLVM generates terrible
fn is_nop_landing_pad(
&self,
bb: BasicBlock,
- mir: &Mir,
+ mir: &Mir<'_>,
nop_landing_pads: &BitSet<BasicBlock>,
) -> bool {
for stmt in &mir[bb].statements {
}
}
- fn remove_nop_landing_pads(&self, mir: &mut Mir) {
+ fn remove_nop_landing_pads(&self, mir: &mut Mir<'_>) {
// make sure there's a single resume block
let resume_block = {
let patch = MirPatch::new(mir);
use rustc::ty::{self, TyCtxt};
use rustc::mir::{self, Mir, Location};
use rustc_data_structures::bit_set::BitSet;
-use transform::{MirPass, MirSource};
-
-use dataflow::{do_dataflow, DebugFormatted};
-use dataflow::MoveDataParamEnv;
-use dataflow::BitDenotation;
-use dataflow::DataflowResults;
-use dataflow::{DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces};
-use dataflow::move_paths::{MovePathIndex, LookupResult};
-use dataflow::move_paths::{HasMoveData, MoveData};
-use dataflow;
-
-use dataflow::has_rustc_mir_with;
+use crate::transform::{MirPass, MirSource};
+
+use crate::dataflow::{do_dataflow, DebugFormatted};
+use crate::dataflow::MoveDataParamEnv;
+use crate::dataflow::BitDenotation;
+use crate::dataflow::DataflowResults;
+use crate::dataflow::{
+ DefinitelyInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces
+};
+use crate::dataflow::move_paths::{MovePathIndex, LookupResult};
+use crate::dataflow::move_paths::{HasMoveData, MoveData};
+use crate::dataflow;
+
+use crate::dataflow::has_rustc_mir_with;
pub struct SanityCheck;
use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext};
use rustc::session::config::DebugInfo;
use std::borrow::Cow;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
pub struct SimplifyCfg { label: String }
}
}
-pub fn simplify_cfg(mir: &mut Mir) {
+pub fn simplify_cfg(mir: &mut Mir<'_>) {
CfgSimplifier::new(mir).simplify();
remove_dead_blocks(mir);
}
}
-pub fn remove_dead_blocks(mir: &mut Mir) {
+pub fn remove_dead_blocks(mir: &mut Mir<'_>) {
let mut seen = BitSet::new_empty(mir.basic_blocks().len());
for (bb, _) in traversal::preorder(mir) {
seen.insert(bb.index());
use rustc::ty::{TyCtxt, ParamEnv};
use rustc::mir::*;
-use transform::{MirPass, MirSource};
+use crate::transform::{MirPass, MirSource};
use std::borrow::Cow;
use rustc::ty::TyCtxt;
use rustc::mir::*;
use rustc::mir::visit::{Visitor, PlaceContext, NonUseContext};
-use transform::{MirPass, MirSource};
-use util::patch::MirPatch;
use rustc_data_structures::indexed_vec::{IndexVec};
+use crate::transform::{MirPass, MirSource};
+use crate::util::patch::MirPatch;
pub struct UniformArrayMoveOut;
}
impl fmt::Display for Origin {
- fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
// If the user passed `-Z borrowck=compare`, then include
// origin info as part of the error report,
// otherwise
fn cannot_move_out_of_interior_noncopy(
self,
move_from_span: Span,
- ty: ty::Ty,
+ ty: ty::Ty<'_>,
is_index: Option<bool>,
o: Origin,
) -> DiagnosticBuilder<'cx> {
fn cannot_move_out_of_interior_of_drop(
self,
move_from_span: Span,
- container_ty: ty::Ty,
+ container_ty: ty::Ty<'_>,
o: Origin,
) -> DiagnosticBuilder<'cx> {
let mut err = struct_span_err!(
pub fn defs_not_including_drop(
&self,
- ) -> iter::Filter<slice::Iter<Use<'tcx>>, fn(&&Use<'tcx>) -> bool> {
+ ) -> iter::Filter<slice::Iter<'_, Use<'tcx>>, fn(&&Use<'tcx>) -> bool> {
self.defs_and_uses.iter().filter(|place_use| {
place_use.context.is_mutating_use() && !place_use.context.is_drop()
})
use rustc::ty::subst::Substs;
use rustc::ty::util::IntTypeExt;
use rustc_data_structures::indexed_vec::Idx;
-use util::patch::MirPatch;
+use crate::util::patch::MirPatch;
use std::u32;
span: self.source_info.span,
ty: self.tcx().types.usize,
user_ty: None,
- literal: self.tcx().intern_lazy_const(ty::LazyConst::Evaluated(
+ literal: self.tcx().mk_lazy_const(ty::LazyConst::Evaluated(
ty::Const::from_usize(self.tcx(), val.into())
)),
})
-use dot;
use rustc::hir::def_id::DefId;
use rustc::mir::*;
use rustc::ty::TyCtxt;
/// Write a graphviz DOT graph of the MIR.
pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
def_id: DefId,
- mir: &Mir,
+ mir: &Mir<'_>,
w: &mut W) -> io::Result<()>
where W: Write
{
/// `init` and `fini` are callbacks for emitting additional rows of
/// data (using HTML enclosed with `<tr>` in the emitted text).
pub fn write_node_label<W: Write, INIT, FINI>(block: BasicBlock,
- mir: &Mir,
+ mir: &Mir<'_>,
w: &mut W,
num_cols: u32,
init: INIT,
}
/// Write a graphviz DOT node for the given basic block.
-fn write_node<W: Write>(block: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<()> {
+fn write_node<W: Write>(block: BasicBlock, mir: &Mir<'_>, w: &mut W) -> io::Result<()> {
// Start a new node with the label to follow, in one of DOT's pseudo-HTML tables.
write!(w, r#" {} [shape="none", label=<"#, node(block))?;
write_node_label(block, mir, w, 1, |_| Ok(()), |_| Ok(()))?;
}
/// Write graphviz DOT edges with labels between the given basic block and all of its successors.
-fn write_edges<W: Write>(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<()> {
+fn write_edges<W: Write>(source: BasicBlock, mir: &Mir<'_>, w: &mut W) -> io::Result<()> {
let terminator = mir[source].terminator();
let labels = terminator.kind.fmt_successor_labels();
/// all the variables and temporaries.
fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
def_id: DefId,
- mir: &Mir,
+ mir: &Mir<'_>,
w: &mut W)
-> io::Result<()> {
write!(w, " label=<fn {}(", dot::escape_html(&tcx.item_path_str(def_id)))?;
use std::fs;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
-use transform::MirSource;
-use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
+use crate::transform::MirSource;
+use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
pub type LiveVarSet<V> = BitSet<V>;
}
}
- pub fn source_info_for_index(data: &BasicBlockData, loc: Location) -> SourceInfo {
+ pub fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo {
match data.statements.get(loc.statement_index) {
Some(stmt) => stmt.source_info,
None => data.terminator().source_info
}
}
- pub fn source_info_for_location(&self, mir: &Mir, loc: Location) -> SourceInfo {
+ pub fn source_info_for_location(&self, mir: &Mir<'_>, loc: Location) -> SourceInfo {
let data = match loc.block.index().checked_sub(mir.basic_blocks().len()) {
Some(new) => &self.new_blocks[new],
None => &mir[loc.block]
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use super::graphviz::write_mir_fn_graphviz;
-use transform::MirSource;
+use crate::transform::MirSource;
const INDENT: &str = " ";
/// Alignment for lining up comments following MIR statements
) where
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
{
- let _: io::Result<()> = try_block! {
+ let _: io::Result<()> = try {
let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?;
writeln!(file, "// MIR for `{}`", node_path)?;
writeln!(file, "// source = {:?}", source)?;
};
if tcx.sess.opts.debugging_opts.dump_mir_graphviz {
- let _: io::Result<()> = try_block! {
+ let _: io::Result<()> = try {
let mut file =
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
}
}
-fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String {
+fn comment(tcx: TyCtxt<'_, '_, '_>, SourceInfo { span, scope }: SourceInfo) -> String {
format!(
"scope {} at {}",
scope.index(),
///
/// Returns the total number of variables printed.
fn write_scope_tree(
- tcx: TyCtxt,
- mir: &Mir,
+ tcx: TyCtxt<'_, '_, '_>,
+ mir: &Mir<'_>,
scope_tree: &FxHashMap<SourceScope, Vec<SourceScope>>,
w: &mut dyn Write,
parent: SourceScope,
pub fn write_mir_intro<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
src: MirSource,
- mir: &Mir,
+ mir: &Mir<'_>,
w: &mut dyn Write,
) -> io::Result<()> {
write_mir_sig(tcx, src, mir, w)?;
Ok(())
}
-fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut dyn Write) -> io::Result<()> {
+fn write_mir_sig(
+ tcx: TyCtxt<'_, '_, '_>,
+ src: MirSource,
+ mir: &Mir<'_>,
+ w: &mut dyn Write,
+) -> io::Result<()> {
let id = tcx.hir().as_local_node_id(src.def_id).unwrap();
let body_owner_kind = tcx.hir().body_owner_kind(id);
match (body_owner_kind, src.promoted) {
Ok(())
}
-fn write_temp_decls(mir: &Mir, w: &mut dyn Write) -> io::Result<()> {
+fn write_temp_decls(mir: &Mir<'_>, w: &mut dyn Write) -> io::Result<()> {
// Compiler-introduced temporary types.
for temp in mir.temps_iter() {
writeln!(
Ok(())
}
-fn write_user_type_annotations(mir: &Mir, w: &mut dyn Write) -> io::Result<()> {
+fn write_user_type_annotations(mir: &Mir<'_>, w: &mut dyn Write) -> io::Result<()> {
if !mir.user_type_annotations.is_empty() {
writeln!(w, "| User Type Annotations")?;
}
Ok(())
}
-pub fn dump_mir_def_ids(tcx: TyCtxt, single: Option<DefId>) -> Vec<DefId> {
+pub fn dump_mir_def_ids(tcx: TyCtxt<'_, '_, '_>, single: Option<DefId>) -> Vec<DefId> {
if let Some(i) = single {
vec![i]
} else {
authors = ["The Rust Project Developers"]
name = "rustc_passes"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_passes"
syntax = { path = "../libsyntax" }
syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }
-rustc_errors = { path = "../librustc_errors" }
+errors = { path = "../librustc_errors", package = "rustc_errors" }
// or type checking or some other kind of complex analysis.
use std::mem;
+use syntax::print::pprust;
use rustc::lint;
use rustc::session::Session;
+use rustc_data_structures::fx::FxHashMap;
use syntax::ast::*;
use syntax::attr;
use syntax::source_map::Spanned;
use syntax::symbol::keywords;
use syntax::ptr::P;
use syntax::visit::{self, Visitor};
+use syntax::{span_err, struct_span_err, walk_list};
use syntax_ext::proc_macro_decls::is_proc_macro_attr;
use syntax_pos::Span;
-use errors;
use errors::Applicability;
+use log::debug;
struct AstValidator<'a> {
session: &'a Session,
_ => None,
}
}
+}
+enum GenericPosition {
+ Param,
+ Arg,
+}
+
+fn validate_generics_order<'a>(
+ handler: &errors::Handler,
+ generics: impl Iterator<Item = (ParamKindOrd, Span, Option<String>)>,
+ pos: GenericPosition,
+ span: Span,
+) {
+ let mut max_param: Option<ParamKindOrd> = None;
+ let mut out_of_order = FxHashMap::default();
+ let mut param_idents = vec![];
+
+ for (kind, span, ident) in generics {
+ if let Some(ident) = ident {
+ param_idents.push((kind, param_idents.len(), ident));
+ }
+ let max_param = &mut max_param;
+ match max_param {
+ Some(max_param) if *max_param > kind => {
+ let entry = out_of_order.entry(kind).or_insert((*max_param, vec![]));
+ entry.1.push(span);
+ }
+ Some(_) | None => *max_param = Some(kind),
+ };
+ }
+
+ let mut ordered_params = "<".to_string();
+ if !out_of_order.is_empty() {
+ param_idents.sort_by_key(|&(po, i, _)| (po, i));
+ let mut first = true;
+ for (_, _, ident) in param_idents {
+ if !first {
+ ordered_params += ", ";
+ }
+ ordered_params += &ident;
+ first = false;
+ }
+ }
+ ordered_params += ">";
+
+ let pos_str = match pos {
+ GenericPosition::Param => "parameter",
+ GenericPosition::Arg => "argument",
+ };
+
+ for (param_ord, (max_param, spans)) in out_of_order {
+ let mut err = handler.struct_span_err(spans,
+ &format!(
+ "{} {pos}s must be declared prior to {} {pos}s",
+ param_ord,
+ max_param,
+ pos = pos_str,
+ ));
+ if let GenericPosition::Param = pos {
+ err.span_suggestion(
+ span,
+ &format!("reorder the {}s: lifetimes, then types, then consts", pos_str),
+ ordered_params.clone(),
+ Applicability::MachineApplicable,
+ );
+ }
+ err.emit();
+ }
}
impl<'a> Visitor<'a> for AstValidator<'a> {
.note("only trait implementations may be annotated with default").emit();
}
}
+ ItemKind::Fn(_, header, ref generics, _) => {
+ // We currently do not permit const generics in `const fn`, as
+ // this is tantamount to allowing compile-time dependent typing.
+ if header.constness.node == Constness::Const {
+ // Look for const generics and error if we find any.
+ for param in &generics.params {
+ match param.kind {
+ GenericParamKind::Const { .. } => {
+ self.err_handler()
+ .struct_span_err(
+ item.span,
+ "const parameters are not permitted in `const fn`",
+ )
+ .emit();
+ }
+ _ => {}
+ }
+ }
+ }
+ }
ItemKind::ForeignMod(..) => {
self.invalid_visibility(
&item.vis,
match *generic_args {
GenericArgs::AngleBracketed(ref data) => {
walk_list!(self, visit_generic_arg, &data.args);
+ validate_generics_order(self.err_handler(), data.args.iter().map(|arg| {
+ (match arg {
+ GenericArg::Lifetime(..) => ParamKindOrd::Lifetime,
+ GenericArg::Type(..) => ParamKindOrd::Type,
+ GenericArg::Const(..) => ParamKindOrd::Const,
+ }, arg.span(), None)
+ }), GenericPosition::Arg, generic_args.span());
// Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
// are allowed to contain nested `impl Trait`.
self.with_impl_trait(None, |this| {
}
fn visit_generics(&mut self, generics: &'a Generics) {
- let mut seen_non_lifetime_param = false;
- let mut seen_default = None;
+ let mut prev_ty_default = None;
for param in &generics.params {
- match (¶m.kind, seen_non_lifetime_param) {
- (GenericParamKind::Lifetime { .. }, true) => {
+ if let GenericParamKind::Type { ref default, .. } = param.kind {
+ if default.is_some() {
+ prev_ty_default = Some(param.ident.span);
+ } else if let Some(span) = prev_ty_default {
self.err_handler()
- .span_err(param.ident.span, "lifetime parameters must be leading");
- },
- (GenericParamKind::Lifetime { .. }, false) => {}
- (GenericParamKind::Type { ref default, .. }, _) => {
- seen_non_lifetime_param = true;
- if default.is_some() {
- seen_default = Some(param.ident.span);
- } else if let Some(span) = seen_default {
- self.err_handler()
- .span_err(span, "type parameters with a default must be trailing");
- break;
- }
+ .span_err(span, "type parameters with a default must be trailing");
+ break;
}
}
}
+
+ validate_generics_order(self.err_handler(), generics.params.iter().map(|param| {
+ let span = param.ident.span;
+ let ident = Some(param.ident.to_string());
+ match ¶m.kind {
+ GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, span, ident),
+ GenericParamKind::Type { .. } => (ParamKindOrd::Type, span, ident),
+ GenericParamKind::Const { ref ty } => {
+ let ty = pprust::ty_to_string(ty);
+ (ParamKindOrd::Const, span, Some(format!("const {}: {}", param.ident, ty)))
+ }
+ }
+ }), GenericPosition::Param, generics.span);
+
for predicate in &generics.where_clause.predicates {
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
self.err_handler()
supported in where clauses (see #20041)");
}
}
+
visit::walk_generics(self, generics)
}
#![allow(non_snake_case)]
+use syntax::{register_diagnostic, register_diagnostics, register_long_diagnostics};
+
register_long_diagnostics! {
/*
E0014: r##"
});
entry.count += 1;
- entry.size = ::std::mem::size_of_val(node);
+ entry.size = std::mem::size_of_val(node);
}
fn print(&self, title: &str) {
#![recursion_limit="256"]
-#[macro_use]
-extern crate rustc;
-extern crate rustc_mir;
-extern crate rustc_data_structures;
+#![deny(rust_2018_idioms)]
#[macro_use]
-extern crate log;
-#[macro_use]
-extern crate syntax;
-extern crate syntax_ext;
-extern crate syntax_pos;
-extern crate rustc_errors as errors;
+extern crate rustc;
use rustc::ty::query::Providers;
__build_diagnostic_array! { librustc_passes, DIAGNOSTICS }
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
rvalue_promotion::provide(providers);
loops::provide(providers);
}
-use self::Context::*;
+use Context::*;
use rustc::session::Session;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::{self, Node, Destination};
use syntax::ast;
+use syntax::struct_span_err;
use syntax_pos::Span;
use errors::Applicability;
}.as_deep_visitor());
}
-pub(crate) fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
check_mod_loops,
..*providers
use rustc_data_structures::sync::Lrc;
use syntax::ast;
use syntax_pos::{Span, DUMMY_SP};
-use self::Promotability::*;
+use log::debug;
+use Promotability::*;
use std::ops::{BitAnd, BitAndAssign, BitOr};
-pub fn provide(providers: &mut Providers) {
+pub fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
rvalue_promotable_map,
const_is_rvalue_promotable_to_static,
fn consume(&mut self,
_consume_id: ast::NodeId,
_consume_span: Span,
- _cmt: &mc::cmt_,
+ _cmt: &mc::cmt_<'_>,
_mode: euv::ConsumeMode) {}
fn borrow(&mut self,
fn mutate(&mut self,
_assignment_id: ast::NodeId,
_assignment_span: Span,
- _assignee_cmt: &mc::cmt_,
+ _assignee_cmt: &mc::cmt_<'_>,
_mode: euv::MutateMode) {
}
- fn matched_pat(&mut self, _: &hir::Pat, _: &mc::cmt_, _: euv::MatchMode) {}
+ fn matched_pat(&mut self, _: &hir::Pat, _: &mc::cmt_<'_>, _: euv::MatchMode) {}
- fn consume_pat(&mut self, _consume_pat: &hir::Pat, _cmt: &mc::cmt_, _mode: euv::ConsumeMode) {}
+ fn consume_pat(&mut self,
+ _consume_pat: &hir::Pat,
+ _cmt: &mc::cmt_<'_>,
+ _mode: euv::ConsumeMode) {}
}
"##,
E0401: r##"
-Inner items do not inherit type parameters from the functions they are embedded
-in.
+Inner items do not inherit type or const parameters from the functions
+they are embedded in.
Erroneous code example:
-use crate::{CrateLint, PathResult, Segment};
-use crate::macros::ParentScope;
-use crate::resolve_imports::ImportResolver;
+use std::cmp::Reverse;
+use log::debug;
+use rustc::hir::def::*;
+use rustc::hir::def::Namespace::*;
+use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::session::config::nightly_options;
+use syntax::ast::{ExprKind};
use syntax::symbol::keywords;
use syntax_pos::Span;
-use log::debug;
+use crate::errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use crate::macros::ParentScope;
+use crate::resolve_imports::ImportResolver;
+use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string};
+use crate::{AssocSuggestion, CrateLint, ImportSuggestion, ModuleOrUniformRoot, PathResult,
+ PathSource, Resolver, Segment};
-use std::cmp::Reverse;
+impl<'a> Resolver<'a> {
+ /// Handles error reporting for `smart_resolve_path_fragment` function.
+ /// Creates base error and amends it with one short label and possibly some longer helps/notes.
+ pub(crate) fn smart_resolve_report_errors(
+ &mut self,
+ path: &[Segment],
+ span: Span,
+ source: PathSource<'_>,
+ def: Option<Def>,
+ ) -> (DiagnosticBuilder<'a>, Vec<ImportSuggestion>) {
+ let ident_span = path.last().map_or(span, |ident| ident.ident.span);
+ let ns = source.namespace();
+ let is_expected = &|def| source.is_expected(def);
+ let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
+
+ // Make the base error.
+ let expected = source.descr_expected();
+ let path_str = Segment::names_to_string(path);
+ let item_str = path.last().unwrap().ident;
+ let code = source.error_code(def.is_some());
+ let (base_msg, fallback_label, base_span) = if let Some(def) = def {
+ (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
+ format!("not a {}", expected),
+ span)
+ } else {
+ let item_span = path.last().unwrap().ident.span;
+ let (mod_prefix, mod_str) = if path.len() == 1 {
+ (String::new(), "this scope".to_string())
+ } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() {
+ (String::new(), "the crate root".to_string())
+ } else {
+ let mod_path = &path[..path.len() - 1];
+ let mod_prefix = match self.resolve_path_without_parent_scope(
+ mod_path, Some(TypeNS), false, span, CrateLint::No
+ ) {
+ PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
+ module.def(),
+ _ => None,
+ }.map_or(String::new(), |def| format!("{} ", def.kind_name()));
+ (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)))
+ };
+ (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
+ format!("not found in {}", mod_str),
+ item_span)
+ };
+
+ let code = DiagnosticId::Error(code.into());
+ let mut err = self.session.struct_span_err_with_code(base_span, &base_msg, code);
+
+ // Emit help message for fake-self from other languages (e.g., `this` in Javascript).
+ if ["this", "my"].contains(&&*item_str.as_str())
+ && self.self_value_is_available(path[0].ident.span, span) {
+ err.span_suggestion(
+ span,
+ "did you mean",
+ "self".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+
+ // Emit special messages for unresolved `Self` and `self`.
+ if is_self_type(path, ns) {
+ __diagnostic_used!(E0411);
+ err.code(DiagnosticId::Error("E0411".into()));
+ err.span_label(span, format!("`Self` is only available in impls, traits, \
+ and type definitions"));
+ return (err, Vec::new());
+ }
+ if is_self_value(path, ns) {
+ debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
+
+ __diagnostic_used!(E0424);
+ err.code(DiagnosticId::Error("E0424".into()));
+ err.span_label(span, match source {
+ PathSource::Pat => {
+ format!("`self` value is a keyword \
+ and may not be bound to \
+ variables or shadowed")
+ }
+ _ => {
+ format!("`self` value is a keyword \
+ only available in methods \
+ with `self` parameter")
+ }
+ });
+ return (err, Vec::new());
+ }
+
+ // Try to lookup name in more relaxed fashion for better error reporting.
+ let ident = path.last().unwrap().ident;
+ let candidates = self.lookup_import_candidates(ident, ns, is_expected);
+ if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
+ let enum_candidates =
+ self.lookup_import_candidates(ident, ns, is_enum_variant);
+ let mut enum_candidates = enum_candidates.iter()
+ .map(|suggestion| {
+ import_candidate_to_enum_paths(&suggestion)
+ }).collect::<Vec<_>>();
+ enum_candidates.sort();
+
+ if !enum_candidates.is_empty() {
+ // Contextualize for E0412 "cannot find type", but don't belabor the point
+ // (that it's a variant) for E0573 "expected type, found variant".
+ let preamble = if def.is_none() {
+ let others = match enum_candidates.len() {
+ 1 => String::new(),
+ 2 => " and 1 other".to_owned(),
+ n => format!(" and {} others", n)
+ };
+ format!("there is an enum variant `{}`{}; ",
+ enum_candidates[0].0, others)
+ } else {
+ String::new()
+ };
+ let msg = format!("{}try using the variant's enum", preamble);
+
+ err.span_suggestions(
+ span,
+ &msg,
+ enum_candidates.into_iter()
+ .map(|(_variant_path, enum_ty_path)| enum_ty_path)
+ // Variants re-exported in prelude doesn't mean `prelude::v1` is the
+ // type name!
+ // FIXME: is there a more principled way to do this that
+ // would work for other re-exports?
+ .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1")
+ // Also write `Option` rather than `std::prelude::v1::Option`.
+ .map(|enum_ty_path| {
+ // FIXME #56861: DRY-er prelude filtering.
+ enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned()
+ }),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+ if path.len() == 1 && self.self_type_is_available(span) {
+ if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) {
+ let self_is_available = self.self_value_is_available(path[0].ident.span, span);
+ match candidate {
+ AssocSuggestion::Field => {
+ err.span_suggestion(
+ span,
+ "try",
+ format!("self.{}", path_str),
+ Applicability::MachineApplicable,
+ );
+ if !self_is_available {
+ err.span_label(span, format!("`self` value is a keyword \
+ only available in \
+ methods with `self` parameter"));
+ }
+ }
+ AssocSuggestion::MethodWithSelf if self_is_available => {
+ err.span_suggestion(
+ span,
+ "try",
+ format!("self.{}", path_str),
+ Applicability::MachineApplicable,
+ );
+ }
+ AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => {
+ err.span_suggestion(
+ span,
+ "try",
+ format!("Self::{}", path_str),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+ return (err, candidates);
+ }
+ }
+
+ let mut levenshtein_worked = false;
+
+ // Try Levenshtein algorithm.
+ let suggestion = self.lookup_typo_candidate(path, ns, is_expected, span);
+ if let Some(suggestion) = suggestion {
+ let msg = format!(
+ "{} {} with a similar name exists",
+ suggestion.article, suggestion.kind
+ );
+ err.span_suggestion(
+ ident_span,
+ &msg,
+ suggestion.candidate.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+
+ levenshtein_worked = true;
+ }
+
+ // Try context-dependent help if relaxed lookup didn't work.
+ if let Some(def) = def {
+ if self.smart_resolve_context_dependent_help(&mut err,
+ span,
+ source,
+ def,
+ &path_str,
+ &fallback_label) {
+ return (err, candidates);
+ }
+ }
+
+ // Fallback label.
+ if !levenshtein_worked {
+ err.span_label(base_span, fallback_label);
+ self.type_ascription_suggestion(&mut err, base_span);
+ }
+ (err, candidates)
+ }
+
+ /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment`
+ /// function.
+ /// Returns `true` if able to provide context-dependent help.
+ fn smart_resolve_context_dependent_help(
+ &mut self,
+ err: &mut DiagnosticBuilder<'a>,
+ span: Span,
+ source: PathSource<'_>,
+ def: Def,
+ path_str: &str,
+ fallback_label: &str,
+ ) -> bool {
+ let ns = source.namespace();
+ let is_expected = &|def| source.is_expected(def);
+
+ match (def, source) {
+ (Def::Macro(..), _) => {
+ err.span_suggestion(
+ span,
+ "use `!` to invoke the macro",
+ format!("{}!", path_str),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ (Def::TyAlias(..), PathSource::Trait(_)) => {
+ err.span_label(span, "type aliases cannot be used as traits");
+ if nightly_options::is_nightly_build() {
+ err.note("did you mean to use a trait alias?");
+ }
+ }
+ (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
+ ExprKind::Field(_, ident) => {
+ err.span_suggestion(
+ parent.span,
+ "use the path separator to refer to an item",
+ format!("{}::{}", path_str, ident),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ ExprKind::MethodCall(ref segment, ..) => {
+ let span = parent.span.with_hi(segment.ident.span.hi());
+ err.span_suggestion(
+ span,
+ "use the path separator to refer to an item",
+ format!("{}::{}", path_str, segment.ident),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ _ => return false,
+ },
+ (Def::Enum(..), PathSource::TupleStruct)
+ | (Def::Enum(..), PathSource::Expr(..)) => {
+ if let Some(variants) = self.collect_enum_variants(def) {
+ err.note(&format!("did you mean to use one \
+ of the following variants?\n{}",
+ variants.iter()
+ .map(|suggestion| path_names_to_string(suggestion))
+ .map(|suggestion| format!("- `{}`", suggestion))
+ .collect::<Vec<_>>()
+ .join("\n")));
+ } else {
+ err.note("did you mean to use one of the enum's variants?");
+ }
+ },
+ (Def::Struct(def_id), _) if ns == ValueNS => {
+ if let Some((ctor_def, ctor_vis))
+ = self.struct_constructors.get(&def_id).cloned() {
+ let accessible_ctor = self.is_accessible(ctor_vis);
+ if is_expected(ctor_def) && !accessible_ctor {
+ err.span_label(span, format!("constructor is not visible \
+ here due to private fields"));
+ }
+ } else {
+ // HACK(estebank): find a better way to figure out that this was a
+ // 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 sm = self.session.source_map();
+ let mut sp = span;
+ loop {
+ sp = sm.next_point(sp);
+ match sm.span_to_snippet(sp) {
+ Ok(ref snippet) => {
+ if snippet.chars().any(|c| { !c.is_whitespace() }) {
+ break;
+ }
+ }
+ _ => break,
+ }
+ }
+ let followed_by_brace = match sm.span_to_snippet(sp) {
+ Ok(ref snippet) if snippet == "{" => true,
+ _ => false,
+ };
+ // In case this could be a struct literal that needs to be surrounded
+ // by parenthesis, find the appropriate span.
+ let mut i = 0;
+ let mut closing_brace = None;
+ loop {
+ sp = sm.next_point(sp);
+ match sm.span_to_snippet(sp) {
+ Ok(ref snippet) => {
+ if snippet == "}" {
+ let sp = span.to(sp);
+ if let Ok(snippet) = sm.span_to_snippet(sp) {
+ closing_brace = Some((sp, snippet));
+ }
+ break;
+ }
+ }
+ _ => break,
+ }
+ i += 1;
+ // The bigger the span, the more likely we're incorrect --
+ // bound it to 100 chars long.
+ if i > 100 {
+ break;
+ }
+ }
+ match source {
+ PathSource::Expr(Some(parent)) => {
+ match parent.node {
+ ExprKind::MethodCall(ref path_assignment, _) => {
+ err.span_suggestion(
+ sm.start_point(parent.span)
+ .to(path_assignment.ident.span),
+ "use `::` to access an associated function",
+ format!("{}::{}",
+ path_str,
+ path_assignment.ident),
+ Applicability::MaybeIncorrect
+ );
+ },
+ _ => {
+ err.span_label(
+ span,
+ format!("did you mean `{} {{ /* fields */ }}`?",
+ path_str),
+ );
+ },
+ }
+ },
+ PathSource::Expr(None) if followed_by_brace == true => {
+ if let Some((sp, snippet)) = closing_brace {
+ err.span_suggestion(
+ sp,
+ "surround the struct literal with parenthesis",
+ format!("({})", snippet),
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ err.span_label(
+ span,
+ format!("did you mean `({} {{ /* fields */ }})`?",
+ path_str),
+ );
+ }
+ },
+ _ => {
+ err.span_label(
+ span,
+ format!("did you mean `{} {{ /* fields */ }}`?",
+ path_str),
+ );
+ },
+ }
+ }
+ }
+ (Def::Union(..), _) |
+ (Def::Variant(..), _) |
+ (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => {
+ err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
+ path_str));
+ }
+ (Def::SelfTy(..), _) if ns == ValueNS => {
+ err.span_label(span, fallback_label);
+ err.note("can't use `Self` as a constructor, you must use the \
+ implemented struct");
+ }
+ (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => {
+ err.note("can't use a type alias as a constructor");
+ }
+ _ => return false,
+ }
+ true
+ }
+}
impl<'a, 'b:'a> ImportResolver<'a, 'b> {
- /// Add suggestions for a path that cannot be resolved.
+ /// Adds suggestions for a path that cannot be resolved.
pub(crate) fn make_path_suggestion(
&mut self,
span: Span,
// On 2015 `{{root}}` is usually added implicitly.
(Some(fst), Some(snd)) if fst.ident.name == keywords::PathRoot.name() &&
!snd.ident.is_path_segment_keyword() => {}
- // `ident::...` on 2018
+ // `ident::...` on 2018.
(Some(fst), _) if fst.ident.span.rust_2018() &&
!fst.ident.is_path_segment_keyword() => {
// Insert a placeholder that's later replaced by `self`/`super`/etc.
}
}
- /// Suggest a missing `crate::` if that resolves to an correct module.
+ /// Suggests a missing `crate::` if that resolves to an correct module.
///
/// ```
/// |
}
}
- /// Suggest a missing `super::` if that resolves to an correct module.
+ /// Suggests a missing `super::` if that resolves to an correct module.
///
/// ```
/// |
}
}
- /// Suggest a missing external crate name if that resolves to an correct module.
+ /// Suggests a missing external crate name if that resolves to an correct module.
///
/// ```
/// |
}
// Sort extern crate names in reverse order to get
- // 1) some consistent ordering for emitted dignostics and
+ // 1) some consistent ordering for emitted dignostics, and
// 2) `std` suggestions before `core` suggestions.
let mut extern_crate_names =
self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
pub use rustc::hir::def::{Namespace, PerNS};
-use TypeParameters::*;
+use GenericParameters::*;
use RibKind::*;
use rustc::hir::map::{Definitions, DefCollector};
use rustc::hir::def::Namespace::*;
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
-use rustc::session::config::nightly_options;
use rustc::ty;
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
use rustc::{bug, span_bug};
}
enum ResolutionError<'a> {
- /// error E0401: can't use type parameters from outer function
- TypeParametersFromOuterFunction(Def),
- /// error E0403: the name is already used for a type parameter in this type parameter list
- NameAlreadyUsedInTypeParameterList(Name, &'a Span),
+ /// error E0401: can't use type or const parameters from outer function
+ GenericParamsFromOuterFunction(Def),
+ /// error E0403: the name is already used for a type/const parameter in this list of
+ /// generic parameters
+ NameAlreadyUsedInParameterList(Name, &'a Span),
/// error E0407: method is not a member of trait
MethodNotMemberOfTrait(Name, &'a str),
/// error E0437: type is not a member of trait
/// error E0530: X bindings cannot shadow Ys
BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
/// error E0128: type parameters with a default cannot use forward declared identifiers
- ForwardDeclaredTyParam,
+ ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
}
/// Combines an error with provided span and emits it
resolution_error: ResolutionError<'a>)
-> DiagnosticBuilder<'sess> {
match resolution_error {
- ResolutionError::TypeParametersFromOuterFunction(outer_def) => {
+ ResolutionError::GenericParamsFromOuterFunction(outer_def) => {
let mut err = struct_span_err!(resolver.session,
- span,
- E0401,
- "can't use type parameters from outer function");
- err.span_label(span, "use of type variable from outer function");
+ span,
+ E0401,
+ "can't use generic parameters from outer function",
+ );
+ err.span_label(span, format!("use of generic parameter from outer function"));
let cm = resolver.session.source_map();
match outer_def {
}
return err;
},
- Def::TyParam(typaram_defid) => {
- if let Some(typaram_span) = resolver.definitions.opt_span(typaram_defid) {
- err.span_label(typaram_span, "type variable from outer function");
+ Def::TyParam(def_id) => {
+ if let Some(span) = resolver.definitions.opt_span(def_id) {
+ err.span_label(span, "type variable from outer function");
}
- },
+ }
+ Def::ConstParam(def_id) => {
+ if let Some(span) = resolver.definitions.opt_span(def_id) {
+ err.span_label(span, "const variable from outer function");
+ }
+ }
_ => {
- bug!("TypeParametersFromOuterFunction should only be used with Def::SelfTy or \
- Def::TyParam")
+ bug!("GenericParamsFromOuterFunction should only be used with Def::SelfTy, \
+ Def::TyParam");
}
}
// Try to retrieve the span of the function signature and generate a new message with
- // a local type parameter
- let sugg_msg = "try using a local type parameter instead";
+ // a local type or const parameter.
+ let sugg_msg = &format!("try using a local generic parameter instead");
if let Some((sugg_span, new_snippet)) = cm.generate_local_type_param_snippet(span) {
// Suggest the modification to the user
err.span_suggestion(
Applicability::MachineApplicable,
);
} else if let Some(sp) = cm.generate_fn_name_span(span) {
- err.span_label(sp, "try adding a local type parameter in this method instead");
+ err.span_label(sp,
+ format!("try adding a local generic parameter in this method instead"));
} else {
- err.help("try using a local type parameter instead");
+ err.help(&format!("try using a local generic parameter instead"));
}
err
}
- ResolutionError::NameAlreadyUsedInTypeParameterList(name, first_use_span) => {
+ ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
let mut err = struct_span_err!(resolver.session,
span,
E0403,
- "the name `{}` is already used for a type parameter \
- in this type parameter list",
+ "the name `{}` is already used for a generic \
+ parameter in this list of generic parameters",
name);
err.span_label(span, "already used");
err.span_label(first_use_span.clone(), format!("first use of `{}`", name));
Def::Struct(..) | Def::Union(..) | Def::Enum(..) |
Def::Trait(..) | Def::TraitAlias(..) | Def::TyAlias(..) |
Def::AssociatedTy(..) | Def::PrimTy(..) | Def::TyParam(..) |
- Def::SelfTy(..) | Def::Existential(..) |
- Def::ForeignTy(..) => true,
+ Def::SelfTy(..) | Def::Existential(..) | Def::ForeignTy(..) => true,
_ => false,
},
PathSource::Trait(AliasPossibility::No) => match def {
Def::VariantCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Fn) |
Def::Const(..) | Def::Static(..) | Def::Local(..) | Def::Upvar(..) |
Def::Fn(..) | Def::Method(..) | Def::AssociatedConst(..) |
- Def::SelfCtor(..) => true,
+ Def::SelfCtor(..) | Def::ConstParam(..) => true,
_ => false,
},
PathSource::Pat => match def {
self.resolve_block(block);
}
fn visit_anon_const(&mut self, constant: &'tcx ast::AnonConst) {
+ debug!("visit_anon_const {:?}", constant);
self.with_constant_rib(|this| {
visit::walk_anon_const(this, constant);
});
visit::walk_poly_trait_ref(self, tref, m);
}
fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) {
- let type_parameters = match foreign_item.node {
+ let generic_params = match foreign_item.node {
ForeignItemKind::Fn(_, ref generics) => {
- HasTypeParameters(generics, ItemRibKind)
+ HasGenericParams(generics, ItemRibKind)
}
- ForeignItemKind::Static(..) => NoTypeParameters,
- ForeignItemKind::Ty => NoTypeParameters,
- ForeignItemKind::Macro(..) => NoTypeParameters,
+ ForeignItemKind::Static(..) => NoGenericParams,
+ ForeignItemKind::Ty => NoGenericParams,
+ ForeignItemKind::Macro(..) => NoGenericParams,
};
- self.with_type_parameter_rib(type_parameters, |this| {
+ self.with_generic_param_rib(generic_params, |this| {
visit::walk_foreign_item(this, foreign_item);
});
}
_: Span,
node_id: NodeId)
{
+ debug!("(resolving function) entering function");
let (rib_kind, asyncness) = match function_kind {
FnKind::ItemFn(_, ref header, ..) =>
(ItemRibKind, header.asyncness),
self.label_ribs.pop();
self.ribs[ValueNS].pop();
}
+
fn visit_generics(&mut self, generics: &'tcx Generics) {
// For type parameter defaults, we have to ban access
// to following type parameters, as the Substs can only
let mut found_default = false;
default_ban_rib.bindings.extend(generics.params.iter()
.filter_map(|param| match param.kind {
+ GenericParamKind::Const { .. } |
GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { ref default, .. } => {
found_default |= default.is_some();
// Allow all following defaults to refer to this type parameter.
default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
}
+ GenericParamKind::Const { ref ty } => {
+ for bound in ¶m.bounds {
+ self.visit_param_bound(bound);
+ }
+
+ self.visit_ty(ty);
+ }
}
}
for p in &generics.where_clause.predicates {
}
#[derive(Copy, Clone)]
-enum TypeParameters<'a, 'b> {
- NoTypeParameters,
- HasTypeParameters(// Type parameters.
+enum GenericParameters<'a, 'b> {
+ NoGenericParams,
+ HasGenericParams(// Type parameters.
&'b Generics,
// The kind of the rib used for type parameters.
}
}
- /// resolve_hir_path, but takes a callback in case there was an error
+ /// Like `resolve_hir_path`, but takes a callback in case there was an error.
fn resolve_hir_path_cb<F>(
&mut self,
path: &ast::Path,
let span = path.span;
let segments = &path.segments;
let path = Segment::from_path(&path);
- // FIXME (Manishearth): Intra doc links won't get warned of epoch changes
+ // FIXME(Manishearth): intra-doc links won't get warned of epoch changes.
let def = match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
span, CrateLint::No) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
let record_used = record_used_id.is_some();
let mut module = self.graph_root;
for i in (0 .. self.ribs[ns].len()).rev() {
+ debug!("walk rib\n{:?}", self.ribs[ns][i].bindings);
if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
// The ident resolves to a type parameter or local variable.
return Some(LexicalScopeBinding::Def(
}
fn resolve_adt(&mut self, item: &Item, generics: &Generics) {
+ debug!("resolve_adt");
self.with_current_self_item(item, |this| {
- this.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
+ this.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
let item_def_id = this.definitions.local_def_id(item.id);
this.with_self_rib(Def::SelfTy(None, Some(item_def_id)), |this| {
visit::walk_item(this, item);
fn resolve_item(&mut self, item: &Item) {
let name = item.ident.name;
- debug!("(resolving item) resolving {}", name);
+ debug!("(resolving item) resolving {} ({:?})", name, item.node);
match item.node {
ItemKind::Ty(_, ref generics) |
ItemKind::Fn(_, _, ref generics, _) |
ItemKind::Existential(_, ref generics) => {
- self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind),
+ self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind),
|this| visit::walk_item(this, item));
}
ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => {
// Create a new rib for the trait-wide type parameters.
- self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
+ self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
let local_def_id = this.definitions.local_def_id(item.id);
this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
this.visit_generics(generics);
walk_list!(this, visit_param_bound, bounds);
for trait_item in trait_items {
- let type_parameters = HasTypeParameters(&trait_item.generics,
+ let generic_params = HasGenericParams(&trait_item.generics,
TraitOrImplItemRibKind);
- this.with_type_parameter_rib(type_parameters, |this| {
+ this.with_generic_param_rib(generic_params, |this| {
match trait_item.node {
TraitItemKind::Const(ref ty, ref default) => {
this.visit_ty(ty);
ItemKind::TraitAlias(ref generics, ref bounds) => {
// Create a new rib for the trait-wide type parameters.
- self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
+ self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
let local_def_id = this.definitions.local_def_id(item.id);
this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
this.visit_generics(generics);
ItemKind::Static(ref ty, _, ref expr) |
ItemKind::Const(ref ty, ref expr) => {
+ debug!("resolve_item ItemKind::Const");
self.with_item_rib(|this| {
this.visit_ty(ty);
this.with_constant_rib(|this| {
}
}
- fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
+ fn with_generic_param_rib<'b, F>(&'b mut self, generic_params: GenericParameters<'a, 'b>, f: F)
where F: FnOnce(&mut Resolver<'_>)
{
- match type_parameters {
- HasTypeParameters(generics, rib_kind) => {
+ debug!("with_generic_param_rib");
+ match generic_params {
+ HasGenericParams(generics, rib_kind) => {
let mut function_type_rib = Rib::new(rib_kind);
+ let mut function_value_rib = Rib::new(rib_kind);
let mut seen_bindings = FxHashMap::default();
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { .. } => {
let ident = param.ident.modern();
- debug!("with_type_parameter_rib: {}", param.id);
+ debug!("with_generic_param_rib: {}", param.id);
if seen_bindings.contains_key(&ident) {
let span = seen_bindings.get(&ident).unwrap();
- let err = ResolutionError::NameAlreadyUsedInTypeParameterList(
+ let err = ResolutionError::NameAlreadyUsedInParameterList(
ident.name,
span,
);
function_type_rib.bindings.insert(ident, def);
self.record_def(param.id, PathResolution::new(def));
}
+ GenericParamKind::Const { .. } => {
+ let ident = param.ident.modern();
+ debug!("with_generic_param_rib: {}", param.id);
+
+ if seen_bindings.contains_key(&ident) {
+ let span = seen_bindings.get(&ident).unwrap();
+ let err = ResolutionError::NameAlreadyUsedInParameterList(
+ ident.name,
+ span,
+ );
+ resolve_error(self, param.ident.span, err);
+ }
+ seen_bindings.entry(ident).or_insert(param.ident.span);
+
+ let def = Def::ConstParam(self.definitions.local_def_id(param.id));
+ function_value_rib.bindings.insert(ident, def);
+ self.record_def(param.id, PathResolution::new(def));
+ }
}
}
+ self.ribs[ValueNS].push(function_value_rib);
self.ribs[TypeNS].push(function_type_rib);
}
- NoTypeParameters => {
+ NoGenericParams => {
// Nothing to do.
}
}
f(self);
- if let HasTypeParameters(..) = type_parameters {
+ if let HasGenericParams(..) = generic_params {
self.ribs[TypeNS].pop();
+ self.ribs[ValueNS].pop();
}
}
fn with_constant_rib<F>(&mut self, f: F)
where F: FnOnce(&mut Resolver<'_>)
{
+ debug!("with_constant_rib");
self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind));
self.label_ribs.push(Rib::new(ConstantItemRibKind));
f(self);
self_type: &Ty,
item_id: NodeId,
impl_items: &[ImplItem]) {
+ debug!("resolve_implementation");
// If applicable, create a rib for the type parameters.
- self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
+ self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| {
// Dummy self type for better errors if `Self` is used in the trait path.
this.with_self_rib(Def::SelfTy(None, None), |this| {
// Resolve the trait reference, if necessary.
}
// Resolve the self type.
this.visit_ty(self_type);
- // Resolve the type parameters.
+ // Resolve the generic parameters.
this.visit_generics(generics);
// Resolve the items within the impl.
this.with_current_self_type(self_type, |this| {
this.with_self_struct_ctor_rib(item_def_id, |this| {
+ debug!("resolve_implementation with_self_struct_ctor_rib");
for impl_item in impl_items {
this.resolve_visibility(&impl_item.vis);
// We also need a new scope for the impl item type parameters.
- let type_parameters = HasTypeParameters(&impl_item.generics,
- TraitOrImplItemRibKind);
- this.with_type_parameter_rib(type_parameters, |this| {
+ let generic_params = HasGenericParams(&impl_item.generics,
+ TraitOrImplItemRibKind);
+ this.with_generic_param_rib(generic_params, |this| {
use self::ResolutionError::*;
match impl_item.node {
ImplItemKind::Const(..) => {
+ debug!(
+ "resolve_implementation ImplItemKind::Const",
+ );
// If this is a trait impl, ensure the const
// exists in trait
- this.check_trait_item(impl_item.ident,
- ValueNS,
- impl_item.span,
- |n, s| ConstNotMemberOfTrait(n, s));
- this.with_constant_rib(|this|
- visit::walk_impl_item(this, impl_item)
+ this.check_trait_item(
+ impl_item.ident,
+ ValueNS,
+ impl_item.span,
+ |n, s| ConstNotMemberOfTrait(n, s),
);
+
+ this.with_constant_rib(|this| {
+ visit::walk_impl_item(this, impl_item)
+ });
}
ImplItemKind::Method(..) => {
// If this is a trait impl, ensure the method
source: PathSource<'_>,
crate_lint: CrateLint)
-> PathResolution {
- let ident_span = path.last().map_or(span, |ident| ident.ident.span);
let ns = source.namespace();
let is_expected = &|def| source.is_expected(def);
- let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
- // Base error is amended with one short label and possibly some longer helps/notes.
let report_errors = |this: &mut Self, def: Option<Def>| {
- // Make the base error.
- let expected = source.descr_expected();
- let path_str = Segment::names_to_string(path);
- let item_str = path.last().unwrap().ident;
- let code = source.error_code(def.is_some());
- let (base_msg, fallback_label, base_span) = if let Some(def) = def {
- (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
- format!("not a {}", expected),
- span)
- } else {
- let item_span = path.last().unwrap().ident.span;
- let (mod_prefix, mod_str) = if path.len() == 1 {
- (String::new(), "this scope".to_string())
- } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() {
- (String::new(), "the crate root".to_string())
- } else {
- let mod_path = &path[..path.len() - 1];
- let mod_prefix = match this.resolve_path_without_parent_scope(
- mod_path, Some(TypeNS), false, span, CrateLint::No
- ) {
- PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
- module.def(),
- _ => None,
- }.map_or(String::new(), |def| format!("{} ", def.kind_name()));
- (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path)))
- };
- (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
- format!("not found in {}", mod_str),
- item_span)
- };
-
- let code = DiagnosticId::Error(code.into());
- let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
-
- // Emit help message for fake-self from other languages like `this`(javascript)
- if ["this", "my"].contains(&&*item_str.as_str())
- && this.self_value_is_available(path[0].ident.span, span) {
- err.span_suggestion(
- span,
- "did you mean",
- "self".to_string(),
- Applicability::MaybeIncorrect,
- );
- }
-
- // Emit special messages for unresolved `Self` and `self`.
- if is_self_type(path, ns) {
- __diagnostic_used!(E0411);
- err.code(DiagnosticId::Error("E0411".into()));
- err.span_label(span, format!("`Self` is only available in impls, traits, \
- and type definitions"));
- return (err, Vec::new());
- }
- if is_self_value(path, ns) {
- debug!("smart_resolve_path_fragment E0424 source:{:?}", source);
-
- __diagnostic_used!(E0424);
- err.code(DiagnosticId::Error("E0424".into()));
- err.span_label(span, match source {
- PathSource::Pat => {
- format!("`self` value is a keyword \
- and may not be bound to \
- variables or shadowed")
- }
- _ => {
- format!("`self` value is a keyword \
- only available in methods \
- with `self` parameter")
- }
- });
- return (err, Vec::new());
- }
-
- // Try to lookup the name in more relaxed fashion for better error reporting.
- let ident = path.last().unwrap().ident;
- let candidates = this.lookup_import_candidates(ident, ns, is_expected);
- if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
- let enum_candidates =
- this.lookup_import_candidates(ident, ns, is_enum_variant);
- let mut enum_candidates = enum_candidates.iter()
- .map(|suggestion| {
- import_candidate_to_enum_paths(&suggestion)
- }).collect::<Vec<_>>();
- enum_candidates.sort();
-
- if !enum_candidates.is_empty() {
- // contextualize for E0412 "cannot find type", but don't belabor the point
- // (that it's a variant) for E0573 "expected type, found variant"
- let preamble = if def.is_none() {
- let others = match enum_candidates.len() {
- 1 => String::new(),
- 2 => " and 1 other".to_owned(),
- n => format!(" and {} others", n)
- };
- format!("there is an enum variant `{}`{}; ",
- enum_candidates[0].0, others)
- } else {
- String::new()
- };
- let msg = format!("{}try using the variant's enum", preamble);
-
- err.span_suggestions(
- span,
- &msg,
- enum_candidates.into_iter()
- .map(|(_variant_path, enum_ty_path)| enum_ty_path)
- // variants reëxported in prelude doesn't mean `prelude::v1` is the
- // type name! FIXME: is there a more principled way to do this that
- // would work for other reëxports?
- .filter(|enum_ty_path| enum_ty_path != "std::prelude::v1")
- // also say `Option` rather than `std::prelude::v1::Option`
- .map(|enum_ty_path| {
- // FIXME #56861: DRYer prelude filtering
- enum_ty_path.trim_start_matches("std::prelude::v1::").to_owned()
- }),
- Applicability::MachineApplicable,
- );
- }
- }
- if path.len() == 1 && this.self_type_is_available(span) {
- if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) {
- let self_is_available = this.self_value_is_available(path[0].ident.span, span);
- match candidate {
- AssocSuggestion::Field => {
- err.span_suggestion(
- span,
- "try",
- format!("self.{}", path_str),
- Applicability::MachineApplicable,
- );
- if !self_is_available {
- err.span_label(span, format!("`self` value is a keyword \
- only available in \
- methods with `self` parameter"));
- }
- }
- AssocSuggestion::MethodWithSelf if self_is_available => {
- err.span_suggestion(
- span,
- "try",
- format!("self.{}", path_str),
- Applicability::MachineApplicable,
- );
- }
- AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => {
- err.span_suggestion(
- span,
- "try",
- format!("Self::{}", path_str),
- Applicability::MachineApplicable,
- );
- }
- }
- return (err, candidates);
- }
- }
-
- let mut levenshtein_worked = false;
-
- // Try Levenshtein algorithm.
- let suggestion = this.lookup_typo_candidate(path, ns, is_expected, span);
- if let Some(suggestion) = suggestion {
- let msg = format!(
- "{} {} with a similar name exists",
- suggestion.article, suggestion.kind
- );
- err.span_suggestion(
- ident_span,
- &msg,
- suggestion.candidate.to_string(),
- Applicability::MaybeIncorrect,
- );
-
- levenshtein_worked = true;
- }
-
- // Try context dependent help if relaxed lookup didn't work.
- if let Some(def) = def {
- match (def, source) {
- (Def::Macro(..), _) => {
- err.span_suggestion(
- span,
- "use `!` to invoke the macro",
- format!("{}!", path_str),
- Applicability::MaybeIncorrect,
- );
- return (err, candidates);
- }
- (Def::TyAlias(..), PathSource::Trait(_)) => {
- err.span_label(span, "type aliases cannot be used as traits");
- if nightly_options::is_nightly_build() {
- err.note("did you mean to use a trait alias?");
- }
- return (err, candidates);
- }
- (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
- ExprKind::Field(_, ident) => {
- err.span_suggestion(
- parent.span,
- "use the path separator to refer to an item",
- format!("{}::{}", path_str, ident),
- Applicability::MaybeIncorrect,
- );
- return (err, candidates);
- }
- ExprKind::MethodCall(ref segment, ..) => {
- let span = parent.span.with_hi(segment.ident.span.hi());
- err.span_suggestion(
- span,
- "use the path separator to refer to an item",
- format!("{}::{}", path_str, segment.ident),
- Applicability::MaybeIncorrect,
- );
- return (err, candidates);
- }
- _ => {}
- },
- (Def::Enum(..), PathSource::TupleStruct)
- | (Def::Enum(..), PathSource::Expr(..)) => {
- if let Some(variants) = this.collect_enum_variants(def) {
- err.note(&format!("did you mean to use one \
- of the following variants?\n{}",
- variants.iter()
- .map(|suggestion| path_names_to_string(suggestion))
- .map(|suggestion| format!("- `{}`", suggestion))
- .collect::<Vec<_>>()
- .join("\n")));
-
- } else {
- err.note("did you mean to use one of the enum's variants?");
- }
- return (err, candidates);
- },
- (Def::Struct(def_id), _) if ns == ValueNS => {
- if let Some((ctor_def, ctor_vis))
- = this.struct_constructors.get(&def_id).cloned() {
- let accessible_ctor = this.is_accessible(ctor_vis);
- if is_expected(ctor_def) && !accessible_ctor {
- err.span_label(span, format!("constructor is not visible \
- here due to private fields"));
- }
- } else {
- // HACK(estebank): find a better way to figure out that this was a
- // 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 sm = this.session.source_map();
- let mut sp = span;
- loop {
- sp = sm.next_point(sp);
- match sm.span_to_snippet(sp) {
- Ok(ref snippet) => {
- if snippet.chars().any(|c| { !c.is_whitespace() }) {
- break;
- }
- }
- _ => break,
- }
- }
- let followed_by_brace = match sm.span_to_snippet(sp) {
- Ok(ref snippet) if snippet == "{" => true,
- _ => false,
- };
- // In case this could be a struct literal that needs to be surrounded
- // by parenthesis, find the appropriate span.
- let mut i = 0;
- let mut closing_brace = None;
- loop {
- sp = sm.next_point(sp);
- match sm.span_to_snippet(sp) {
- Ok(ref snippet) => {
- if snippet == "}" {
- let sp = span.to(sp);
- if let Ok(snippet) = sm.span_to_snippet(sp) {
- closing_brace = Some((sp, snippet));
- }
- break;
- }
- }
- _ => break,
- }
- i += 1;
- if i > 100 { // The bigger the span the more likely we're
- break; // incorrect. Bound it to 100 chars long.
- }
- }
- match source {
- PathSource::Expr(Some(parent)) => {
- match parent.node {
- ExprKind::MethodCall(ref path_assignment, _) => {
- err.span_suggestion(
- 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 => {
- if let Some((sp, snippet)) = closing_brace {
- err.span_suggestion(
- sp,
- "surround the struct literal with parenthesis",
- format!("({})", snippet),
- Applicability::MaybeIncorrect,
- );
- } else {
- 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);
- }
- (Def::Union(..), _) |
- (Def::Variant(..), _) |
- (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => {
- err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
- path_str));
- return (err, candidates);
- }
- (Def::SelfTy(..), _) if ns == ValueNS => {
- err.span_label(span, fallback_label);
- err.note("can't use `Self` as a constructor, you must use the \
- implemented struct");
- return (err, candidates);
- }
- (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => {
- err.note("can't use a type alias as a constructor");
- return (err, candidates);
- }
- _ => {}
- }
- }
-
- // Fallback label.
- if !levenshtein_worked {
- err.span_label(base_span, fallback_label);
- this.type_ascription_suggestion(&mut err, base_span);
- }
- (err, candidates)
- };
- let report_errors = |this: &mut Self, def: Option<Def>| {
- let (err, candidates) = report_errors(this, def);
+ let (err, candidates) = this.smart_resolve_report_errors(path, span, source, def);
let def_id = this.current_module.normal_ancestor_id;
let node_id = this.definitions.as_local_node_id(def_id).unwrap();
let better = def.is_some();
debug!("self.current_type_ascription {:?}", self.current_type_ascription);
if let Some(sp) = self.current_type_ascription.last() {
let mut sp = *sp;
- loop { // try to find the `:`, bail on first non-':'/non-whitespace
+ loop {
+ // Try to find the `:`; bail on first non-':' / non-whitespace.
sp = cm.next_point(sp);
if let Ok(snippet) = cm.span_to_snippet(sp.to(cm.next_point(sp))) {
debug!("snippet {:?}", snippet);
mut def: Def,
record_used: bool,
span: Span) -> Def {
+ debug!("adjust_local_def");
let ribs = &self.ribs[ns][rib_index + 1..];
// An invalid forward use of a type parameter from a previous default.
span_bug!(span, "unexpected {:?} in bindings", def)
}
Def::Local(node_id) => {
+ use ResolutionError::*;
+ let mut res_err = None;
+
for rib in ribs {
match rib.kind {
NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) |
// named function item. This is not allowed, so we
// report an error.
if record_used {
- resolve_error(self, span,
- ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
+ // We don't immediately trigger a resolve error, because
+ // we want certain other resolution errors (namely those
+ // emitted for `ConstantItemRibKind` below) to take
+ // precedence.
+ res_err = Some(CannotCaptureDynamicEnvironmentInFnItem);
}
- return Def::Err;
}
ConstantItemRibKind => {
// Still doesn't deal with upvars
if record_used {
- resolve_error(self, span,
- ResolutionError::AttemptToUseNonConstantValueInConstant);
+ resolve_error(self, span, AttemptToUseNonConstantValueInConstant);
}
return Def::Err;
}
}
}
+ if let Some(res_err) = res_err {
+ resolve_error(self, span, res_err);
+ return Def::Err;
+ }
}
Def::TyParam(..) | Def::SelfTy(..) => {
for rib in ribs {
// Nothing to do. Continue.
}
ItemRibKind => {
- // This was an attempt to use a type parameter outside
- // its scope.
+ // This was an attempt to use a type parameter outside its scope.
if record_used {
- resolve_error(self, span,
- ResolutionError::TypeParametersFromOuterFunction(def));
+ resolve_error(
+ self,
+ span,
+ ResolutionError::GenericParamsFromOuterFunction(def),
+ );
}
return Def::Err;
}
}
}
}
+ Def::ConstParam(..) => {
+ // A const param is always declared in a signature, which is always followed by
+ // some kind of function rib kind (specifically, ItemRibKind in the case of a
+ // normal function), so we can skip the first rib as it will be guaranteed to
+ // (spuriously) conflict with the const param.
+ for rib in &ribs[1..] {
+ if let ItemRibKind = rib.kind {
+ // This was an attempt to use a const parameter outside its scope.
+ if record_used {
+ resolve_error(
+ self,
+ span,
+ ResolutionError::GenericParamsFromOuterFunction(def),
+ );
+ }
+ return Def::Err;
+ }
+ }
+ }
_ => {}
}
def
(variant_path_string, enum_path_string)
}
-
/// When an entity with a given name is not available in scope, we search for
/// entities with that name in all crates. This method allows outputting the
/// results of this search in a programmer-friendly way
authors = ["The Rust Project Developers"]
name = "rustc_save_analysis"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_save_analysis"
use rustc::hir::def::Def as HirDef;
use rustc::hir::def_id::DefId;
use rustc::session::config::Input;
+use rustc::span_bug;
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
};
use syntax::ptr::P;
use syntax::source_map::{Spanned, DUMMY_SP, respan};
+use syntax::walk_list;
use syntax_pos::*;
-use {escape, generated_code, lower_attributes, PathCollector, SaveContext};
-use json_dumper::{Access, DumpOutput, JsonDumper};
-use span_utils::SpanUtils;
-use sig;
+use crate::{escape, generated_code, id_from_def_id, id_from_node_id, lower_attributes,
+ PathCollector, SaveContext};
+use crate::json_dumper::{Access, DumpOutput, JsonDumper};
+use crate::span_utils::SpanUtils;
+use crate::sig;
use rls_data::{CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import,
ImportKind, Ref, RefKind, Relation, RelationKind, SpanData};
+use log::{debug, error};
+
macro_rules! down_cast_data {
($id:ident, $kind:ident, $sp:expr) => {
let $id = if let super::Data::$kind(data) = $id {
};
}
-pub struct DumpVisitor<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> {
+pub struct DumpVisitor<'l, 'tcx: 'l, 'll, O: DumpOutput> {
save_ctxt: SaveContext<'l, 'tcx>,
tcx: TyCtxt<'l, 'tcx, 'tcx>,
dumper: &'ll mut JsonDumper<O>,
None => continue,
};
if !self.span.filter_generated(ident.span) {
- let id = ::id_from_node_id(id, &self.save_ctxt);
+ let id = id_from_node_id(id, &self.save_ctxt);
let span = self.span_from_span(ident.span);
self.dumper.dump_def(
debug!("process_method: {}:{}", id, ident);
if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) {
- let sig_str = ::make_signature(&sig.decl, &generics);
+ let sig_str = crate::make_signature(&sig.decl, &generics);
if body.is_some() {
self.nest_tables(
id,
// Append $id to name to make sure each one is unique.
let qualname = format!("{}::{}${}", prefix, name, id);
if !self.span.filter_generated(param_ss) {
- let id = ::id_from_node_id(param.id, &self.save_ctxt);
+ let id = id_from_node_id(param.id, &self.save_ctxt);
let span = self.span_from_span(param_ss);
self.dumper.dump_def(
);
}
}
+ ast::GenericParamKind::Const { .. } => {}
}
}
self.visit_generics(generics);
&access_from!(self.save_ctxt, vis, id),
Def {
kind: DefKind::Const,
- id: ::id_from_node_id(id, &self.save_ctxt),
+ id: id_from_node_id(id, &self.save_ctxt),
span,
name: ident.name.to_string(),
qualname,
value: ty_to_string(&typ),
- parent: Some(::id_from_def_id(parent_id)),
+ parent: Some(id_from_def_id(parent_id)),
children: vec![],
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(attrs),
value,
fields
.iter()
- .map(|f| ::id_from_node_id(f.id, &self.save_ctxt))
+ .map(|f| id_from_node_id(f.id, &self.save_ctxt))
.collect(),
)
}
&access_from!(self.save_ctxt, item),
Def {
kind,
- id: ::id_from_node_id(item.id, &self.save_ctxt),
+ id: id_from_node_id(item.id, &self.save_ctxt),
span,
name,
qualname: qualname.clone(),
let value = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str);
if !self.span.filter_generated(name_span) {
let span = self.span_from_span(name_span);
- let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt);
- let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
+ let id = id_from_node_id(variant.node.data.id(), &self.save_ctxt);
+ let parent = Some(id_from_node_id(item.id, &self.save_ctxt));
self.dumper.dump_def(
&access,
}
if !self.span.filter_generated(name_span) {
let span = self.span_from_span(name_span);
- let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt);
- let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
+ let id = id_from_node_id(variant.node.data.id(), &self.save_ctxt);
+ let parent = Some(id_from_node_id(item.id, &self.save_ctxt));
self.dumper.dump_def(
&access,
val.push_str(&bounds_to_string(trait_refs));
}
if !self.span.filter_generated(item.ident.span) {
- let id = ::id_from_node_id(item.id, &self.save_ctxt);
+ let id = id_from_node_id(item.id, &self.save_ctxt);
let span = self.span_from_span(item.ident.span);
let children = methods
.iter()
- .map(|i| ::id_from_node_id(i.id, &self.save_ctxt))
+ .map(|i| id_from_node_id(i.id, &self.save_ctxt))
.collect();
self.dumper.dump_def(
&access_from!(self.save_ctxt, item),
self.dumper.dump_ref(Ref {
kind: RefKind::Type,
span: span.clone(),
- ref_id: ::id_from_def_id(id),
+ ref_id: id_from_def_id(id),
});
self.dumper.dump_relation(Relation {
kind: RelationKind::SuperTrait,
span,
- from: ::id_from_def_id(id),
- to: ::id_from_node_id(item.id, &self.save_ctxt),
+ from: id_from_def_id(id),
+ to: id_from_node_id(item.id, &self.save_ctxt),
});
}
}
self.dumper.dump_ref(Ref {
kind: RefKind::Variable,
span,
- ref_id: ::id_from_def_id(variant.fields[index].did),
+ ref_id: id_from_def_id(variant.fields[index].did),
});
}
}
if !self.span.filter_generated(ident.span) {
let qualname = format!("{}${}", ident.to_string(), id);
- let id = ::id_from_node_id(id, &self.save_ctxt);
+ let id = id_from_node_id(id, &self.save_ctxt);
let span = self.span_from_span(ident.span);
self.dumper.dump_def(
// Rust uses the id of the pattern for var lookups, so we'll use it too.
if !self.span.filter_generated(ident.span) {
let qualname = format!("{}${}", ident.to_string(), id);
- let id = ::id_from_node_id(id, &self.save_ctxt);
+ let id = id_from_node_id(id, &self.save_ctxt);
let span = self.span_from_span(ident.span);
self.dumper.dump_def(
if !self.span.filter_generated(trait_item.ident.span) {
let span = self.span_from_span(trait_item.ident.span);
- let id = ::id_from_node_id(trait_item.id, &self.save_ctxt);
+ let id = id_from_node_id(trait_item.id, &self.save_ctxt);
self.dumper.dump_def(
&Access {
name,
qualname,
value: self.span.snippet(trait_item.span),
- parent: Some(::id_from_def_id(trait_id)),
+ parent: Some(id_from_def_id(trait_id)),
children: vec![],
decl_id: None,
docs: self.save_ctxt.docs_for_attrs(&trait_item.attrs),
// The parent def id of a given use tree is always the enclosing item.
let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id)
.and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
- .map(::id_from_def_id);
+ .map(id_from_def_id);
match use_tree.kind {
ast::UseTreeKind::Simple(alias, ..) => {
let sub_span = path.segments.last().unwrap().ident.span;
if !self.span.filter_generated(sub_span) {
- let ref_id = self.lookup_def_id(id).map(|id| ::id_from_def_id(id));
+ let ref_id = self.lookup_def_id(id).map(|id| id_from_def_id(id));
let alias_span = alias.map(|i| self.span_from_span(i.span));
let span = self.span_from_span(sub_span);
self.dumper.import(&access, Import {
let cm = self.tcx.sess.source_map();
let filename = cm.span_to_filename(span);
- let data_id = ::id_from_node_id(id, &self.save_ctxt);
+ let data_id = id_from_node_id(id, &self.save_ctxt);
let children = m.items
.iter()
- .map(|i| ::id_from_node_id(i.id, &self.save_ctxt))
+ .map(|i| id_from_node_id(i.id, &self.save_ctxt))
.collect();
let span = self.span_from_span(span);
let span = self.span_from_span(name_span);
let parent = self.save_ctxt.tcx.hir().opt_local_def_id(item.id)
.and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
- .map(::id_from_def_id);
+ .map(id_from_def_id);
self.dumper.import(
&Access {
public: false,
let value = ty_to_string(&ty);
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
- let id = ::id_from_node_id(item.id, &self.save_ctxt);
+ let id = id_from_node_id(item.id, &self.save_ctxt);
self.dumper.dump_def(
&access_from!(self.save_ctxt, item),
let value = String::new();
if !self.span.filter_generated(item.ident.span) {
let span = self.span_from_span(item.ident.span);
- let id = ::id_from_node_id(item.id, &self.save_ctxt);
+ let id = id_from_node_id(item.id, &self.save_ctxt);
self.dumper.dump_def(
&access_from!(self.save_ctxt, item),
fn visit_generics(&mut self, generics: &'l ast::Generics) {
for param in &generics.params {
- if let ast::GenericParamKind::Type { ref default, .. } = param.kind {
- self.process_bounds(¶m.bounds);
- if let Some(ref ty) = default {
+ match param.kind {
+ ast::GenericParamKind::Lifetime { .. } => {}
+ ast::GenericParamKind::Type { ref default, .. } => {
+ self.process_bounds(¶m.bounds);
+ if let Some(ref ty) = default {
+ self.visit_ty(&ty);
+ }
+ }
+ ast::GenericParamKind::Const { ref ty } => {
+ self.process_bounds(¶m.bounds);
self.visit_ty(&ty);
}
}
self.dumper.dump_ref(Ref {
kind: RefKind::Type,
span,
- ref_id: ::id_from_def_id(id),
+ ref_id: id_from_def_id(id),
});
}
MacroRef, Ref, RefKind, Relation};
use rls_span::{Column, Row};
+use log::error;
+
#[derive(Debug)]
pub struct Access {
pub reachable: bool,
fn dump(&mut self, result: &Analysis);
}
-pub struct WriteOutput<'b, W: Write + 'b> {
+pub struct WriteOutput<'b, W: Write> {
output: &'b mut W,
}
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(custom_attribute)]
-#![feature(nll)]
+#![deny(rust_2018_idioms)]
#![allow(unused_attributes)]
#![recursion_limit="256"]
-#[macro_use]
-extern crate rustc;
-
-#[macro_use]
-extern crate log;
-extern crate rustc_data_structures;
-extern crate rustc_codegen_utils;
-extern crate rustc_serialize;
-extern crate rustc_target;
-extern crate rustc_typeck;
-#[macro_use]
-extern crate syntax;
-extern crate syntax_pos;
-
-extern crate rls_data;
-extern crate rls_span;
-
mod json_dumper;
mod dump_visitor;
use rustc::middle::cstore::ExternCrate;
use rustc::session::config::{CrateType, Input, OutputType};
use rustc::ty::{self, TyCtxt};
+use rustc::{bug, span_bug};
use rustc_typeck::hir_ty_to_ty;
use rustc_codegen_utils::link::{filename_for_metadata, out_filename};
use rustc_data_structures::sync::Lrc;
RelationKind, SpanData, Impl, ImplKind};
use rls_data::config::Config;
+use log::{debug, error, info};
+
pub struct SaveContext<'l, 'tcx: 'l> {
tcx: TyCtxt<'l, 'tcx, 'tcx>,
ast::ForeignItemKind::Static(ref ty, _) => {
filter!(self.span_utils, item.ident.span);
- let id = ::id_from_node_id(item.id, self);
+ let id = id_from_node_id(item.id, self);
let span = self.span_from_span(item.ident.span);
Some(Data::DefData(Def {
ref_id: id_from_def_id(def_id),
})
}
+ HirDef::ConstParam(def_id) => {
+ Some(Ref {
+ kind: RefKind::Variable,
+ span,
+ ref_id: id_from_def_id(def_id),
+ })
+ }
HirDef::StructCtor(def_id, _) => {
// This is a reference to a tuple struct where the def_id points
// to an invisible constructor function. That is not a very useful
}
}
- fn output_file(&self, ctx: &SaveContext) -> File {
+ fn output_file(&self, ctx: &SaveContext<'_, '_>) -> File {
let sess = &ctx.tcx.sess;
let file_name = match ctx.config.output_file {
Some(ref s) => PathBuf::from(s),
}
}
-fn id_from_node_id(id: NodeId, scx: &SaveContext) -> rls_data::Id {
+fn id_from_node_id(id: NodeId, scx: &SaveContext<'_, '_>) -> rls_data::Id {
let def_id = scx.tcx.hir().opt_local_def_id(id);
def_id.map(|id| id_from_def_id(id)).unwrap_or_else(|| {
// Create a *fake* `DefId` out of a `NodeId` by subtracting the `NodeId`
}
}
-fn lower_attributes(attrs: Vec<Attribute>, scx: &SaveContext) -> Vec<rls_data::Attribute> {
+fn lower_attributes(attrs: Vec<Attribute>, scx: &SaveContext<'_, '_>) -> Vec<rls_data::Attribute> {
attrs.into_iter()
// Only retain real attributes. Doc comments are lowered separately.
.filter(|attr| attr.path != "doc")
//
// FIXME where clauses need implementing, defs/refs in generics are mostly missing.
-use {id_from_def_id, id_from_node_id, SaveContext};
+use crate::{id_from_def_id, id_from_node_id, SaveContext};
use rls_data::{SigElement, Signature};
use syntax::print::pprust;
-pub fn item_signature(item: &ast::Item, scx: &SaveContext) -> Option<Signature> {
+pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
if !scx.config.signatures {
return None;
}
item.make(0, None, scx).ok()
}
-pub fn foreign_item_signature(item: &ast::ForeignItem, scx: &SaveContext) -> Option<Signature> {
+pub fn foreign_item_signature(
+ item: &ast::ForeignItem,
+ scx: &SaveContext<'_, '_>
+) -> Option<Signature> {
if !scx.config.signatures {
return None;
}
/// Signature for a struct or tuple field declaration.
/// Does not include a trailing comma.
-pub fn field_signature(field: &ast::StructField, scx: &SaveContext) -> Option<Signature> {
+pub fn field_signature(field: &ast::StructField, scx: &SaveContext<'_, '_>) -> Option<Signature> {
if !scx.config.signatures {
return None;
}
}
/// Does not include a trailing comma.
-pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext) -> Option<Signature> {
+pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext<'_, '_>) -> Option<Signature> {
if !scx.config.signatures {
return None;
}
ident: ast::Ident,
generics: &ast::Generics,
m: &ast::MethodSig,
- scx: &SaveContext,
+ scx: &SaveContext<'_, '_>,
) -> Option<Signature> {
if !scx.config.signatures {
return None;
ident: ast::Name,
ty: &ast::Ty,
default: Option<&ast::Expr>,
- scx: &SaveContext,
+ scx: &SaveContext<'_, '_>,
) -> Option<Signature> {
if !scx.config.signatures {
return None;
ident: ast::Ident,
bounds: Option<&ast::GenericBounds>,
default: Option<&ast::Ty>,
- scx: &SaveContext,
+ scx: &SaveContext<'_, '_>,
) -> Option<Signature> {
if !scx.config.signatures {
return None;
make_assoc_type_signature(id, ident, bounds, default, scx).ok()
}
-type Result = ::std::result::Result<Signature, &'static str>;
+type Result = std::result::Result<Signature, &'static str>;
trait Sig {
- fn make(&self, offset: usize, id: Option<NodeId>, scx: &SaveContext) -> Result;
+ fn make(&self, offset: usize, id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result;
}
fn extend_sig(
}
impl Sig for ast::Ty {
- fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
+ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let id = Some(self.id);
match self.node {
ast::TyKind::Slice(ref ty) => {
if f.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe ");
}
- if f.abi != ::rustc_target::spec::abi::Abi::Rust {
+ if f.abi != rustc_target::spec::abi::Abi::Rust {
text.push_str("extern");
text.push_str(&f.abi.to_string());
text.push(' ');
}
impl Sig for ast::Item {
- fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
+ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let id = Some(self.id);
match self.node {
if header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe ");
}
- if header.abi != ::rustc_target::spec::abi::Abi::Rust {
+ if header.abi != rustc_target::spec::abi::Abi::Rust {
text.push_str("extern");
text.push_str(&header.abi.to_string());
text.push(' ');
}
impl Sig for ast::Path {
- fn make(&self, offset: usize, id: Option<NodeId>, scx: &SaveContext) -> Result {
+ fn make(&self, offset: usize, id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let def = scx.get_path_def(id.ok_or("Missing id for Path")?);
let (name, start, end) = match def {
// This does not cover the where clause, which must be processed separately.
impl Sig for ast::Generics {
- fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
+ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
if self.params.is_empty() {
return Ok(text_sig(String::new()));
}
let mut defs = Vec::with_capacity(self.params.len());
for param in &self.params {
- let mut param_text = param.ident.to_string();
+ let mut param_text = String::new();
+ if let ast::GenericParamKind::Const { .. } = param.kind {
+ param_text.push_str("const ");
+ }
+ param_text.push_str(¶m.ident.as_str());
defs.push(SigElement {
id: id_from_node_id(param.id, scx),
start: offset + text.len(),
- end: offset + text.len() + param_text.len(),
+ end: offset + text.len() + param_text.as_str().len(),
});
+ if let ast::GenericParamKind::Const { ref ty } = param.kind {
+ param_text.push_str(": ");
+ param_text.push_str(&pprust::ty_to_string(&ty));
+ }
if !param.bounds.is_empty() {
param_text.push_str(": ");
match param.kind {
param_text.push_str(&pprust::bounds_to_string(¶m.bounds));
// FIXME descend properly into bounds.
}
+ ast::GenericParamKind::Const { .. } => {
+ // Const generics cannot contain bounds.
+ }
}
}
text.push_str(¶m_text);
}
impl Sig for ast::StructField {
- fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
+ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let mut text = String::new();
let mut defs = None;
if let Some(ident) = self.ident {
impl Sig for ast::Variant_ {
- fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
+ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let mut text = self.ident.to_string();
match self.data {
ast::VariantData::Struct(ref fields, id) => {
}
impl Sig for ast::ForeignItem {
- fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> Result {
+ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let id = Some(self.id);
match self.node {
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
generics: &ast::Generics,
id: NodeId,
name: ast::Ident,
- scx: &SaveContext,
+ scx: &SaveContext<'_, '_>,
) -> Result {
let name = name.to_string();
let def = SigElement {
ident: ast::Ident,
bounds: Option<&ast::GenericBounds>,
default: Option<&ast::Ty>,
- scx: &SaveContext,
+ scx: &SaveContext<'_, '_>,
) -> Result {
let mut text = "type ".to_owned();
let name = ident.to_string();
ident: ast::Name,
ty: &ast::Ty,
default: Option<&ast::Expr>,
- scx: &SaveContext,
+ scx: &SaveContext<'_, '_>,
) -> Result {
let mut text = "const ".to_owned();
let name = ident.to_string();
ident: ast::Ident,
generics: &ast::Generics,
m: &ast::MethodSig,
- scx: &SaveContext,
+ scx: &SaveContext<'_, '_>,
) -> Result {
// FIXME code dup with function signature
let mut text = String::new();
if m.header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe ");
}
- if m.header.abi != ::rustc_target::spec::abi::Abi::Rust {
+ if m.header.abi != rustc_target::spec::abi::Abi::Rust {
text.push_str("extern");
text.push_str(&m.header.abi.to_string());
text.push(' ');
use rustc::session::Session;
-use generated_code;
+use crate::generated_code;
use std::cell::Cell;
authors = ["The Rust Project Developers"]
name = "rustc_target"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_target"
-use abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
-use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
-> Option<Uniform>
-use abi::call::{ArgType, FnType, };
-use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::call::{ArgType, FnType, };
+use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
fn classify_ret_ty<'a, Ty, C>(_cx: &C, ret: &mut ArgType<'a, Ty>)
where Ty: TyLayoutMethods<'a, C> + Copy,
-use abi::call::{Conv, FnType, ArgType, Reg, RegKind, Uniform};
-use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-use spec::HasTargetSpec;
+use crate::abi::call::{Conv, FnType, ArgType, Reg, RegKind, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::spec::HasTargetSpec;
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
-> Option<Uniform>
-use abi::call::{FnType, ArgType, Uniform};
-use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::call::{FnType, ArgType, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128
}
}
-fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>) {
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
if arg.layout.is_aggregate() {
arg.make_indirect_byval();
}
#![allow(non_upper_case_globals)]
-use abi::call::{FnType, ArgType};
+use crate::abi::call::{FnType, ArgType};
-fn classify_ret_ty<Ty>(ret: &mut ArgType<Ty>) {
+fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
ret.make_indirect();
} else {
}
}
-fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>) {
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
arg.make_indirect();
} else {
}
}
-pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>) {
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_,Ty>) {
if !fty.ret.is_ignore() {
classify_ret_ty(&mut fty.ret);
}
-use abi::call::{ArgType, FnType, Reg, Uniform};
-use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
+use crate::abi::call::{ArgType, FnType, Reg, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'_, Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
if !ret.layout.is_aggregate() {
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'_, Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let dl = cx.data_layout();
*offset = offset.align_to(align) + size.align_to(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'_, Ty>)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let mut offset = Size::ZERO;
-use abi::call::{ArgAttribute, ArgType, CastTarget, FnType, PassMode, Reg, RegKind, Uniform};
-use abi::{self, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
+use crate::abi::call::{ArgAttribute, ArgType, CastTarget, FnType, PassMode, Reg, RegKind, Uniform};
+use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
-fn extend_integer_width_mips<Ty>(arg: &mut ArgType<Ty>, bits: u64) {
+fn extend_integer_width_mips<Ty>(arg: &mut ArgType<'_, Ty>, bits: u64) {
// Always sign extend u32 values on 64-bit mips
if let abi::Abi::Scalar(ref scalar) = arg.layout.abi {
if let abi::Int(i, signed) = scalar.value {
-use abi::{self, Abi, Align, FieldPlacement, Size};
-use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-use spec::HasTargetSpec;
+use crate::abi::{self, Abi, Align, FieldPlacement, Size};
+use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::spec::{self, HasTargetSpec};
mod aarch64;
mod amdgpu;
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
// of this module
-pub use self::attr_impl::ArgAttribute;
+pub use attr_impl::ArgAttribute;
#[allow(non_upper_case_globals)]
#[allow(unused)]
mod attr_impl {
// The subset of llvm::Attribute needed for arguments, packed into a bitfield.
- bitflags! {
+ bitflags::bitflags! {
#[derive(Default)]
pub struct ArgAttribute: u16 {
const ByVal = 1 << 0;
}
impl<'a, Ty> FnType<'a, Ty> {
- pub fn adjust_for_cabi<C>(&mut self, cx: &C, abi: ::spec::abi::Abi) -> Result<(), String>
+ pub fn adjust_for_cabi<C>(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String>
where Ty: TyLayoutMethods<'a, C> + Copy,
C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout + HasTargetSpec
{
match &cx.target_spec().arch[..] {
"x86" => {
- let flavor = if abi == ::spec::abi::Abi::Fastcall {
+ let flavor = if abi == spec::abi::Abi::Fastcall {
x86::Flavor::Fastcall
} else {
x86::Flavor::General
};
x86::compute_abi_info(cx, self, flavor);
},
- "x86_64" => if abi == ::spec::abi::Abi::SysV64 {
+ "x86_64" => if abi == spec::abi::Abi::SysV64 {
x86_64::compute_abi_info(cx, self);
- } else if abi == ::spec::abi::Abi::Win64 || cx.target_spec().options.is_like_windows {
+ } else if abi == spec::abi::Abi::Win64 || cx.target_spec().options.is_like_windows {
x86_win64::compute_abi_info(self);
} else {
x86_64::compute_abi_info(cx, self);
// Reference: MSP430 Embedded Application Binary Interface
// http://www.ti.com/lit/an/slaa534/slaa534.pdf
-use abi::call::{ArgType, FnType};
+use crate::abi::call::{ArgType, FnType};
// 3.5 Structures or Unions Passed and Returned by Reference
//
// returned by reference. To pass a structure or union by reference, the caller
// places its address in the appropriate location: either in a register or on
// the stack, according to its position in the argument list. (..)"
-fn classify_ret_ty<Ty>(ret: &mut ArgType<Ty>) {
+fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
if ret.layout.is_aggregate() && ret.layout.size.bits() > 32 {
ret.make_indirect();
} else {
}
}
-fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>) {
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 {
arg.make_indirect();
} else {
}
}
-pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>) {
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
if !fty.ret.is_ignore() {
classify_ret_ty(&mut fty.ret);
}
// Reference: PTX Writer's Guide to Interoperability
// http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability
-use abi::call::{ArgType, FnType};
+use crate::abi::call::{ArgType, FnType};
-fn classify_ret_ty<Ty>(ret: &mut ArgType<Ty>) {
+fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
if ret.layout.is_aggregate() && ret.layout.size.bits() > 32 {
ret.make_indirect();
} else {
}
}
-fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>) {
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
if arg.layout.is_aggregate() && arg.layout.size.bits() > 32 {
arg.make_indirect();
} else {
}
}
-pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>) {
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
if !fty.ret.is_ignore() {
classify_ret_ty(&mut fty.ret);
}
// Reference: PTX Writer's Guide to Interoperability
// http://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability
-use abi::call::{ArgType, FnType};
+use crate::abi::call::{ArgType, FnType};
-fn classify_ret_ty<Ty>(ret: &mut ArgType<Ty>) {
+fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
ret.make_indirect();
} else {
}
}
-fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>) {
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
arg.make_indirect();
} else {
}
}
-pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>) {
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
if !fty.ret.is_ignore() {
classify_ret_ty(&mut fty.ret);
}
-use abi::call::{ArgType, FnType, Reg, Uniform};
-use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
+use crate::abi::call::{ArgType, FnType, Reg, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'_, Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
if !ret.layout.is_aggregate() {
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'_, Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let dl = cx.data_layout();
*offset = offset.align_to(align) + size.align_to(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'_, Ty>)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let mut offset = Size::ZERO;
// Alignment of 128 bit types is not currently handled, this will
// need to be fixed when PowerPC vector support is added.
-use abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
-use abi::{Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-use spec::HasTargetSpec;
+use crate::abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
+use crate::abi::{Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::spec::HasTargetSpec;
#[derive(Debug, Clone, Copy, PartialEq)]
enum ABI {
ELFv1, // original ABI used for powerpc64 (big-endian)
ELFv2, // newer ABI used for powerpc64le and musl (both endians)
}
-use self::ABI::*;
+use ABI::*;
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI)
-> Option<Uniform>
// Reference: RISC-V ELF psABI specification
// https://github.com/riscv/riscv-elf-psabi-doc
-use abi::call::{ArgType, FnType};
+use crate::abi::call::{ArgType, FnType};
-fn classify_ret_ty<Ty>(arg: &mut ArgType<Ty>, xlen: u64) {
+fn classify_ret_ty<Ty>(arg: &mut ArgType<'_, Ty>, xlen: u64) {
// "Scalars wider than 2✕XLEN are passed by reference and are replaced in
// the argument list with the address."
// "Aggregates larger than 2✕XLEN bits are passed by reference and are
arg.extend_integer_width_to(xlen); // this method only affects integer scalars
}
-fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>, xlen: u64) {
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>, xlen: u64) {
// "Scalars wider than 2✕XLEN are passed by reference and are replaced in
// the argument list with the address."
// "Aggregates larger than 2✕XLEN bits are passed by reference and are
arg.extend_integer_width_to(xlen); // this method only affects integer scalars
}
-pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>, xlen: u64) {
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>, xlen: u64) {
if !fty.ret.is_ignore() {
classify_ret_ty(&mut fty.ret, xlen);
}
// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
// for a pre-z13 machine or using -mno-vx.
-use abi::call::{FnType, ArgType, Reg};
-use abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::call::{FnType, ArgType, Reg};
+use crate::abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(ret: &mut ArgType<Ty>)
+fn classify_ret_ty<'a, Ty, C>(ret: &mut ArgType<'_, Ty>)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
-use abi::call::{ArgType, FnType, Reg, Uniform};
-use abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
+use crate::abi::call::{ArgType, FnType, Reg, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
-fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'_, Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
if !ret.layout.is_aggregate() {
}
}
-fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<Ty>, offset: &mut Size)
+fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'_, Ty>, offset: &mut Size)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let dl = cx.data_layout();
*offset = offset.align_to(align) + size.align_to(align);
}
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<Ty>)
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'_, Ty>)
where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
{
let mut offset = Size::ZERO;
// FIXME: This needs an audit for correctness and completeness.
-use abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
-use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::call::{FnType, ArgType, Reg, RegKind, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
-> Option<Uniform>
-use abi::call::{FnType, ArgType};
+use crate::abi::call::{FnType, ArgType};
-fn classify_ret_ty<Ty>(ret: &mut ArgType<Ty>) {
+fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
ret.extend_integer_width_to(32);
}
-fn classify_arg_ty<Ty>(arg: &mut ArgType<Ty>) {
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
arg.extend_integer_width_to(32);
}
-pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>) {
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
if !fty.ret.is_ignore() {
classify_ret_ty(&mut fty.ret);
}
-use abi::call::{ArgAttribute, FnType, PassMode, Reg, RegKind};
-use abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
-use spec::HasTargetSpec;
+use crate::abi::call::{ArgAttribute, FnType, PassMode, Reg, RegKind};
+use crate::abi::{self, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::spec::HasTargetSpec;
#[derive(PartialEq)]
pub enum Flavor {
// The classification code for the x86_64 ABI is taken from the clay language
// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
-use abi::call::{ArgType, CastTarget, FnType, Reg, RegKind};
-use abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
+use crate::abi::call::{ArgType, CastTarget, FnType, Reg, RegKind};
+use crate::abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyLayout, TyLayoutMethods};
/// Classification of "eightbyte" components.
// N.B., the order of the variants is from general to specific,
-use abi::call::{ArgType, FnType, Reg};
-use abi::Abi;
+use crate::abi::call::{ArgType, FnType, Reg};
+use crate::abi::Abi;
// Win64 ABI: http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
-pub fn compute_abi_info<Ty>(fty: &mut FnType<Ty>) {
- let fixup = |a: &mut ArgType<Ty>| {
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
+ let fixup = |a: &mut ArgType<'_, Ty>| {
match a.layout.abi {
Abi::Uninhabited => {}
Abi::ScalarPair(..) |
-pub use self::Integer::*;
-pub use self::Primitive::*;
+pub use Integer::*;
+pub use Primitive::*;
-use spec::Target;
+use crate::spec::Target;
use std::fmt;
use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive};
}
impl fmt::Debug for FloatTy {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for FloatTy {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ty_to_string())
}
}
#![feature(slice_patterns)]
#![feature(step_trait)]
-#[macro_use]
-extern crate bitflags;
-extern crate serialize;
+#![deny(rust_2018_idioms)]
+
#[macro_use] extern crate log;
+#[allow(unused_extern_crates)]
extern crate serialize as rustc_serialize; // used by deriving
// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
use super::apple_ios_base::{opts, Arch};
pub fn target() -> TargetResult {
-use spec::{LldFlavor, LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LldFlavor, LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::fuchsia_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
// See https://developer.android.com/ndk/guides/abis.html#arm64-v8a
// for target ABI requirements.
-use spec::{LinkerFlavor, Target, TargetResult, PanicStrategy};
+use crate::spec::{LinkerFlavor, Target, TargetResult, PanicStrategy};
pub fn target() -> TargetResult {
let mut base = super::windows_msvc_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::freebsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::hermit_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::openbsd_base::opts();
}
impl fmt::Display for Abi {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\"{}\"", self.name())
}
}
-use spec::{LinkerFlavor, TargetOptions};
+use crate::spec::{LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
use std::env;
-use spec::{LinkArgs, TargetOptions};
+use crate::spec::{LinkArgs, TargetOptions};
pub fn opts() -> TargetOptions {
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
use std::io;
use std::process::Command;
-use spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
-use self::Arch::*;
+use Arch::*;
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
-use spec::abi::Abi;
+use crate::spec::abi::Abi;
// All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
pub fn abi_blacklist() -> Vec<Abi> {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::android_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
// Targets the Big endian Cortex-R4/R5 processor (ARMv7-R)
use std::default::Default;
-use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
// Targets the Cortex-R4F/R5F processor (ARMv7-R)
use std::default::Default;
-use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
use super::apple_ios_base::{opts, Arch};
pub fn target() -> TargetResult {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
// This target if is for the baseline of the Android v7a ABI
// in thumb mode. It's named armv7-* instead of thumbv7-*
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
// This target is for glibc Linux on ARMv7 without NEON or
// thumb-mode. See the thumbv7neon variant for enabling both.
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
// This target is for musl Linux on ARMv7 without thumb-mode or NEON.
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let base = super::netbsd_base::opts();
// Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R)
use std::default::Default;
-use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
// Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R)
use std::default::Default;
-use spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
use super::apple_ios_base::{opts, Arch};
pub fn target() -> TargetResult {
-use spec::{TargetOptions, RelroLevel};
+use crate::spec::{TargetOptions, RelroLevel};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
pub fn opts() -> TargetOptions {
let mut args = LinkArgs::new();
-use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LldFlavor, LinkArgs, LinkerFlavor, TargetOptions};
+use crate::spec::{LldFlavor, LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{TargetOptions, RelroLevel};
+use crate::spec::{TargetOptions, RelroLevel};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
use super::apple_ios_base::{opts, Arch};
pub fn target() -> TargetResult {
-use spec::TargetResult;
+use crate::spec::TargetResult;
pub fn target() -> TargetResult {
let mut base = super::i686_pc_windows_msvc::target()?;
-use spec::TargetResult;
+use crate::spec::TargetResult;
pub fn target() -> TargetResult {
let mut base = super::i686_unknown_linux_gnu::target()?;
-use spec::TargetResult;
+use crate::spec::TargetResult;
pub fn target() -> TargetResult {
let mut base = super::i686_unknown_linux_musl::target()?;
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::apple_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
// See https://developer.android.com/ndk/guides/abis.html#x86
// for target ABI requirements.
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::windows_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::windows_msvc_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::dragonfly_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::freebsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::haiku_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::openbsd_base::opts();
-use spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
use std::default::Default;
//use std::process::Command;
-use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkerFlavor, TargetOptions};
+use crate::spec::{LinkerFlavor, TargetOptions};
pub fn opts() -> TargetOptions {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
use std::{fmt, io};
use std::path::{Path, PathBuf};
use std::str::FromStr;
-use spec::abi::{Abi, lookup as lookup_abi};
+use crate::spec::abi::{Abi, lookup as lookup_abi};
pub mod abi;
mod android_base;
}
impl fmt::Display for TargetTriple {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.debug_triple())
}
}
-use spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy, MergeFunctions};
-use spec::abi::Abi;
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy, MergeFunctions};
+use crate::spec::abi::Abi;
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::freebsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult, RelroLevel};
+use crate::spec::{LinkerFlavor, Target, TargetResult, RelroLevel};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
-use spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkerFlavor, LldFlavor, PanicStrategy,
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy,
Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
-use spec::{LinkerFlavor, LldFlavor, PanicStrategy,
+use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy,
Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
-use spec::abi::Abi;
+use crate::spec::abi::Abi;
// All the calling conventions trigger an assertion(Unsupported calling
// convention) in llvm on RISCV
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::TargetOptions;
+use crate::spec::TargetOptions;
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::solaris_base::opts();
// build scripts / gcc flags.
use std::default::Default;
-use spec::{PanicStrategy, TargetOptions};
+use crate::spec::{PanicStrategy, TargetOptions};
pub fn opts() -> TargetOptions {
// See rust-lang/rfcs#1645 for a discussion about these defaults
// Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture)
-use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult, PanicStrategy};
pub fn target() -> TargetResult {
let mut base = super::windows_msvc_base::opts();
// To opt-in to hardware accelerated floating point operations, you can use, for example,
// `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`.
-use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
//
// To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag.
-use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
// Targets the Cortex-M3 processor (ARMv7-M)
-use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
// This target if is for the Android v7a ABI in thumb mode with
// NEON unconditionally enabled and, therefore, with 32 FPU registers
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
// This target is for glibc Linux on ARMv7 with thumb mode enabled
// (for consistency with Android and Debian-based distributions)
// Targets the Cortex-M23 processor (Baseline ARMv8-M)
-use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
// Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile),
// without the Floating Point extension.
-use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
// Targets the Cortex-M33 processor (Armv8-M Mainline architecture profile),
// with the Floating Point extension.
-use spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
Ok(Target {
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
// code runs in the same environment, no process separation is supported.
-use spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
use std::default::Default;
pub fn opts() -> TargetOptions {
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::apple_base::opts();
-use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
use super::apple_ios_base::{opts, Arch};
pub fn target() -> TargetResult {
-use spec::{LldFlavor, LinkerFlavor, Target, TargetResult};
+use crate::spec::{LldFlavor, LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::fuchsia_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::android_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::windows_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::windows_msvc_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::solaris_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::bitrig_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::dragonfly_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::freebsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::haiku_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::hermit_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::l4re_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::openbsd_base::opts();
-use spec::{LinkerFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::redox_base::opts();
// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
-use spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::uefi_base::opts();
authors = ["The Rust Project Developers"]
name = "rustc_traits"
version = "0.0.0"
+edition = "2018"
[lib]
name = "rustc_traits"
type ChalkExClause<'tcx> = ExClause<ChalkArenas<'tcx>>;
impl Debug for ChalkContext<'cx, 'gcx> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ChalkContext")
}
}
impl Debug for ChalkInferenceContext<'cx, 'gcx, 'tcx> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ChalkInferenceContext")
}
}
}
}
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
evaluate_goal,
..*p
def_id: sized_trait,
substs: tcx.mk_substs_trait(ty, ty::List::empty()),
};
- let sized_implemented: DomainGoal = ty::TraitPredicate {
+ let sized_implemented: DomainGoal<'_> = ty::TraitPredicate {
trait_ref: sized_implemented
}.lower();
def_id: sized_trait,
substs: tcx.mk_substs_trait(ty, ty::List::empty()),
};
- let sized_implemented: DomainGoal = ty::TraitPredicate {
+ let sized_implemented: DomainGoal<'_> = ty::TraitPredicate {
trait_ref: sized_implemented
}.lower();
mutbl,
});
- let _outlives: DomainGoal = ty::OutlivesPredicate(ty, region).lower();
+ let _outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
let wf_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(ref_ty)),
hypotheses: ty::List::empty(),
use rustc_data_structures::sync::Lrc;
use syntax::source_map::{Span, DUMMY_SP};
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
dropck_outlives,
adt_dtorck_constraint,
let mut result = def.all_fields()
.map(|field| tcx.type_of(field.did))
.map(|fty| dtorck_constraint_for_ty(tcx, span, fty, 0, fty))
- .collect::<Result<DtorckConstraint, NoSolution>>()?;
+ .collect::<Result<DtorckConstraint<'_>, NoSolution>>()?;
result.outlives.extend(tcx.destructor_constraints(def));
dedup_dtorck_constraint(&mut result);
use rustc::ty::{ParamEnvAnd, TyCtxt};
use syntax::source_map::DUMMY_SP;
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
evaluate_obligation,
..*p
use rustc_data_structures::sync::Lrc;
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
implied_outlives_bounds,
..*p
//! New recursive solver modeled on Chalk's recursive solver. Most of
//! the guts are broken up into modules; see the comments in those modules.
+#![deny(rust_2018_idioms)]
+
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![recursion_limit="256"]
-extern crate chalk_engine;
#[macro_use]
extern crate log;
#[macro_use]
extern crate rustc;
-extern crate rustc_data_structures;
-extern crate rustc_target;
-extern crate syntax;
-extern crate syntax_pos;
-extern crate smallvec;
mod chalk_context;
mod dropck_outlives;
use rustc::ty::query::Providers;
-pub fn provide(p: &mut Providers) {
+pub fn provide(p: &mut Providers<'_>) {
dropck_outlives::provide(p);
evaluate_obligation::provide(p);
implied_outlives_bounds::provide(p);
use std::iter;
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
program_clauses_for,
program_clauses_for_env: environment::program_clauses_for_env,
};
// `Implemented(Self: Trait<P1..Pn>)`
- let impl_trait: DomainGoal = trait_pred.lower();
+ let impl_trait: DomainGoal<'_> = trait_pred.lower();
// `FromEnv(Self: Trait<P1..Pn>)`
let from_env_goal = tcx.mk_goal(impl_trait.into_from_env_goal().into_goal());
let ty = tcx.type_of(item_id);
// `Implemented(A0: Trait<A1..An>)`
- let trait_implemented: DomainGoal = ty::TraitPredicate { trait_ref }.lower();
+ let trait_implemented: DomainGoal<'_> = ty::TraitPredicate { trait_ref }.lower();
// `<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm>`
let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.ident);
use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt};
use std::sync::atomic::Ordering;
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
normalize_ty_after_erasing_regions,
..*p
use syntax::ast::DUMMY_NODE_ID;
use syntax_pos::DUMMY_SP;
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
normalize_projection_ty,
..*p
use syntax::ast;
use syntax_pos::DUMMY_SP;
-crate fn provide(p: &mut Providers) {
+crate fn provide(p: &mut Providers<'_>) {
*p = Providers {
type_op_ascribe_user_type,
type_op_eq,
let length_def_id = tcx.hir().local_def_id(length.id);
let substs = Substs::identity_for_item(tcx, length_def_id);
let length = ty::LazyConst::Unevaluated(length_def_id, substs);
- let length = tcx.intern_lazy_const(length);
+ let length = tcx.mk_lazy_const(length);
let array_ty = tcx.mk_ty(ty::Array(self.ast_ty_to_ty(&ty), length));
self.normalize_ty(ast_ty.span, array_ty)
}
#[derive(Debug)]
struct Candidate<'tcx> {
+ // Candidates are (I'm not quite sure, but they are mostly) basically
+ // some metadata on top of a `ty::AssociatedItem` (without substs).
+ //
+ // However, method probing wants to be able to evaluate the predicates
+ // for a function with the substs applied - for example, if a function
+ // has `where Self: Sized`, we don't want to consider it unless `Self`
+ // is actually `Sized`, and similarly, return-type suggestions want
+ // to consider the "actual" return type.
+ //
+ // The way this is handled is through `xform_self_ty`. It contains
+ // the receiver type of this candidate, but `xform_self_ty`,
+ // `xform_ret_ty` and `kind` (which contains the predicates) have the
+ // generic parameters of this candidate substituted with the *same set*
+ // of inference variables, which acts as some weird sort of "query".
+ //
+ // When we check out a candidate, we require `xform_self_ty` to be
+ // a subtype of the passed-in self-type, and this equates the type
+ // variables in the rest of the fields.
+ //
+ // For example, if we have this candidate:
+ // ```
+ // trait Foo {
+ // fn foo(&self) where Self: Sized;
+ // }
+ // ```
+ //
+ // Then `xform_self_ty` will be `&'erased ?X` and `kind` will contain
+ // the predicate `?X: Sized`, so if we are evaluating `Foo` for a
+ // the receiver `&T`, we'll do the subtyping which will make `?X`
+ // get the right value, then when we evaluate the predicate we'll check
+ // if `T: Sized`.
xform_self_ty: Ty<'tcx>,
xform_ret_ty: Option<Ty<'tcx>>,
item: ty::AssociatedItem,
match self_ty.value.value.sty {
ty::Dynamic(ref data, ..) => {
if let Some(p) = data.principal() {
- let InferOk { value: instantiated_self_ty, obligations: _ } =
- self.fcx.probe_instantiate_query_response(
- self.span, &self.orig_steps_var_values, self_ty)
- .unwrap_or_else(|_| {
- span_bug!(self.span, "{:?} was applicable but now isn't?", self_ty)
- });
- self.assemble_inherent_candidates_from_object(instantiated_self_ty);
+ // Subtle: we can't use `instantiate_query_response` here: using it will
+ // commit to all of the type equalities assumed by inference going through
+ // autoderef (see the `method-probe-no-guessing` test).
+ //
+ // However, in this code, it is OK if we end up with an object type that is
+ // "more general" than the object type that we are evaluating. For *every*
+ // object type `MY_OBJECT`, a function call that goes through a trait-ref
+ // of the form `<MY_OBJECT as SuperTraitOf(MY_OBJECT)>::func` is a valid
+ // `ObjectCandidate`, and it should be discoverable "exactly" through one
+ // of the iterations in the autoderef loop, so there is no problem with it
+ // being discoverable in another one of these iterations.
+ //
+ // Using `instantiate_canonical_with_fresh_inference_vars` on our
+ // `Canonical<QueryResponse<Ty<'tcx>>>` and then *throwing away* the
+ // `CanonicalVarValues` will exactly give us such a generalization - it
+ // will still match the original object type, but it won't pollute our
+ // type variables in any form, so just do that!
+ let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) =
+ self.fcx.instantiate_canonical_with_fresh_inference_vars(
+ self.span, &self_ty);
+
+ self.assemble_inherent_candidates_from_object(generalized_self_ty);
self.assemble_inherent_impl_candidates_for_type(p.def_id());
}
}
if element_ty.references_error() {
tcx.types.err
} else if let Ok(count) = count {
- tcx.mk_ty(ty::Array(t, tcx.intern_lazy_const(ty::LazyConst::Evaluated(count))))
+ tcx.mk_ty(ty::Array(t, tcx.mk_lazy_const(ty::LazyConst::Evaluated(count))))
} else {
tcx.types.err
}
"##,
E0044: r##"
-You can't use type parameters on foreign items. Example of erroneous code:
+You can't use type or const parameters on foreign items.
+Example of erroneous code:
```compile_fail,E0044
extern { fn some_func<T>(x: T); }
```
-To fix this, replace the type parameter with the specializations that you
+To fix this, replace the generic parameter with the specializations that you
need:
```
} else if (action === "hide") {
addClass(relatedDoc, "fns-now-collapsed");
addClass(docblock, "hidden-by-usual-hider");
- onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule);
+ onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule));
onEachLazy(relatedDoc.childNodes, implHider(true, dontApplyBlockRule));
}
}
pub enum GenericArg {
Lifetime(Lifetime),
Type(P<Ty>),
+ Const(AnonConst),
+}
+
+impl GenericArg {
+ pub fn span(&self) -> Span {
+ match self {
+ GenericArg::Lifetime(lt) => lt.ident.span,
+ GenericArg::Type(ty) => ty.span,
+ GenericArg::Const(ct) => ct.value.span,
+ }
+ }
}
/// A path like `Foo<'a, T>`
pub type GenericBounds = Vec<GenericBound>;
+/// Specifies the enforced ordering for generic parameters. In the future,
+/// if we wanted to relax this order, we could override `PartialEq` and
+/// `PartialOrd`, to allow the kinds to be unordered.
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
+pub enum ParamKindOrd {
+ Lifetime,
+ Type,
+ Const,
+}
+
+impl fmt::Display for ParamKindOrd {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ ParamKindOrd::Lifetime => "lifetime".fmt(f),
+ ParamKindOrd::Type => "type".fmt(f),
+ ParamKindOrd::Const => "const".fmt(f),
+ }
+ }
+}
+
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum GenericParamKind {
/// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
Lifetime,
- Type {
- default: Option<P<Ty>>,
- },
+ Type { default: Option<P<Ty>> },
+ Const { ty: P<Ty> },
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
/// Usage of `?` as a macro separator is deprecated.
QuestionMarkMacroSep,
IllFormedAttributeInput,
+ /// Usage of a duplicate macro matcher binding name.
+ DuplicateMacroMatcherBindingName,
}
/// Stores buffered lint info which can later be passed to `librustc`.
bindings: Vec<ast::TypeBinding>)
-> (ast::QSelf, ast::Path);
- // types
+ // types and consts
fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
fn ty(&self, span: Span, ty: ast::TyKind) -> P<ast::Ty>;
fn ty_path(&self, path: ast::Path) -> P<ast::Ty>;
fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>;
+ fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst;
+ fn const_ident(&self, span: Span, idents: ast::Ident) -> ast::AnonConst;
fn ty_rptr(&self, span: Span,
ty: P<ast::Ty>,
self.ty_path(self.path_ident(span, ident))
}
+ fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst {
+ ast::AnonConst {
+ id: ast::DUMMY_NODE_ID,
+ value: P(ast::Expr {
+ id: ast::DUMMY_NODE_ID,
+ node: expr,
+ span,
+ attrs: ThinVec::new(),
+ })
+ }
+ }
+
+ fn const_ident(&self, span: Span, ident: ast::Ident) -> ast::AnonConst {
+ self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident)))
+ }
+
fn ty_rptr(&self,
span: Span,
ty: P<ast::Ty>,
use crate::symbol::Symbol;
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
-use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::{Span, DUMMY_SP, symbol::Ident};
use log::debug;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap};
use std::borrow::Cow;
use std::collections::hash_map::Entry;
// Holy self-referential!
/// Converts a `macro_rules!` invocation into a syntax extension.
-pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: Edition)
- -> SyntaxExtension {
+pub fn compile(
+ sess: &ParseSess,
+ features: &Features,
+ def: &ast::Item,
+ edition: Edition
+) -> SyntaxExtension {
let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs"));
let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs"));
// don't abort iteration early, so that errors for multiple lhses can be reported
for lhs in &lhses {
- valid &= check_lhs_no_empty_seq(sess, &[lhs.clone()])
+ valid &= check_lhs_no_empty_seq(sess, &[lhs.clone()]);
+ valid &= check_lhs_duplicate_matcher_bindings(
+ sess,
+ &[lhs.clone()],
+ &mut FxHashMap::default(),
+ def.id
+ );
}
let expander: Box<_> = Box::new(MacroRulesMacroExpander {
true
}
+/// Check that the LHS contains no duplicate matcher bindings. e.g. `$a:expr, $a:expr` would be
+/// illegal, since it would be ambiguous which `$a` to use if we ever needed to.
+fn check_lhs_duplicate_matcher_bindings(
+ sess: &ParseSess,
+ tts: &[quoted::TokenTree],
+ metavar_names: &mut FxHashMap<Ident, Span>,
+ node_id: ast::NodeId,
+) -> bool {
+ use self::quoted::TokenTree;
+ use crate::early_buffered_lints::BufferedEarlyLintId;
+ for tt in tts {
+ match *tt {
+ TokenTree::MetaVarDecl(span, name, _kind) => {
+ if let Some(&prev_span) = metavar_names.get(&name) {
+ // FIXME(mark-i-m): in a few cycles, make this a hard error.
+ // sess.span_diagnostic
+ // .struct_span_err(span, "duplicate matcher binding")
+ // .span_note(prev_span, "previous declaration was here")
+ // .emit();
+ sess.buffer_lint(
+ BufferedEarlyLintId::DuplicateMacroMatcherBindingName,
+ crate::source_map::MultiSpan::from(vec![prev_span, span]),
+ node_id,
+ "duplicate matcher binding"
+ );
+ return false;
+ } else {
+ metavar_names.insert(name, span);
+ }
+ }
+ TokenTree::Delimited(_, ref del) => {
+ if !check_lhs_duplicate_matcher_bindings(sess, &del.tts, metavar_names, node_id) {
+ return false;
+ }
+ },
+ TokenTree::Sequence(_, ref seq) => {
+ if !check_lhs_duplicate_matcher_bindings(sess, &seq.tts, metavar_names, node_id) {
+ return false;
+ }
+ }
+ _ => {}
+ }
+ }
+
+ true
+}
+
fn check_rhs(sess: &ParseSess, rhs: "ed::TokenTree) -> bool {
match *rhs {
quoted::TokenTree::Delimited(..) => return true,
use AttributeType::*;
use AttributeGate::*;
-use crate::ast::{self, NodeId, PatKind, RangeEnd};
+use crate::ast::{self, NodeId, GenericParam, GenericParamKind, PatKind, RangeEnd};
use crate::attr;
use crate::early_buffered_lints::BufferedEarlyLintId;
use crate::source_map::Spanned;
// Re-Rebalance coherence
(active, re_rebalance_coherence, "1.32.0", Some(55437), None),
+ // Const generic types.
+ (active, const_generics, "1.34.0", Some(44580), None),
+
// #[optimize(X)]
(active, optimize_attribute, "1.34.0", Some(54882), None),
visit::walk_fn(self, fn_kind, fn_decl, span);
}
+ fn visit_generic_param(&mut self, param: &'a GenericParam) {
+ if let GenericParamKind::Const { .. } = param.kind {
+ gate_feature_post!(&self, const_generics, param.ident.span,
+ "const generics are unstable");
+ }
+ visit::walk_generic_param(self, param);
+ }
+
fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
match ti.node {
ast::TraitItemKind::Method(ref sig, ref block) => {
// Some features are known to be incomplete and using them is likely to have
// unanticipated results, such as compiler crashes. We warn the user about these
// to alert them.
- let incomplete_features = ["generic_associated_types"];
+ let incomplete_features = ["generic_associated_types", "const_generics"];
let mut features = Features::new();
let mut edition_enabled_features = FxHashMap::default();
match arg {
GenericArg::Lifetime(lt) => vis.visit_lifetime(lt),
GenericArg::Type(ty) => vis.visit_ty(ty),
+ GenericArg::Const(ct) => vis.visit_anon_const(ct),
}
}
GenericParamKind::Type { default } => {
visit_opt(default, |default| vis.visit_ty(default));
}
+ GenericParamKind::Const { ty } => {
+ vis.visit_ty(ty);
+ }
}
}
}
}
+#[derive(Clone, Debug)]
+pub struct UnmatchedBrace {
+ pub expected_delim: token::DelimToken,
+ pub found_delim: token::DelimToken,
+ pub found_span: Span,
+ pub unclosed_span: Option<Span>,
+ pub candidate_span: Option<Span>,
+}
+
pub struct StringReader<'a> {
pub sess: &'a ParseSess,
/// The absolute offset within the source_map of the next character to read
span_src_raw: Span,
/// Stack of open delimiters and their spans. Used for error message.
open_braces: Vec<(token::DelimToken, Span)>,
+ crate unmatched_braces: Vec<UnmatchedBrace>,
/// The type and spans for all braces
///
/// Used only for error recovery when arriving to EOF with mismatched braces.
span: syntax_pos::DUMMY_SP,
span_src_raw: syntax_pos::DUMMY_SP,
open_braces: Vec::new(),
+ unmatched_braces: Vec::new(),
matching_delim_spans: Vec::new(),
override_span,
last_unclosed_found_span: None,
use crate::print::pprust::token_to_string;
-use crate::parse::lexer::StringReader;
+use crate::parse::lexer::{StringReader, UnmatchedBrace};
use crate::parse::{token, PResult};
use crate::tokenstream::{DelimSpan, IsJoint::*, TokenStream, TokenTree, TreeAndJoint};
}
// Incorrect delimiter.
token::CloseDelim(other) => {
- let token_str = token_to_string(&self.token);
+ let mut unclosed_delimiter = None;
+ let mut candidate = None;
if self.last_unclosed_found_span != Some(self.span) {
// do not complain about the same unclosed delimiter multiple times
self.last_unclosed_found_span = Some(self.span);
- let msg = format!("incorrect close delimiter: `{}`", token_str);
- let mut err = self.sess.span_diagnostic.struct_span_err(
- self.span,
- &msg,
- );
- err.span_label(self.span, "incorrect close delimiter");
// This is a conservative error: only report the last unclosed
// delimiter. The previous unclosed delimiters could actually be
// closed! The parser just hasn't gotten to them yet.
if let Some(&(_, sp)) = self.open_braces.last() {
- err.span_label(sp, "un-closed delimiter");
+ unclosed_delimiter = Some(sp);
};
if let Some(current_padding) = sm.span_to_margin(self.span) {
for (brace, brace_span) in &self.open_braces {
if let Some(padding) = sm.span_to_margin(*brace_span) {
// high likelihood of these two corresponding
if current_padding == padding && brace == &other {
- err.span_label(
- *brace_span,
- "close delimiter possibly meant for this",
- );
+ candidate = Some(*brace_span);
}
}
}
}
- err.emit();
+ let (tok, _) = self.open_braces.pop().unwrap();
+ self.unmatched_braces.push(UnmatchedBrace {
+ expected_delim: tok,
+ found_delim: other,
+ found_span: self.span,
+ unclosed_span: unclosed_delimiter,
+ candidate_span: candidate,
+ });
+ } else {
+ self.open_braces.pop();
}
- self.open_braces.pop().unwrap();
// If the incorrect delimiter matches an earlier opening
// delimiter, then don't consume it (it can be used to
use crate::symbol::Symbol;
use crate::tokenstream::{TokenStream, TokenTree};
use crate::diagnostics::plugin::ErrorMap;
+use crate::print::pprust::token_to_string;
use rustc_data_structures::sync::{Lrc, Lock};
use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
new_parser_from_source_str(sess, name, source).parse_inner_attributes()
}
-pub fn parse_stream_from_source_str(name: FileName, source: String, sess: &ParseSess,
- override_span: Option<Span>)
- -> TokenStream {
+pub fn parse_stream_from_source_str(
+ name: FileName,
+ source: String,
+ sess: &ParseSess,
+ override_span: Option<Span>,
+) -> (TokenStream, Vec<lexer::UnmatchedBrace>) {
source_file_to_stream(sess, sess.source_map().new_source_file(name, source), override_span)
}
/// Create a new parser from a source string
-pub fn new_parser_from_source_str(sess: &ParseSess, name: FileName, source: String)
- -> Parser<'_> {
+pub fn new_parser_from_source_str(sess: &ParseSess, name: FileName, source: String) -> Parser<'_> {
panictry_buffer!(&sess.span_diagnostic, maybe_new_parser_from_source_str(sess, name, source))
}
/// Given a source_file and config, return a parser. Returns any buffered errors from lexing the
/// initial token stream.
-fn maybe_source_file_to_parser(sess: &ParseSess, source_file: Lrc<SourceFile>)
- -> Result<Parser<'_>, Vec<Diagnostic>>
-{
+fn maybe_source_file_to_parser(
+ sess: &ParseSess,
+ source_file: Lrc<SourceFile>,
+) -> Result<Parser<'_>, Vec<Diagnostic>> {
let end_pos = source_file.end_pos;
- let mut parser = stream_to_parser(sess, maybe_file_to_stream(sess, source_file, None)?);
-
+ let (stream, unclosed_delims) = maybe_file_to_stream(sess, source_file, None)?;
+ let mut parser = stream_to_parser(sess, stream);
+ parser.unclosed_delims = unclosed_delims;
if parser.token == token::Eof && parser.span.is_dummy() {
parser.span = Span::new(end_pos, end_pos, parser.span.ctxt());
}
}
/// Given a source_file, produce a sequence of token-trees
-pub fn source_file_to_stream(sess: &ParseSess,
- source_file: Lrc<SourceFile>,
- override_span: Option<Span>) -> TokenStream {
+pub fn source_file_to_stream(
+ sess: &ParseSess,
+ source_file: Lrc<SourceFile>,
+ override_span: Option<Span>,
+) -> (TokenStream, Vec<lexer::UnmatchedBrace>) {
panictry_buffer!(&sess.span_diagnostic, maybe_file_to_stream(sess, source_file, override_span))
}
/// Given a source file, produce a sequence of token-trees. Returns any buffered errors from
/// parsing the token tream.
-pub fn maybe_file_to_stream(sess: &ParseSess,
- source_file: Lrc<SourceFile>,
- override_span: Option<Span>) -> Result<TokenStream, Vec<Diagnostic>> {
+pub fn maybe_file_to_stream(
+ sess: &ParseSess,
+ source_file: Lrc<SourceFile>,
+ override_span: Option<Span>,
+) -> Result<(TokenStream, Vec<lexer::UnmatchedBrace>), Vec<Diagnostic>> {
let mut srdr = lexer::StringReader::new_or_buffered_errs(sess, source_file, override_span)?;
srdr.real_token();
match srdr.parse_all_token_trees() {
- Ok(stream) => Ok(stream),
+ Ok(stream) => Ok((stream, srdr.unmatched_braces)),
Err(err) => {
let mut buffer = Vec::with_capacity(1);
err.buffer(&mut buffer);
+ // Not using `emit_unclosed_delims` to use `db.buffer`
+ for unmatched in srdr.unmatched_braces {
+ let mut db = sess.span_diagnostic.struct_span_err(unmatched.found_span, &format!(
+ "incorrect close delimiter: `{}`",
+ token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
+ ));
+ db.span_label(unmatched.found_span, "incorrect close delimiter");
+ if let Some(sp) = unmatched.candidate_span {
+ db.span_label(sp, "close delimiter possibly meant for this");
+ }
+ if let Some(sp) = unmatched.unclosed_span {
+ db.span_label(sp, "un-closed delimiter");
+ }
+ db.buffer(&mut buffer);
+ }
Err(buffer)
}
}
use crate::source_map::{self, SourceMap, Spanned, respan};
use crate::errors::{self, Applicability, DiagnosticBuilder, DiagnosticId};
use crate::parse::{self, SeqSep, classify, token};
-use crate::parse::lexer::TokenAndSpan;
+use crate::parse::lexer::{TokenAndSpan, UnmatchedBrace};
use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use crate::parse::token::DelimToken;
use crate::parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
///
/// See the comments in the `parse_path_segment` function for more details.
crate unmatched_angle_bracket_count: u32,
+ crate max_angle_bracket_count: u32,
+ /// List of all unclosed delimiters found by the lexer. If an entry is used for error recovery
+ /// it gets removed from here. Every entry left at the end gets emitted as an independent
+ /// error.
+ crate unclosed_delims: Vec<UnmatchedBrace>,
}
Ident,
Path,
Type,
+ Const,
}
impl TokenType {
TokenType::Ident => "identifier".to_string(),
TokenType::Path => "path".to_string(),
TokenType::Type => "type".to_string(),
+ TokenType::Const => "const".to_string(),
}
}
}
desugar_doc_comments,
cfg_mods: true,
unmatched_angle_bracket_count: 0,
+ max_angle_bracket_count: 0,
+ unclosed_delims: Vec::new(),
};
let tok = parser.next_tok();
/// Expect and consume the token t. Signal an error if
/// the next token is not t.
- pub fn expect(&mut self, t: &token::Token) -> PResult<'a, ()> {
+ pub fn expect(&mut self, t: &token::Token) -> PResult<'a, bool /* recovered */> {
if self.expected_tokens.is_empty() {
if self.token == *t {
self.bump();
- Ok(())
+ Ok(false)
} else {
let token_str = pprust::token_to_string(t);
let this_token_str = self.this_token_descr();
self.sess.source_map().next_point(self.prev_span)
};
let label_exp = format!("expected `{}`", token_str);
+ match self.recover_closing_delimiter(&[t.clone()], err) {
+ Err(e) => err = e,
+ Ok(recovered) => {
+ return Ok(recovered);
+ }
+ }
let cm = self.sess.source_map();
match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
}
}
+ fn recover_closing_delimiter(
+ &mut self,
+ tokens: &[token::Token],
+ mut err: DiagnosticBuilder<'a>,
+ ) -> PResult<'a, bool> {
+ let mut pos = None;
+ // we want to use the last closing delim that would apply
+ for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
+ if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
+ && Some(self.span) > unmatched.unclosed_span
+ {
+ pos = Some(i);
+ }
+ }
+ match pos {
+ Some(pos) => {
+ // Recover and assume that the detected unclosed delimiter was meant for
+ // this location. Emit the diagnostic and act as if the delimiter was
+ // present for the parser's sake.
+
+ // Don't attempt to recover from this unclosed delimiter more than once.
+ let unmatched = self.unclosed_delims.remove(pos);
+ let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
+
+ // We want to suggest the inclusion of the closing delimiter where it makes
+ // the most sense, which is immediately after the last token:
+ //
+ // {foo(bar {}}
+ // - ^
+ // | |
+ // | help: `)` may belong here (FIXME: #58270)
+ // |
+ // unclosed delimiter
+ if let Some(sp) = unmatched.unclosed_span {
+ err.span_label(sp, "unclosed delimiter");
+ }
+ err.span_suggestion_short(
+ self.sess.source_map().next_point(self.prev_span),
+ &format!("{} may belong here", delim.to_string()),
+ delim.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ err.emit();
+ self.expected_tokens.clear(); // reduce errors
+ Ok(true)
+ }
+ _ => Err(err),
+ }
+ }
+
/// Expect next token to be edible or inedible token. If edible,
/// then consume it; if inedible, then return without consuming
/// anything. Signal a fatal error if next token is unexpected.
- pub fn expect_one_of(&mut self,
- edible: &[token::Token],
- inedible: &[token::Token]) -> PResult<'a, ()>{
+ pub fn expect_one_of(
+ &mut self,
+ edible: &[token::Token],
+ inedible: &[token::Token],
+ ) -> PResult<'a, bool /* recovered */> {
fn tokens_to_string(tokens: &[TokenType]) -> String {
let mut i = tokens.iter();
// This might be a sign we need a connect method on Iterator.
}
if edible.contains(&self.token) {
self.bump();
- Ok(())
+ Ok(false)
} else if inedible.contains(&self.token) {
// leave it in the input
- Ok(())
+ Ok(false)
} else {
let mut expected = edible.iter()
.map(|x| TokenType::Token(x.clone()))
} else {
label_sp
};
+ match self.recover_closing_delimiter(&expected.iter().filter_map(|tt| match tt {
+ TokenType::Token(t) => Some(t.clone()),
+ _ => None,
+ }).collect::<Vec<_>>(), err) {
+ Err(e) => err = e,
+ Ok(recovered) => {
+ return Ok(recovered);
+ }
+ }
let cm = self.sess.source_map();
match (cm.lookup_line(self.span.lo()), cm.lookup_line(sp.lo())) {
}
}
+ fn check_const_arg(&mut self) -> bool {
+ if self.token.can_begin_const_arg() {
+ true
+ } else {
+ self.expected_tokens.push(TokenType::Const);
+ false
+ }
+ }
+
/// Expect and consume a `+`. if `+=` is seen, replace it with a `=`
/// and continue. If a `+` is not seen, return false.
///
}
/// Attempt to consume a `<`. If `<<` is seen, replace it with a single
- /// `<` and continue. If a `<` is not seen, return false.
+ /// `<` and continue. If `<-` is seen, replace it with a single `<`
+ /// and continue. If a `<` is not seen, return false.
///
/// This is meant to be used when parsing generics on a path to get the
/// starting token.
self.bump_with(token::Lt, span);
true
}
+ token::LArrow => {
+ let span = self.span.with_lo(self.span.lo() + BytePos(1));
+ self.bump_with(token::BinOp(token::Minus), span);
+ true
+ }
_ => false,
};
if ate {
// See doc comment for `unmatched_angle_bracket_count`.
self.unmatched_angle_bracket_count += 1;
+ self.max_angle_bracket_count += 1;
debug!("eat_lt: (increment) count={:?}", self.unmatched_angle_bracket_count);
}
};
match ate {
- Some(x) => {
+ Some(_) => {
// See doc comment for `unmatched_angle_bracket_count`.
self.unmatched_angle_bracket_count -= 1;
debug!("expect_gt: (decrement) count={:?}", self.unmatched_angle_bracket_count);
- Ok(x)
+ Ok(())
},
None => self.unexpected(),
}
-> PResult<'a, Vec<T>> where
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
{
- let val = self.parse_seq_to_before_end(ket, sep, f)?;
- self.bump();
+ let (val, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
+ if !recovered {
+ self.bump();
+ }
Ok(val)
}
/// Parse a sequence, not including the closing delimiter. The function
/// f must consume tokens until reaching the next separator or
/// closing bracket.
- pub fn parse_seq_to_before_end<T, F>(&mut self,
- ket: &token::Token,
- sep: SeqSep,
- f: F)
- -> PResult<'a, Vec<T>>
+ pub fn parse_seq_to_before_end<T, F>(
+ &mut self,
+ ket: &token::Token,
+ sep: SeqSep,
+ f: F,
+ ) -> PResult<'a, (Vec<T>, bool)>
where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>
{
self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
sep: SeqSep,
expect: TokenExpectType,
mut f: F,
- ) -> PResult<'a, Vec<T>>
+ ) -> PResult<'a, (Vec<T>, bool /* recovered */)>
where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>
{
- let mut first: bool = true;
+ let mut first = true;
+ let mut recovered = false;
let mut v = vec![];
while !kets.iter().any(|k| {
match expect {
if first {
first = false;
} else {
- if let Err(mut e) = self.expect(t) {
- // Attempt to keep parsing if it was a similar separator
- if let Some(ref tokens) = t.similar_tokens() {
- if tokens.contains(&self.token) {
- self.bump();
- }
+ match self.expect(t) {
+ Ok(false) => {}
+ Ok(true) => {
+ recovered = true;
+ break;
}
- e.emit();
- // Attempt to keep parsing if it was an omitted separator
- match f(self) {
- Ok(t) => {
- v.push(t);
- continue;
- },
- Err(mut e) => {
- e.cancel();
- break;
+ Err(mut e) => {
+ // Attempt to keep parsing if it was a similar separator
+ if let Some(ref tokens) = t.similar_tokens() {
+ if tokens.contains(&self.token) {
+ self.bump();
+ }
+ }
+ e.emit();
+ // Attempt to keep parsing if it was an omitted separator
+ match f(self) {
+ Ok(t) => {
+ v.push(t);
+ continue;
+ },
+ Err(mut e) => {
+ e.cancel();
+ break;
+ }
}
}
}
v.push(t);
}
- Ok(v)
+ Ok((v, recovered))
}
/// Parse a sequence, including the closing delimiter. The function
/// f must consume tokens until reaching the next separator or
/// closing bracket.
- fn parse_unspanned_seq<T, F>(&mut self,
- bra: &token::Token,
- ket: &token::Token,
- sep: SeqSep,
- f: F)
- -> PResult<'a, Vec<T>> where
+ fn parse_unspanned_seq<T, F>(
+ &mut self,
+ bra: &token::Token,
+ ket: &token::Token,
+ sep: SeqSep,
+ f: F,
+ ) -> PResult<'a, Vec<T>> where
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
{
self.expect(bra)?;
- let result = self.parse_seq_to_before_end(ket, sep, f)?;
- self.eat(ket);
+ let (result, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
+ if !recovered {
+ self.eat(ket);
+ }
Ok(result)
}
// We use `style == PathStyle::Expr` to check if this is in a recursion or not. If
// it isn't, then we reset the unmatched angle bracket count as we're about to start
// parsing a new path.
- if style == PathStyle::Expr { self.unmatched_angle_bracket_count = 0; }
+ if style == PathStyle::Expr {
+ self.unmatched_angle_bracket_count = 0;
+ self.max_angle_bracket_count = 0;
+ }
let args = if self.eat_lt() {
// `<'a, T, A = U>`
} else {
// `(T, U) -> R`
self.bump(); // `(`
- let inputs = self.parse_seq_to_before_tokens(
+ let (inputs, recovered) = self.parse_seq_to_before_tokens(
&[&token::CloseDelim(token::Paren)],
SeqSep::trailing_allowed(token::Comma),
TokenExpectType::Expect,
|p| p.parse_ty())?;
- self.bump(); // `)`
+ if !recovered {
+ self.bump(); // `)`
+ }
let span = lo.to(self.prev_span);
let output = if self.eat(&token::RArrow) {
Some(self.parse_ty_common(false, false)?)
// (e,) is a tuple with only one field, e
let mut es = vec![];
let mut trailing_comma = false;
+ let mut recovered = false;
while self.token != token::CloseDelim(token::Paren) {
es.push(self.parse_expr()?);
- self.expect_one_of(&[], &[token::Comma, token::CloseDelim(token::Paren)])?;
+ recovered = self.expect_one_of(
+ &[],
+ &[token::Comma, token::CloseDelim(token::Paren)],
+ )?;
if self.eat(&token::Comma) {
trailing_comma = true;
} else {
break;
}
}
- self.bump();
+ if !recovered {
+ self.bump();
+ }
hi = self.prev_span;
ex = if es.len() == 1 && !trailing_comma {
hi = pth.span;
ex = ExprKind::Path(None, pth);
} else {
+ if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
+ // Don't complain about bare semicolons after unclosed braces
+ // recovery in order to keep the error count down. Fixing the
+ // delimiters will possibly also fix the bare semicolon found in
+ // expression context. For example, silence the following error:
+ // ```
+ // error: expected expression, found `;`
+ // --> file.rs:2:13
+ // |
+ // 2 | foo(bar(;
+ // | ^ expected expression
+ // ```
+ self.bump();
+ return Ok(self.mk_expr(self.span, ExprKind::Err, ThinVec::new()));
+ }
match self.parse_literal_maybe_minus() {
Ok(expr) => {
hi = expr.span;
match self.expect_one_of(&[token::Comma],
&[token::CloseDelim(token::Brace)]) {
- Ok(()) => if let Some(f) = parsed_field.or(recovery_field) {
+ Ok(_) => if let Some(f) = parsed_field.or(recovery_field) {
// only include the field if there's no parse error for the field name
fields.push(f);
}
Ok((ident, TraitItemKind::Type(bounds, default), generics))
}
+ fn parse_const_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> {
+ self.expect_keyword(keywords::Const)?;
+ let ident = self.parse_ident()?;
+ self.expect(&token::Colon)?;
+ let ty = self.parse_ty()?;
+
+ Ok(GenericParam {
+ ident,
+ id: ast::DUMMY_NODE_ID,
+ attrs: preceding_attrs.into(),
+ bounds: Vec::new(),
+ kind: GenericParamKind::Const {
+ ty,
+ }
+ })
+ }
+
/// Parses (possibly empty) list of lifetime and type parameters, possibly including
/// trailing comma and erroneous trailing attributes.
crate fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
- let mut lifetimes = Vec::new();
let mut params = Vec::new();
- let mut seen_ty_param: Option<Span> = None;
- let mut last_comma_span = None;
- let mut bad_lifetime_pos = vec![];
- let mut suggestions = vec![];
loop {
let attrs = self.parse_outer_attributes()?;
if self.check_lifetime() {
} else {
Vec::new()
};
- lifetimes.push(ast::GenericParam {
+ params.push(ast::GenericParam {
ident: lifetime.ident,
id: lifetime.id,
attrs: attrs.into(),
bounds,
kind: ast::GenericParamKind::Lifetime,
});
- if let Some(sp) = seen_ty_param {
- let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span);
- bad_lifetime_pos.push(self.prev_span);
- if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) {
- suggestions.push((remove_sp, String::new()));
- suggestions.push((
- sp.shrink_to_lo(),
- format!("{}, ", snippet)));
- }
- }
+ } else if self.check_keyword(keywords::Const) {
+ // Parse const parameter.
+ params.push(self.parse_const_param(attrs)?);
} else if self.check_ident() {
// Parse type parameter.
params.push(self.parse_ty_param(attrs)?);
- if seen_ty_param.is_none() {
- seen_ty_param = Some(self.prev_span);
- }
} else {
// Check for trailing attributes and stop parsing.
if !attrs.is_empty() {
- let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" };
- self.struct_span_err(
- attrs[0].span,
- &format!("trailing attribute after {} parameters", param_kind),
- )
- .span_label(attrs[0].span, "attributes must go before parameters")
- .emit();
+ if !params.is_empty() {
+ self.struct_span_err(
+ attrs[0].span,
+ &format!("trailing attribute after generic parameter"),
+ )
+ .span_label(attrs[0].span, "attributes must go before parameters")
+ .emit();
+ } else {
+ self.struct_span_err(
+ attrs[0].span,
+ &format!("attribute without generic parameters"),
+ )
+ .span_label(
+ attrs[0].span,
+ "attributes are only permitted when preceding parameters",
+ )
+ .emit();
+ }
}
break
}
if !self.eat(&token::Comma) {
break
}
- last_comma_span = Some(self.prev_span);
- }
- if !bad_lifetime_pos.is_empty() {
- let mut err = self.struct_span_err(
- bad_lifetime_pos,
- "lifetime parameters must be declared prior to type parameters",
- );
- if !suggestions.is_empty() {
- err.multipart_suggestion(
- "move the lifetime parameter prior to the first type parameter",
- suggestions,
- Applicability::MachineApplicable,
- );
- }
- err.emit();
}
- lifetimes.extend(params); // ensure the correct order of lifetimes and type params
- Ok(lifetimes)
+ Ok(params)
}
/// Parse a set of optional generic type parameter declarations. Where
fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<TypeBinding>)> {
let mut args = Vec::new();
let mut bindings = Vec::new();
+ let mut misplaced_assoc_ty_bindings: Vec<Span> = Vec::new();
+ let mut assoc_ty_bindings: Vec<Span> = Vec::new();
- let mut seen_type = false;
- let mut seen_binding = false;
-
- let mut last_comma_span = None;
- let mut first_type_or_binding_span: Option<Span> = None;
- let mut first_binding_span: Option<Span> = None;
-
- let mut bad_lifetime_pos = vec![];
- let mut bad_type_pos = vec![];
+ let args_lo = self.span;
- let mut lifetime_suggestions = vec![];
- let mut type_suggestions = vec![];
loop {
if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
// Parse lifetime argument.
args.push(GenericArg::Lifetime(self.expect_lifetime()));
-
- if seen_type || seen_binding {
- let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span);
- bad_lifetime_pos.push(self.prev_span);
-
- if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) {
- lifetime_suggestions.push((remove_sp, String::new()));
- lifetime_suggestions.push((
- first_type_or_binding_span.unwrap().shrink_to_lo(),
- format!("{}, ", snippet)));
- }
- }
+ misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings);
} else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) {
// Parse associated type binding.
let lo = self.span;
ty,
span,
});
-
- seen_binding = true;
- if first_type_or_binding_span.is_none() {
- first_type_or_binding_span = Some(span);
- }
- if first_binding_span.is_none() {
- first_binding_span = Some(span);
- }
+ assoc_ty_bindings.push(span);
+ } else if self.check_const_arg() {
+ // FIXME(const_generics): to distinguish between idents for types and consts,
+ // we should introduce a GenericArg::Ident in the AST and distinguish when
+ // lowering to the HIR. For now, idents for const args are not permitted.
+
+ // Parse const argument.
+ let expr = if let token::OpenDelim(token::Brace) = self.token {
+ self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())?
+ } else if self.token.is_ident() {
+ // FIXME(const_generics): to distinguish between idents for types and consts,
+ // we should introduce a GenericArg::Ident in the AST and distinguish when
+ // lowering to the HIR. For now, idents for const args are not permitted.
+ return Err(
+ self.fatal("identifiers may currently not be used for const generics")
+ );
+ } else {
+ // FIXME(const_generics): this currently conflicts with emplacement syntax
+ // with negative integer literals.
+ self.parse_literal_maybe_minus()?
+ };
+ let value = AnonConst {
+ id: ast::DUMMY_NODE_ID,
+ value: expr,
+ };
+ args.push(GenericArg::Const(value));
+ misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings);
} else if self.check_type() {
// Parse type argument.
- let ty_param = self.parse_ty()?;
- if seen_binding {
- let remove_sp = last_comma_span.unwrap_or(self.prev_span).to(self.prev_span);
- bad_type_pos.push(self.prev_span);
-
- if let Ok(snippet) = self.sess.source_map().span_to_snippet(self.prev_span) {
- type_suggestions.push((remove_sp, String::new()));
- type_suggestions.push((
- first_binding_span.unwrap().shrink_to_lo(),
- format!("{}, ", snippet)));
- }
- }
-
- if first_type_or_binding_span.is_none() {
- first_type_or_binding_span = Some(ty_param.span);
- }
- args.push(GenericArg::Type(ty_param));
- seen_type = true;
+ args.push(GenericArg::Type(self.parse_ty()?));
+ misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings);
} else {
break
}
if !self.eat(&token::Comma) {
break
- } else {
- last_comma_span = Some(self.prev_span);
- }
- }
-
- self.maybe_report_incorrect_generic_argument_order(
- bad_lifetime_pos, bad_type_pos, lifetime_suggestions, type_suggestions
- );
-
- Ok((args, bindings))
- }
-
- /// Maybe report an error about incorrect generic argument order - "lifetime parameters
- /// must be declared before type parameters", "type parameters must be declared before
- /// associated type bindings" or both.
- fn maybe_report_incorrect_generic_argument_order(
- &self,
- bad_lifetime_pos: Vec<Span>,
- bad_type_pos: Vec<Span>,
- lifetime_suggestions: Vec<(Span, String)>,
- type_suggestions: Vec<(Span, String)>,
- ) {
- let mut err = if !bad_lifetime_pos.is_empty() && !bad_type_pos.is_empty() {
- let mut positions = bad_lifetime_pos.clone();
- positions.extend_from_slice(&bad_type_pos);
-
- self.struct_span_err(
- positions,
- "generic arguments must declare lifetimes, types and associated type bindings in \
- that order",
- )
- } else if !bad_lifetime_pos.is_empty() {
- self.struct_span_err(
- bad_lifetime_pos.clone(),
- "lifetime parameters must be declared prior to type parameters"
- )
- } else if !bad_type_pos.is_empty() {
- self.struct_span_err(
- bad_type_pos.clone(),
- "type parameters must be declared prior to associated type bindings"
- )
- } else {
- return;
- };
-
- if !bad_lifetime_pos.is_empty() {
- for sp in &bad_lifetime_pos {
- err.span_label(*sp, "must be declared prior to type parameters");
}
}
- if !bad_type_pos.is_empty() {
- for sp in &bad_type_pos {
- err.span_label(*sp, "must be declared prior to associated type bindings");
- }
- }
-
- if !lifetime_suggestions.is_empty() && !type_suggestions.is_empty() {
- let mut suggestions = lifetime_suggestions;
- suggestions.extend_from_slice(&type_suggestions);
-
- let plural = bad_lifetime_pos.len() + bad_type_pos.len() > 1;
- err.multipart_suggestion(
- &format!(
- "move the parameter{}",
- if plural { "s" } else { "" },
- ),
- suggestions,
- Applicability::MachineApplicable,
- );
- } else if !lifetime_suggestions.is_empty() {
- err.multipart_suggestion(
- &format!(
- "move the lifetime parameter{} prior to the first type parameter",
- if bad_lifetime_pos.len() > 1 { "s" } else { "" },
- ),
- lifetime_suggestions,
- Applicability::MachineApplicable,
- );
- } else if !type_suggestions.is_empty() {
- err.multipart_suggestion(
- &format!(
- "move the type parameter{} prior to the first associated type binding",
- if bad_type_pos.len() > 1 { "s" } else { "" },
- ),
- type_suggestions,
- Applicability::MachineApplicable,
+ // FIXME: we would like to report this in ast_validation instead, but we currently do not
+ // preserve ordering of generic parameters with respect to associated type binding, so we
+ // lose that information after parsing.
+ if misplaced_assoc_ty_bindings.len() > 0 {
+ let mut err = self.struct_span_err(
+ args_lo.to(self.prev_span),
+ "associated type bindings must be declared after generic parameters",
);
+ for span in misplaced_assoc_ty_bindings {
+ err.span_label(
+ span,
+ "this associated type binding should be moved after the generic parameters",
+ );
+ }
+ err.emit();
}
- err.emit();
+ Ok((args, bindings))
}
/// Parses an optional `where` clause and places it in `generics`.
let sp = self.span;
let mut variadic = false;
- let args: Vec<Option<Arg>> =
+ let (args, recovered): (Vec<Option<Arg>>, bool) =
self.parse_seq_to_before_end(
&token::CloseDelim(token::Paren),
SeqSep::trailing_allowed(token::Comma),
}
)?;
- self.eat(&token::CloseDelim(token::Paren));
+ if !recovered {
+ self.eat(&token::CloseDelim(token::Paren));
+ }
let args: Vec<_> = args.into_iter().filter_map(|x| x).collect();
// Parse the rest of the function parameter list.
let sep = SeqSep::trailing_allowed(token::Comma);
- let fn_inputs = if let Some(self_arg) = self_arg {
+ let (fn_inputs, recovered) = if let Some(self_arg) = self_arg {
if self.check(&token::CloseDelim(token::Paren)) {
- vec![self_arg]
+ (vec![self_arg], false)
} else if self.eat(&token::Comma) {
let mut fn_inputs = vec![self_arg];
- fn_inputs.append(&mut self.parse_seq_to_before_end(
- &token::CloseDelim(token::Paren), sep, parse_arg_fn)?
- );
- fn_inputs
+ let (mut input, recovered) = self.parse_seq_to_before_end(
+ &token::CloseDelim(token::Paren), sep, parse_arg_fn)?;
+ fn_inputs.append(&mut input);
+ (fn_inputs, recovered)
} else {
return self.unexpected();
}
self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?
};
- // Parse closing paren and return type.
- self.expect(&token::CloseDelim(token::Paren))?;
+ if !recovered {
+ // Parse closing paren and return type.
+ self.expect(&token::CloseDelim(token::Paren))?;
+ }
Ok(P(FnDecl {
inputs: fn_inputs,
output: self.parse_ret_ty(true)?,
SeqSep::trailing_allowed(token::Comma),
TokenExpectType::NoExpect,
|p| p.parse_fn_block_arg()
- )?;
+ )?.0;
self.expect_or()?;
args
}
// `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
// `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
// `<` (LIFETIME|IDENT) `=` - generic parameter with a default
+ // `<` const - generic const parameter
// The only truly ambiguous case is
// `<` IDENT `>` `::` IDENT ...
// we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
(self.look_ahead(1, |t| t == &token::Pound || t == &token::Gt) ||
self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) &&
self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma ||
- t == &token::Colon || t == &token::Eq))
+ t == &token::Colon || t == &token::Eq) ||
+ self.look_ahead(1, |t| t.is_keyword(keywords::Const)))
}
fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
// eat a matched-delimiter token tree:
let (delim, tts) = self.expect_delimited_token_tree()?;
if delim != MacDelimiter::Brace {
- self.expect(&token::Semi)?
+ self.expect(&token::Semi)?;
}
Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim })))
/// entry point for the parser.
pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
let lo = self.span;
- Ok(ast::Crate {
+ let krate = Ok(ast::Crate {
attrs: self.parse_inner_attributes()?,
module: self.parse_mod_items(&token::Eof, lo)?,
span: lo.to(self.span),
- })
+ });
+ emit_unclosed_delims(&self.unclosed_delims, self.diagnostic());
+ self.unclosed_delims.clear();
+ krate
}
pub fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
}
}
}
+
+pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors::Handler) {
+ for unmatched in unclosed_delims {
+ let mut err = handler.struct_span_err(unmatched.found_span, &format!(
+ "incorrect close delimiter: `{}`",
+ pprust::token_to_string(&token::Token::CloseDelim(unmatched.found_delim)),
+ ));
+ err.span_label(unmatched.found_span, "incorrect close delimiter");
+ if let Some(sp) = unmatched.candidate_span {
+ err.span_label(sp, "close delimiter possibly meant for this");
+ }
+ if let Some(sp) = unmatched.unclosed_span {
+ err.span_label(sp, "un-closed delimiter");
+ }
+ err.emit();
+ }
+}
use crate::ptr::P;
use crate::symbol::keywords;
use crate::syntax::parse::parse_stream_from_source_str;
+use crate::syntax::parse::parser::emit_unclosed_delims;
use crate::tokenstream::{self, DelimSpan, TokenStream, TokenTree};
use serialize::{Decodable, Decoder, Encodable, Encoder};
}
}
+ /// Returns `true` if the token can appear at the start of a const param.
+ pub fn can_begin_const_arg(&self) -> bool {
+ match self {
+ OpenDelim(Brace) => true,
+ Interpolated(ref nt) => match nt.0 {
+ NtExpr(..) => true,
+ NtBlock(..) => true,
+ NtLiteral(..) => true,
+ _ => false,
+ }
+ _ => self.can_begin_literal_or_bool(),
+ }
+ }
+
/// Returns `true` if the token can appear at the start of a generic bound.
crate fn can_begin_bound(&self) -> bool {
self.is_path_start() || self.is_lifetime() || self.is_keyword(keywords::For) ||
}
}
- /// Returns `true` if the token is any literal, a minus (which can follow a literal,
+ /// Returns `true` if the token is any literal, a minus (which can prefix a literal,
/// for example a '-42', or one of the boolean idents).
crate fn can_begin_literal_or_bool(&self) -> bool {
match *self {
/// Enables better error recovery when the wrong token is found.
crate fn similar_tokens(&self) -> Option<Vec<Token>> {
match *self {
- Comma => Some(vec![Dot, Lt]),
- Semi => Some(vec![Colon]),
+ Comma => Some(vec![Dot, Lt, Semi]),
+ Semi => Some(vec![Colon, Comma]),
_ => None
}
}
// FIXME(#43081): Avoid this pretty-print + reparse hack
let source = pprust::token_to_string(self);
let filename = FileName::macro_expansion_source_code(&source);
- parse_stream_from_source_str(filename, source, sess, Some(span))
+ let (tokens, errors) = parse_stream_from_source_str(
+ filename, source, sess, Some(span));
+ emit_unclosed_delims(&errors, &sess.span_diagnostic);
+ tokens
});
// During early phases of the compiler the AST could get modified
let source = pprust::attr_to_string(attr);
let macro_filename = FileName::macro_expansion_source_code(&source);
if attr.is_sugared_doc {
- let stream = parse_stream_from_source_str(
+ let (stream, errors) = parse_stream_from_source_str(
macro_filename,
source,
sess,
Some(span),
);
+ emit_unclosed_delims(&errors, &sess.span_diagnostic);
builder.push(stream);
continue
}
// ... and for more complicated paths, fall back to a reparse hack that
// should eventually be removed.
} else {
- let stream = parse_stream_from_source_str(
+ let (stream, errors) = parse_stream_from_source_str(
macro_filename,
source,
sess,
Some(span),
);
+ emit_unclosed_delims(&errors, &sess.span_diagnostic);
brackets.push(stream);
}
match generic_arg {
GenericArg::Lifetime(lt) => self.print_lifetime(*lt),
GenericArg::Type(ty) => self.print_type(ty),
+ GenericArg::Const(ct) => self.print_expr(&ct.value),
}
}
s.print_outer_attributes_inline(¶m.attrs)?;
let lt = ast::Lifetime { id: param.id, ident: param.ident };
s.print_lifetime_bounds(lt, ¶m.bounds)
- },
+ }
ast::GenericParamKind::Type { ref default } => {
s.print_outer_attributes_inline(¶m.attrs)?;
s.print_ident(param.ident)?;
_ => Ok(())
}
}
+ ast::GenericParamKind::Const { ref ty } => {
+ s.print_outer_attributes_inline(¶m.attrs)?;
+ s.word_space("const")?;
+ s.print_ident(param.ident)?;
+ s.s.space()?;
+ s.word_space(":")?;
+ s.print_type(ty)?;
+ s.print_type_bounds(":", ¶m.bounds)
+ }
}
})?;
/// Map a string to tts, using a made-up filename:
pub fn string_to_stream(source_str: String) -> TokenStream {
let ps = ParseSess::new(FilePathMapping::empty());
- source_file_to_stream(&ps, ps.source_map()
- .new_source_file(PathBuf::from("bogofile").into(), source_str), None)
+ source_file_to_stream(
+ &ps,
+ ps.source_map().new_source_file(PathBuf::from("bogofile").into(),
+ source_str,
+ ), None).0
}
/// Map string to parser (via tts)
match generic_arg {
GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
GenericArg::Type(ty) => self.visit_ty(ty),
+ GenericArg::Const(ct) => self.visit_anon_const(ct),
}
}
fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) {
match param.kind {
GenericParamKind::Lifetime => {}
GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default),
+ GenericParamKind::Const { ref ty, .. } => visitor.visit_ty(ty),
}
}
cx.typaram(self.span, param.ident, vec![], bounds, None)
}
+ GenericParamKind::Const { .. } => param.clone(),
}));
// and similarly for where clauses
GenericParamKind::Type { .. } => {
GenericArg::Type(cx.ty_ident(self.span, param.ident))
}
+ GenericParamKind::Const { .. } => {
+ GenericArg::Const(cx.const_ident(self.span, param.ident))
+ }
}).collect();
// Create the type of `self`.
}
}
-/// A type. Supports pointers, Self, and literals
+/// A type. Supports pointers, Self, and literals.
#[derive(Clone)]
pub enum Ty<'a> {
Self_,
Tuple(Vec<Ty<'a>>),
}
+/// A const expression. Supports literals and blocks.
+#[derive(Clone, Eq, PartialEq)]
+pub enum Const {
+ Literal,
+ Block,
+}
+
pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
Borrowed(None, ast::Mutability::Immutable)
}
GenericParamKind::Type { .. } => {
GenericArg::Type(cx.ty_ident(span, param.ident))
}
+ GenericParamKind::Const { .. } => {
+ GenericArg::Const(cx.const_ident(span, param.ident))
+ }
}).collect();
cx.path_all(span, false, vec![self_ty], params, vec![])
use syntax::ext::base::ExtCtxt;
use syntax::parse::lexer::comments;
use syntax::parse::{self, token, ParseSess};
+use syntax::parse::parser::emit_unclosed_delims;
use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
use syntax_pos::hygiene::{SyntaxContext, Transparency};
use syntax_pos::symbol::{keywords, Symbol};
stream.is_empty()
}
fn from_str(&mut self, src: &str) -> Self::TokenStream {
- parse::parse_stream_from_source_str(
+ let (tokens, errors) = parse::parse_stream_from_source_str(
FileName::proc_macro_source_code(src.clone()),
src.to_string(),
self.sess,
Some(self.call_site),
- )
+ );
+ emit_unclosed_delims(&errors, &self.sess.span_diagnostic);
+ tokens
}
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
stream.to_string()
($b:block $t:ty) => {};
($b:block $s:stmt) => {};
($b:block $p:path) => {};
- ($b:block $b:block) => {};
+ ($b:block $c:block) => {};
($b:block $i:ident) => {};
($b:block $t:tt) => {};
($b:block $i:item) => {};
($i:ident $s:stmt) => {};
($i:ident $p:path) => {};
($i:ident $b:block) => {};
- ($i:ident $i:ident) => {};
+ ($i:ident $j:ident) => {};
($i:ident $t:tt) => {};
- ($i:ident $i:item) => {};
+ ($i:ident $j:item) => {};
($i:ident $m:meta) => {};
}
// FOLLOW(tt) = any token
($t:tt ident) => {};
($t:tt $p:pat) => {};
($t:tt $e:expr) => {};
- ($t:tt $t:ty) => {};
+ ($t:tt $v:ty) => {};
($t:tt $s:stmt) => {};
($t:tt $p:path) => {};
($t:tt $b:block) => {};
($t:tt $i:ident) => {};
- ($t:tt $t:tt) => {};
+ ($t:tt $v:tt) => {};
($t:tt $i:item) => {};
($t:tt $m:meta) => {};
}
($i:item $s:stmt) => {};
($i:item $p:path) => {};
($i:item $b:block) => {};
- ($i:item $i:ident) => {};
+ ($i:item $j:ident) => {};
($i:item $t:tt) => {};
- ($i:item $i:item) => {};
+ ($i:item $j:item) => {};
($i:item $m:meta) => {};
}
// FOLLOW(meta) = any token
($m:meta $i:ident) => {};
($m:meta $t:tt) => {};
($m:meta $i:item) => {};
- ($m:meta $m:meta) => {};
+ ($m:meta $n:meta) => {};
}
fn main() {}
--- /dev/null
+// Check that method matching does not make "guesses" depending on
+// Deref impls that don't eventually end up being picked.
+
+use std::ops::Deref;
+
+// An impl with less derefs will get called over an impl with more derefs,
+// so `(t: Foo<_>).my_fn()` will use `<Foo<u32> as MyTrait1>::my_fn(t)`,
+// and does *not* force the `_` to equal `()`, because the Deref impl
+// was *not* used.
+
+trait MyTrait1 {
+ fn my_fn(&self) {}
+}
+
+impl MyTrait1 for Foo<u32> {}
+
+struct Foo<T>(T);
+
+impl Deref for Foo<()> {
+ type Target = dyn MyTrait1 + 'static;
+ fn deref(&self) -> &(dyn MyTrait1 + 'static) {
+ panic!()
+ }
+}
+
+// ...but if there is no impl with less derefs, the "guess" will be
+// forced, so `(t: Bar<_>).my_fn2()` is `<dyn MyTrait2 as MyTrait2>::my_fn2(*t)`,
+// and because the deref impl is used, the `_` is forced to equal `u8`.
+
+trait MyTrait2 {
+ fn my_fn2(&self) {}
+}
+
+impl MyTrait2 for u32 {}
+struct Bar<T>(T, u32);
+impl Deref for Bar<u8> {
+ type Target = dyn MyTrait2 + 'static;
+ fn deref(&self) -> &(dyn MyTrait2 + 'static) {
+ &self.1
+ }
+}
+
+// actually invoke things
+
+fn main() {
+ let mut foo: Option<Foo<_>> = None;
+ let mut bar: Option<Bar<_>> = None;
+ let mut first_iter = true;
+ loop {
+ if !first_iter {
+ foo.as_ref().unwrap().my_fn();
+ bar.as_ref().unwrap().my_fn2();
+ break;
+ }
+ foo = Some(Foo(0));
+ bar = Some(Bar(Default::default(), 0));
+ first_iter = false;
+ }
+}
--- /dev/null
+fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters
+
+fn main() {}
--- /dev/null
+error: attribute without generic parameters
+ --> $DIR/attribute-with-no-generics-in-parameter-list.rs:1:8
+ |
+LL | fn foo<#[attr]>() {} //~ ERROR attribute without generic parameters
+ | ^^^^^^^ attributes are only permitted when preceding parameters
+
+error: aborting due to previous error
+
struct RefIntPair<'a, 'b>(&'a u32, &'b u32);
impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
- //~^ ERROR trailing attribute after lifetime parameters
+ //~^ ERROR trailing attribute after generic parameter
}
fn main() {
-error: trailing attribute after lifetime parameters
+error: trailing attribute after generic parameter
--> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25
|
LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
struct RefAny<'a, T>(&'a T);
impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {}
-//~^ ERROR trailing attribute after type parameters
+//~^ ERROR trailing attribute after generic parameter
fn main() {}
-error: trailing attribute after type parameters
+error: trailing attribute after generic parameter
--> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35
|
LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {}
fn hof_lt<Q>(_: Q)
where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32
- //~^ ERROR trailing attribute after lifetime parameters
+ //~^ ERROR trailing attribute after generic parameter
{}
fn main() {}
-error: trailing attribute after lifetime parameters
+error: trailing attribute after generic parameter
--> $DIR/attrs-with-no-formal-in-generics-3.rs:8:44
|
LL | where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32
LL | | //~^ value used here after move
LL | | +=
LL | | x; //~ value moved here
- | | -
+ | | ^
| | |
| |_____move out of `x` occurs here
| borrow later used here
fn foo<T>() {
- fn bar(b: T) { } //~ ERROR can't use type parameters from outer
+ fn bar(b: T) { } //~ ERROR can't use generic parameters from outer
}
fn main() { }
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/bad-type-env-capture.rs:2:15
|
LL | fn foo<T>() {
| - type variable from outer function
-LL | fn bar(b: T) { } //~ ERROR can't use type parameters from outer
- | --- ^ use of type variable from outer function
+LL | fn bar(b: T) { } //~ ERROR can't use generic parameters from outer
+ | --- ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `bar<T>`
+ | help: try using a local generic parameter instead: `bar<T>`
error: aborting due to previous error
--- /dev/null
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn u32_identity<const X: u32>() -> u32 {
+ //~^ ERROR const generics in any position are currently unsupported
+ 5
+}
+
+fn foo_a() {
+ u32_identity::<-1>(); //~ ERROR expected identifier, found `<-`
+}
+
+fn foo_b() {
+ u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+`
+}
+
+fn foo_c() {
+ u32_identity::< -1 >(); // ok
+}
+
+fn main() {
+ u32_identity::<5>(); // ok
+}
--- /dev/null
+error: expected identifier, found `<-`
+ --> $DIR/const-expression-parameter.rs:10:19
+ |
+LL | u32_identity::<-1>(); //~ ERROR expected identifier, found `<-`
+ | ^^ expected identifier
+
+error: expected one of `,` or `>`, found `+`
+ --> $DIR/const-expression-parameter.rs:14:22
+ |
+LL | u32_identity::<1 + 2>(); //~ ERROR expected one of `,` or `>`, found `+`
+ | ^ expected one of `,` or `>` here
+
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/const-expression-parameter.rs:1:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+
+error: const generics in any position are currently unsupported
+ --> $DIR/const-expression-parameter.rs:4:23
+ |
+LL | fn u32_identity<const X: u32>() -> u32 {
+ | ^
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+const fn const_u32_identity<const X: u32>() -> u32 {
+ //~^ ERROR const parameters are not permitted in `const fn`
+ //~^^ ERROR const generics in any position are currently unsupported
+ X
+}
+
+fn main() {
+ println!("{:?}", const_u32_identity::<18>());
+}
--- /dev/null
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/const-fn-with-const-param.rs:1:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+
+error: const parameters are not permitted in `const fn`
+ --> $DIR/const-fn-with-const-param.rs:4:1
+ |
+LL | / const fn const_u32_identity<const X: u32>() -> u32 {
+LL | | //~^ ERROR const parameters are not permitted in `const fn`
+LL | | //~^^ ERROR const generics in any position are currently unsupported
+LL | | X
+LL | | }
+ | |_^
+
+error: const generics in any position are currently unsupported
+ --> $DIR/const-fn-with-const-param.rs:4:35
+ |
+LL | const fn const_u32_identity<const X: u32>() -> u32 {
+ | ^
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn foo<const X: (), T>(_: T) {
+ //~^ ERROR type parameters must be declared prior to const parameters
+ //~^^ ERROR const generics in any position are currently unsupported
+}
+
+fn bar<const X: (), 'a>(_: &'a ()) {
+ //~^ ERROR lifetime parameters must be declared prior to const parameters
+}
+
+fn main() {}
--- /dev/null
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/const-param-before-other-params.rs:1:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+
+error: type parameters must be declared prior to const parameters
+ --> $DIR/const-param-before-other-params.rs:4:21
+ |
+LL | fn foo<const X: (), T>(_: T) {
+ | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>`
+
+error: lifetime parameters must be declared prior to const parameters
+ --> $DIR/const-param-before-other-params.rs:9:21
+ |
+LL | fn bar<const X: (), 'a>(_: &'a ()) {
+ | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>`
+
+error: const generics in any position are currently unsupported
+ --> $DIR/const-param-before-other-params.rs:4:14
+ |
+LL | fn foo<const X: (), T>(_: T) {
+ | ^
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn foo<const X: u32>() {
+ //~^ ERROR const generics in any position are currently unsupported
+ fn bar() -> u32 {
+ X //~ ERROR can't use generic parameters from outer function
+ }
+}
+
+fn main() {}
--- /dev/null
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/const-param-from-outer-fn.rs:1:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/const-param-from-outer-fn.rs:7:9
+ |
+LL | fn foo<const X: u32>() {
+ | - const variable from outer function
+LL | //~^ ERROR const generics in any position are currently unsupported
+LL | fn bar() -> u32 {
+ | --- try adding a local generic parameter in this method instead
+LL | X //~ ERROR can't use generic parameters from outer function
+ | ^ use of generic parameter from outer function
+
+error: const generics in any position are currently unsupported
+ --> $DIR/const-param-from-outer-fn.rs:4:14
+ |
+LL | fn foo<const X: u32>() {
+ | ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0401`.
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/duplicate-type-parameter.rs:1:12
|
LL | type Foo<T,T> = Option<T>;
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/duplicate-type-parameter.rs:4:14
|
LL | struct Bar<T,T>(T);
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/duplicate-type-parameter.rs:7:14
|
LL | struct Baz<T,T> {
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/duplicate-type-parameter.rs:12:12
|
LL | enum Boo<T,T> {
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/duplicate-type-parameter.rs:18:11
|
LL | fn quux<T,T>(x: T) {}
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/duplicate-type-parameter.rs:21:13
|
LL | trait Qux<T,T> {}
| |
| first use of `T`
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/duplicate-type-parameter.rs:24:8
|
LL | impl<T,T> Qux<T,T> for Option<T> {}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/E0401.rs:4:39
|
LL | fn foo<T>(x: T) {
| - type variable from outer function
LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) { //~ ERROR E0401
- | --------------------------- ^ use of type variable from outer function
+ | --------------------------- ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `bfnr<U, V: Baz<U>, W: Fn(), T>`
+ | help: try using a local generic parameter instead: `bfnr<U, V: Baz<U>, W: Fn(), T>`
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/E0401.rs:9:16
|
LL | fn foo<T>(x: T) {
| - type variable from outer function
...
LL | fn baz<U,
- | --- try adding a local type parameter in this method instead
+ | --- try adding a local generic parameter in this method instead
...
LL | (y: T) { //~ ERROR E0401
- | ^ use of type variable from outer function
+ | ^ use of generic parameter from outer function
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/E0401.rs:22:25
|
LL | impl<T> Iterator for A<T> {
LL | fn helper(sel: &Self) -> u8 { //~ ERROR E0401
| ^^^^
| |
- | use of type variable from outer function
+ | use of generic parameter from outer function
| use a type here instead
error: aborting due to 3 previous errors
-error[E0403]: the name `T` is already used for a type parameter in this type parameter list
+error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
--> $DIR/E0403.rs:1:11
|
LL | fn foo<T, T>(s: T, u: T) {} //~ ERROR E0403
--- /dev/null
+fn foo<const X: ()>() {} //~ ERROR const generics are unstable
+//~^ const generics in any position are currently unsupported
+
+struct Foo<const X: usize>([(); X]); //~ ERROR const generics are unstable
+
+fn main() {}
--- /dev/null
+error[E0658]: const generics are unstable (see issue #44580)
+ --> $DIR/feature-gate-const_generics.rs:1:14
+ |
+LL | fn foo<const X: ()>() {} //~ ERROR const generics are unstable
+ | ^
+ |
+ = help: add #![feature(const_generics)] to the crate attributes to enable
+
+error[E0658]: const generics are unstable (see issue #44580)
+ --> $DIR/feature-gate-const_generics.rs:4:18
+ |
+LL | struct Foo<const X: usize>([(); X]); //~ ERROR const generics are unstable
+ | ^
+ |
+ = help: add #![feature(const_generics)] to the crate attributes to enable
+
+error: const generics in any position are currently unsupported
+ --> $DIR/feature-gate-const_generics.rs:1:14
+ |
+LL | fn foo<const X: ()>() {} //~ ERROR const generics are unstable
+ | ^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
fn a<T: Clone>(x: T) {
const foo: impl Clone = x;
-//~^ ERROR can't capture dynamic environment in a fn item
+ //~^ ERROR attempt to use a non-constant value in a constant
}
fn b<T: Clone>(x: T) {
let _ = move || {
const foo: impl Clone = x;
-//~^ ERROR can't capture dynamic environment in a fn item
+ //~^ ERROR attempt to use a non-constant value in a constant
};
}
trait Foo<T: Clone> {
fn a(x: T) {
const foo: impl Clone = x;
-//~^ ERROR can't capture dynamic environment in a fn item
+ //~^ ERROR attempt to use a non-constant value in a constant
}
}
impl<T: Clone> Foo<T> for i32 {
fn a(x: T) {
const foo: impl Clone = x;
-//~^ ERROR can't capture dynamic environment in a fn item
+ //~^ ERROR attempt to use a non-constant value in a constant
}
}
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/bindings.rs:4:29
|
LL | const foo: impl Clone = x;
- | ^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^ non-constant value
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/bindings.rs:10:33
|
LL | const foo: impl Clone = x;
- | ^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^ non-constant value
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/bindings.rs:17:33
|
LL | const foo: impl Clone = x;
- | ^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^ non-constant value
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/bindings.rs:24:33
|
LL | const foo: impl Clone = x;
- | ^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^ non-constant value
error: aborting due to 4 previous errors
-For more information about this error, try `rustc --explain E0434`.
+For more information about this error, try `rustc --explain E0435`.
fn foo<T>() {
static a: Bar<T> = Bar::What;
-//~^ ERROR can't use type parameters from outer function
+//~^ ERROR can't use generic parameters from outer function
}
fn main() {
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/inner-static-type-parameter.rs:6:19
|
LL | fn foo<T>() {
| --- - type variable from outer function
| |
- | try adding a local type parameter in this method instead
+ | try adding a local generic parameter in this method instead
LL | static a: Bar<T> = Bar::What;
- | ^ use of type variable from outer function
+ | ^ use of generic parameter from outer function
error[E0392]: parameter `T` is never used
--> $DIR/inner-static-type-parameter.rs:3:10
trait Trait {
fn outer(&self) {
fn inner(_: &Self) {
- //~^ ERROR can't use type parameters from outer function
+ //~^ ERROR can't use generic parameters from outer function
}
}
}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-12796.rs:3:22
|
LL | fn inner(_: &Self) {
| ^^^^
| |
- | use of type variable from outer function
+ | use of generic parameter from outer function
| can't use `Self` here
error: aborting due to previous error
// We need all these 9 issue-20616-N.rs files
// because we can only catch one parsing error at a time
-
-
type Type_1_<'a, T> = &'a T;
//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
-type Type_3<T> = Box<T,,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,`
+type Type_3<T> = Box<T,,>;
+//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
-error: expected one of `>`, identifier, lifetime, or type, found `,`
- --> $DIR/issue-20616-3.rs:15:24
+error: expected one of `>`, const, identifier, lifetime, or type, found `,`
+ --> $DIR/issue-20616-3.rs:13:24
|
-LL | type Type_3<T> = Box<T,,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,`
- | ^ expected one of `>`, identifier, lifetime, or type here
+LL | type Type_3<T> = Box<T,,>;
+ | ^ expected one of `>`, const, identifier, lifetime, or type here
error: aborting due to previous error
// We need all these 9 issue-20616-N.rs files
// because we can only catch one parsing error at a time
-
-
type Type_1_<'a, T> = &'a T;
type Type_4<T> = Type_1_<'static,, T>;
-//~^ error: expected one of `>`, identifier, lifetime, or type, found `,`
+//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
type Type_5_<'a> = Type_1_<'a, ()>;
-error: expected one of `>`, identifier, lifetime, or type, found `,`
- --> $DIR/issue-20616-4.rs:18:34
+error: expected one of `>`, const, identifier, lifetime, or type, found `,`
+ --> $DIR/issue-20616-4.rs:16:34
|
LL | type Type_4<T> = Type_1_<'static,, T>;
- | ^ expected one of `>`, identifier, lifetime, or type here
+ | ^ expected one of `>`, const, identifier, lifetime, or type here
error: aborting due to previous error
// We need all these 9 issue-20616-N.rs files
// because we can only catch one parsing error at a time
-
-
type Type_1_<'a, T> = &'a T;
type Type_5<'a> = Type_1_<'a, (),,>;
-//~^ error: expected one of `>`, identifier, lifetime, or type, found `,`
+//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
-error: expected one of `>`, identifier, lifetime, or type, found `,`
- --> $DIR/issue-20616-5.rs:24:34
+error: expected one of `>`, const, identifier, lifetime, or type, found `,`
+ --> $DIR/issue-20616-5.rs:22:34
|
LL | type Type_5<'a> = Type_1_<'a, (),,>;
- | ^ expected one of `>`, identifier, lifetime, or type here
+ | ^ expected one of `>`, const, identifier, lifetime, or type here
error: aborting due to previous error
// We need all these 9 issue-20616-N.rs files
// because we can only catch one parsing error at a time
-
-
type Type_1_<'a, T> = &'a T;
type Type_6 = Type_5_<'a,,>;
-//~^ error: expected one of `>`, identifier, lifetime, or type, found `,`
+//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
//type Type_7 = Box<(),,>; // error: expected type, found `,`
-error: expected one of `>`, identifier, lifetime, or type, found `,`
- --> $DIR/issue-20616-6.rs:27:26
+error: expected one of `>`, const, identifier, lifetime, or type, found `,`
+ --> $DIR/issue-20616-6.rs:25:26
|
LL | type Type_6 = Type_5_<'a,,>;
- | ^ expected one of `>`, identifier, lifetime, or type here
+ | ^ expected one of `>`, const, identifier, lifetime, or type here
error: aborting due to previous error
// We need all these 9 issue-20616-N.rs files
// because we can only catch one parsing error at a time
-
-
type Type_1_<'a, T> = &'a T;
//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
-type Type_7 = Box<(),,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,`
+type Type_7 = Box<(),,>;
+//~^ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
-error: expected one of `>`, identifier, lifetime, or type, found `,`
- --> $DIR/issue-20616-7.rs:30:22
+error: expected one of `>`, const, identifier, lifetime, or type, found `,`
+ --> $DIR/issue-20616-7.rs:28:22
|
-LL | type Type_7 = Box<(),,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,`
- | ^ expected one of `>`, identifier, lifetime, or type here
+LL | type Type_7 = Box<(),,>;
+ | ^ expected one of `>`, const, identifier, lifetime, or type here
error: aborting due to previous error
// We need all these 9 issue-20616-N.rs files
// because we can only catch one parsing error at a time
-
-
type Type_1_<'a, T> = &'a T;
//type Type_7 = Box<(),,>; // error: expected type, found `,`
-type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, identifier, or lifetime, found `,`
+type Type_8<'a,,> = &'a ();
+//~^ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
//type Type_9<T,,> = Box<T>; // error: expected identifier, found `,`
-error: expected one of `>`, identifier, or lifetime, found `,`
- --> $DIR/issue-20616-8.rs:33:16
+error: expected one of `>`, `const`, identifier, or lifetime, found `,`
+ --> $DIR/issue-20616-8.rs:31:16
|
-LL | type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, identifier, or lifetime, found `,`
- | ^ expected one of `>`, identifier, or lifetime here
+LL | type Type_8<'a,,> = &'a ();
+ | ^ expected one of `>`, `const`, identifier, or lifetime here
error: aborting due to previous error
// We need all these 9 issue-20616-N.rs files
// because we can only catch one parsing error at a time
-
-
type Type_1_<'a, T> = &'a T;
//type Type_8<'a,,> = &'a (); // error: expected identifier, found `,`
-type Type_9<T,,> = Box<T>; //~ error: expected one of `>`, identifier, or lifetime, found `,`
+type Type_9<T,,> = Box<T>;
+//~^ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
-error: expected one of `>`, identifier, or lifetime, found `,`
- --> $DIR/issue-20616-9.rs:36:15
+error: expected one of `>`, `const`, identifier, or lifetime, found `,`
+ --> $DIR/issue-20616-9.rs:34:15
|
-LL | type Type_9<T,,> = Box<T>; //~ error: expected one of `>`, identifier, or lifetime, found `,`
- | ^ expected one of `>`, identifier, or lifetime here
+LL | type Type_9<T,,> = Box<T>;
+ | ^ expected one of `>`, `const`, identifier, or lifetime here
error: aborting due to previous error
fn main() {
let foo = 42u32;
const FOO : u32 = foo;
- //~^ ERROR can't capture dynamic environment
+ //~^ ERROR attempt to use a non-constant value in a constant
}
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-27433.rs:3:23
|
LL | const FOO : u32 = foo;
- | ^^^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^^^ non-constant value
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0434`.
+For more information about this error, try `rustc --explain E0435`.
fn siphash<T>() {
trait U {
- fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function
- //~^ ERROR can't use type parameters from outer function
+ fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function
+ //~^ ERROR can't use generic parameters from outer function
}
}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-3021-c.rs:4:24
|
LL | fn siphash<T>() {
| - type variable from outer function
...
-LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function
- | - ^ use of type variable from outer function
+LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function
+ | - ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `g<T>`
+ | help: try using a local generic parameter instead: `g<T>`
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-3021-c.rs:4:30
|
LL | fn siphash<T>() {
| - type variable from outer function
...
-LL | fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function
- | - ^ use of type variable from outer function
+LL | fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function
+ | - ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `g<T>`
+ | help: try using a local generic parameter instead: `g<T>`
error: aborting due to 2 previous errors
fn foo<T>() {
struct Foo {
- x: T, //~ ERROR can't use type parameters from outer function
+ x: T, //~ ERROR can't use generic parameters from outer function
}
impl<T> Drop for Foo<T> {
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-3214.rs:3:12
|
LL | fn foo<T>() {
| --- - type variable from outer function
| |
- | try adding a local type parameter in this method instead
+ | try adding a local generic parameter in this method instead
LL | struct Foo {
-LL | x: T, //~ ERROR can't use type parameters from outer function
- | ^ use of type variable from outer function
+LL | x: T, //~ ERROR can't use generic parameters from outer function
+ | ^ use of generic parameter from outer function
error[E0107]: wrong number of type arguments: expected 0, found 1
--> $DIR/issue-3214.rs:6:26
let foo = 100;
static y: isize = foo + 1;
- //~^ ERROR can't capture dynamic environment
+ //~^ ERROR attempt to use a non-constant value in a constant
println!("{}", y);
}
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-3521-2.rs:4:23
|
LL | static y: isize = foo + 1;
- | ^^^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^^^ non-constant value
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0434`.
+For more information about this error, try `rustc --explain E0435`.
fn f(x:isize) {
static child: isize = x + 1;
- //~^ ERROR can't capture dynamic environment
+ //~^ ERROR attempt to use a non-constant value in a constant
}
fn main() {}
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-3668-2.rs:2:27
|
LL | static child: isize = x + 1;
- | ^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^ non-constant value
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0434`.
+For more information about this error, try `rustc --explain E0435`.
impl PTrait for P {
fn getChildOption(&self) -> Option<Box<P>> {
static childVal: Box<P> = self.child.get();
- //~^ ERROR can't capture dynamic environment
+ //~^ ERROR attempt to use a non-constant value in a constant
panic!();
}
}
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/issue-3668.rs:8:34
|
LL | static childVal: Box<P> = self.child.get();
- | ^^^^
- |
- = help: use the `|| { ... }` closure form instead
+ | ^^^^ non-constant value
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0434`.
+For more information about this error, try `rustc --explain E0435`.
LL | m,
| ______-
LL | | a}; //~ ERROR `a` is defined multiple times
- | | -
+ | | ^
| | |
| |_____`a` reimported here
| help: remove unnecessary import
fn f<Z>() -> bool {
enum E { V(Z) }
- //~^ ERROR can't use type parameters from outer function
+ //~^ ERROR can't use generic parameters from outer function
true
}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-5997-enum.rs:2:16
|
LL | fn f<Z>() -> bool {
| - - type variable from outer function
| |
- | try adding a local type parameter in this method instead
+ | try adding a local generic parameter in this method instead
LL | enum E { V(Z) }
- | ^ use of type variable from outer function
+ | ^ use of generic parameter from outer function
error: aborting due to previous error
fn f<T>() -> bool {
- struct S(T); //~ ERROR can't use type parameters from outer function
+ struct S(T); //~ ERROR can't use generic parameters from outer function
true
}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/issue-5997-struct.rs:2:14
|
LL | fn f<T>() -> bool {
| - - type variable from outer function
| |
- | try adding a local type parameter in this method instead
-LL | struct S(T); //~ ERROR can't use type parameters from outer function
- | ^ use of type variable from outer function
+ | try adding a local generic parameter in this method instead
+LL | struct S(T); //~ ERROR can't use generic parameters from outer function
+ | ^ use of generic parameter from outer function
error: aborting due to previous error
--> $DIR/lifetime-before-type-params.rs:2:13
|
LL | fn first<T, 'a, 'b>() {}
- | ^^ ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | fn first<'a, 'b, T>() {}
- | ^^^ ^^^ --
+ | ----^^--^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/lifetime-before-type-params.rs:4:18
|
LL | fn second<'a, T, 'b>() {}
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | fn second<'a, 'b, T>() {}
- | ^^^ --
+ | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/lifetime-before-type-params.rs:6:16
|
LL | fn third<T, U, 'a>() {}
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | fn third<'a, T, U>() {}
- | ^^^ --
+ | -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/lifetime-before-type-params.rs:8:18
|
LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
- | ^^ ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | fn fourth<'a, 'b, 'c, T, U, V>() {}
- | ^^^ ^^^ -- --
+ | --------^^-----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
error[E0601]: `main` function not found in crate `lifetime_before_type_params`
|
($p:pat >) => {}; //~ERROR `$p:pat` is followed by `>`
($p:pat +) => {}; //~ERROR `$p:pat` is followed by `+`
($p:pat ident) => {}; //~ERROR `$p:pat` is followed by `ident`
- ($p:pat $p:pat) => {}; //~ERROR `$p:pat` is followed by `$p:pat`
+ ($p:pat $q:pat) => {}; //~ERROR `$p:pat` is followed by `$q:pat`
($p:pat $e:expr) => {}; //~ERROR `$p:pat` is followed by `$e:expr`
($p:pat $t:ty) => {}; //~ERROR `$p:pat` is followed by `$t:ty`
($p:pat $s:stmt) => {}; //~ERROR `$p:pat` is followed by `$s:stmt`
- ($p:pat $p:path) => {}; //~ERROR `$p:pat` is followed by `$p:path`
+ ($p:pat $q:path) => {}; //~ERROR `$p:pat` is followed by `$q:path`
($p:pat $b:block) => {}; //~ERROR `$p:pat` is followed by `$b:block`
($p:pat $i:ident) => {}; //~ERROR `$p:pat` is followed by `$i:ident`
($p:pat $t:tt) => {}; //~ERROR `$p:pat` is followed by `$t:tt`
($e:expr if) => {}; //~ERROR `$e:expr` is followed by `if`
($e:expr in) => {}; //~ERROR `$e:expr` is followed by `in`
($e:expr $p:pat) => {}; //~ERROR `$e:expr` is followed by `$p:pat`
- ($e:expr $e:expr) => {}; //~ERROR `$e:expr` is followed by `$e:expr`
+ ($e:expr $f:expr) => {}; //~ERROR `$e:expr` is followed by `$f:expr`
($e:expr $t:ty) => {}; //~ERROR `$e:expr` is followed by `$t:ty`
($e:expr $s:stmt) => {}; //~ERROR `$e:expr` is followed by `$s:stmt`
($e:expr $p:path) => {}; //~ERROR `$e:expr` is followed by `$p:path`
($t:ty if) => {}; //~ERROR `$t:ty` is followed by `if`
($t:ty $p:pat) => {}; //~ERROR `$t:ty` is followed by `$p:pat`
($t:ty $e:expr) => {}; //~ERROR `$t:ty` is followed by `$e:expr`
- ($t:ty $t:ty) => {}; //~ERROR `$t:ty` is followed by `$t:ty`
+ ($t:ty $r:ty) => {}; //~ERROR `$t:ty` is followed by `$r:ty`
($t:ty $s:stmt) => {}; //~ERROR `$t:ty` is followed by `$s:stmt`
($t:ty $p:path) => {}; //~ERROR `$t:ty` is followed by `$p:path`
($t:ty $b:block) => {}; // ok (RFC 1494)
($t:ty $i:ident) => {}; //~ERROR `$t:ty` is followed by `$i:ident`
- ($t:ty $t:tt) => {}; //~ERROR `$t:ty` is followed by `$t:tt`
+ ($t:ty $r:tt) => {}; //~ERROR `$t:ty` is followed by `$r:tt`
($t:ty $i:item) => {}; //~ERROR `$t:ty` is followed by `$i:item`
($t:ty $m:meta) => {}; //~ERROR `$t:ty` is followed by `$m:meta`
}
($s:stmt $p:pat) => {}; //~ERROR `$s:stmt` is followed by `$p:pat`
($s:stmt $e:expr) => {}; //~ERROR `$s:stmt` is followed by `$e:expr`
($s:stmt $t:ty) => {}; //~ERROR `$s:stmt` is followed by `$t:ty`
- ($s:stmt $s:stmt) => {}; //~ERROR `$s:stmt` is followed by `$s:stmt`
+ ($s:stmt $t:stmt) => {}; //~ERROR `$s:stmt` is followed by `$t:stmt`
($s:stmt $p:path) => {}; //~ERROR `$s:stmt` is followed by `$p:path`
($s:stmt $b:block) => {}; //~ERROR `$s:stmt` is followed by `$b:block`
($s:stmt $i:ident) => {}; //~ERROR `$s:stmt` is followed by `$i:ident`
($p:path +) => {}; //~ERROR `$p:path` is followed by `+`
($p:path ident) => {}; //~ERROR `$p:path` is followed by `ident`
($p:path if) => {}; //~ERROR `$p:path` is followed by `if`
- ($p:path $p:pat) => {}; //~ERROR `$p:path` is followed by `$p:pat`
+ ($p:path $q:pat) => {}; //~ERROR `$p:path` is followed by `$q:pat`
($p:path $e:expr) => {}; //~ERROR `$p:path` is followed by `$e:expr`
($p:path $t:ty) => {}; //~ERROR `$p:path` is followed by `$t:ty`
($p:path $s:stmt) => {}; //~ERROR `$p:path` is followed by `$s:stmt`
- ($p:path $p:path) => {}; //~ERROR `$p:path` is followed by `$p:path`
+ ($p:path $q:path) => {}; //~ERROR `$p:path` is followed by `$q:path`
($p:path $b:block) => {}; // ok (RFC 1494)
($p:path $i:ident) => {}; //~ERROR `$p:path` is followed by `$i:ident`
($p:path $t:tt) => {}; //~ERROR `$p:path` is followed by `$t:tt`
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
-error: `$p:pat` is followed by `$p:pat`, which is not allowed for `pat` fragments
+error: `$p:pat` is followed by `$q:pat`, which is not allowed for `pat` fragments
--> $DIR/macro-follow.rs:15:13
|
-LL | ($p:pat $p:pat) => {}; //~ERROR `$p:pat` is followed by `$p:pat`
+LL | ($p:pat $q:pat) => {}; //~ERROR `$p:pat` is followed by `$q:pat`
| ^^^^^^ not allowed after `pat` fragments
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
-error: `$p:pat` is followed by `$p:path`, which is not allowed for `pat` fragments
+error: `$p:pat` is followed by `$q:path`, which is not allowed for `pat` fragments
--> $DIR/macro-follow.rs:19:13
|
-LL | ($p:pat $p:path) => {}; //~ERROR `$p:pat` is followed by `$p:path`
+LL | ($p:pat $q:path) => {}; //~ERROR `$p:pat` is followed by `$q:path`
| ^^^^^^^ not allowed after `pat` fragments
|
= note: allowed there are: `=>`, `,`, `=`, `|`, `if` or `in`
|
= note: allowed there are: `=>`, `,` or `;`
-error: `$e:expr` is followed by `$e:expr`, which is not allowed for `expr` fragments
+error: `$e:expr` is followed by `$f:expr`, which is not allowed for `expr` fragments
--> $DIR/macro-follow.rs:40:14
|
-LL | ($e:expr $e:expr) => {}; //~ERROR `$e:expr` is followed by `$e:expr`
+LL | ($e:expr $f:expr) => {}; //~ERROR `$e:expr` is followed by `$f:expr`
| ^^^^^^^ not allowed after `expr` fragments
|
= note: allowed there are: `=>`, `,` or `;`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
-error: `$t:ty` is followed by `$t:ty`, which is not allowed for `ty` fragments
+error: `$t:ty` is followed by `$r:ty`, which is not allowed for `ty` fragments
--> $DIR/macro-follow.rs:60:12
|
-LL | ($t:ty $t:ty) => {}; //~ERROR `$t:ty` is followed by `$t:ty`
+LL | ($t:ty $r:ty) => {}; //~ERROR `$t:ty` is followed by `$r:ty`
| ^^^^^ not allowed after `ty` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
-error: `$t:ty` is followed by `$t:tt`, which is not allowed for `ty` fragments
+error: `$t:ty` is followed by `$r:tt`, which is not allowed for `ty` fragments
--> $DIR/macro-follow.rs:65:12
|
-LL | ($t:ty $t:tt) => {}; //~ERROR `$t:ty` is followed by `$t:tt`
+LL | ($t:ty $r:tt) => {}; //~ERROR `$t:ty` is followed by `$r:tt`
| ^^^^^ not allowed after `ty` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
|
= note: allowed there are: `=>`, `,` or `;`
-error: `$s:stmt` is followed by `$s:stmt`, which is not allowed for `stmt` fragments
+error: `$s:stmt` is followed by `$t:stmt`, which is not allowed for `stmt` fragments
--> $DIR/macro-follow.rs:85:14
|
-LL | ($s:stmt $s:stmt) => {}; //~ERROR `$s:stmt` is followed by `$s:stmt`
+LL | ($s:stmt $t:stmt) => {}; //~ERROR `$s:stmt` is followed by `$t:stmt`
| ^^^^^^^ not allowed after `stmt` fragments
|
= note: allowed there are: `=>`, `,` or `;`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
-error: `$p:path` is followed by `$p:pat`, which is not allowed for `path` fragments
+error: `$p:path` is followed by `$q:pat`, which is not allowed for `path` fragments
--> $DIR/macro-follow.rs:100:14
|
-LL | ($p:path $p:pat) => {}; //~ERROR `$p:path` is followed by `$p:pat`
+LL | ($p:path $q:pat) => {}; //~ERROR `$p:path` is followed by `$q:pat`
| ^^^^^^ not allowed after `path` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
-error: `$p:path` is followed by `$p:path`, which is not allowed for `path` fragments
+error: `$p:path` is followed by `$q:path`, which is not allowed for `path` fragments
--> $DIR/macro-follow.rs:104:14
|
-LL | ($p:path $p:path) => {}; //~ERROR `$p:path` is followed by `$p:path`
+LL | ($p:path $q:path) => {}; //~ERROR `$p:path` is followed by `$q:path`
| ^^^^^^^ not allowed after `path` fragments
|
= note: allowed there are: `{`, `[`, `=>`, `,`, `>`, `=`, `:`, `;`, `|`, `as` or `where`
--- /dev/null
+// Test that duplicate matcher binding names are caught at declaration time, rather than at macro
+// invocation time.
+//
+// FIXME(mark-i-m): Update this when it becomes a hard error.
+
+// compile-pass
+
+#![allow(unused_macros)]
+
+macro_rules! foo1 {
+ ($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding
+ ($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding
+}
+
+macro_rules! foo2 {
+ ($a:ident) => {}; // OK
+ ($a:path) => {}; // OK
+}
+
+macro_rules! foo3 {
+ ($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding
+ ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding
+}
+
+fn main() {}
--- /dev/null
+warning: duplicate matcher binding
+ --> $DIR/macro-multiple-matcher-bindings.rs:11:6
+ |
+LL | ($a:ident, $a:ident) => {}; //~WARNING duplicate matcher binding
+ | ^^^^^^^^ ^^^^^^^^
+ |
+ = note: #[warn(duplicate_matcher_binding_name)] on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
+
+warning: duplicate matcher binding
+ --> $DIR/macro-multiple-matcher-bindings.rs:12:6
+ |
+LL | ($a:ident, $a:path) => {}; //~WARNING duplicate matcher binding
+ | ^^^^^^^^ ^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
+
+warning: duplicate matcher binding
+ --> $DIR/macro-multiple-matcher-bindings.rs:21:6
+ |
+LL | ($a:ident, $($a:ident),*) => {}; //~WARNING duplicate matcher binding
+ | ^^^^^^^^ ^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
+
+warning: duplicate matcher binding
+ --> $DIR/macro-multiple-matcher-bindings.rs:22:8
+ |
+LL | ($($a:ident)+ # $($($a:path),+);*) => {}; //~WARNING duplicate matcher binding
+ | ^^^^^^^^ ^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #57593 <https://github.com/rust-lang/rust/issues/57593>
+
--- /dev/null
+#![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize, unsized_locals)]
+
+// This tests a few edge-cases around `arbitrary_self_types`. Most specifically,
+// it checks that the `ObjectCandidate` you get from method matching can't
+// match a trait with the same DefId as a supertrait but a bad type parameter.
+
+use std::marker::PhantomData;
+
+mod internal {
+ use std::ops::{CoerceUnsized, Deref, DispatchFromDyn};
+ use std::marker::{PhantomData, Unsize};
+
+ pub struct Smaht<T: ?Sized, MISC>(pub Box<T>, pub PhantomData<MISC>);
+
+ impl<T: ?Sized, MISC> Deref for Smaht<T, MISC> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+ impl<T: ?Sized + Unsize<U>, U: ?Sized, MISC> CoerceUnsized<Smaht<U, MISC>>
+ for Smaht<T, MISC>
+ {}
+ impl<T: ?Sized + Unsize<U>, U: ?Sized, MISC> DispatchFromDyn<Smaht<U, MISC>>
+ for Smaht<T, MISC>
+ {}
+
+ pub trait Foo: X<u32> {}
+ pub trait X<T> {
+ fn foo(self: Smaht<Self, T>) -> T;
+ }
+
+ impl X<u32> for () {
+ fn foo(self: Smaht<Self, u32>) -> u32 {
+ 0
+ }
+ }
+
+ pub trait Marker {}
+ impl Marker for dyn Foo {}
+ impl<T: Marker + ?Sized> X<u64> for T {
+ fn foo(self: Smaht<Self, u64>) -> u64 {
+ 1
+ }
+ }
+
+ impl Deref for dyn Foo {
+ type Target = ();
+ fn deref(&self) -> &() { &() }
+ }
+
+ impl Foo for () {}
+}
+
+pub trait FinalFoo {
+ fn foo(&self) -> u8;
+}
+
+impl FinalFoo for () {
+ fn foo(&self) -> u8 { 0 }
+}
+
+mod nuisance_foo {
+ pub trait NuisanceFoo {
+ fn foo(self);
+ }
+
+ impl<T: ?Sized> NuisanceFoo for T {
+ fn foo(self) {}
+ }
+}
+
+
+fn objectcandidate_impl() {
+ let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData);
+ let x: internal::Smaht<dyn internal::Foo, u32> = x;
+
+ // This picks `<dyn internal::Foo as X<u32>>::foo` via `ObjectCandidate`.
+ //
+ // The `TraitCandidate` is not relevant because `X` is not in scope.
+ let z = x.foo();
+
+ // Observe the type of `z` is `u32`
+ let _seetype: () = z; //~ ERROR mismatched types
+ //~| expected (), found u32
+}
+
+fn traitcandidate_impl() {
+ use internal::X;
+
+ let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData);
+ let x: internal::Smaht<dyn internal::Foo, u64> = x;
+
+ // This picks `<dyn internal::Foo as X<u64>>::foo` via `TraitCandidate`.
+ //
+ // The `ObjectCandidate` does not apply, as it only applies to
+ // `X<u32>` (and not `X<u64>`).
+ let z = x.foo();
+
+ // Observe the type of `z` is `u64`
+ let _seetype: () = z; //~ ERROR mismatched types
+ //~| expected (), found u64
+}
+
+fn traitcandidate_impl_with_nuisance() {
+ use internal::X;
+ use nuisance_foo::NuisanceFoo;
+
+ let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData);
+ let x: internal::Smaht<dyn internal::Foo, u64> = x;
+
+ // This picks `<dyn internal::Foo as X<u64>>::foo` via `TraitCandidate`.
+ //
+ // The `ObjectCandidate` does not apply, as it only applies to
+ // `X<u32>` (and not `X<u64>`).
+ //
+ // The NuisanceFoo impl has the same priority as the `X` impl,
+ // so we get a conflict.
+ let z = x.foo(); //~ ERROR multiple applicable items in scope
+}
+
+
+fn neither_impl() {
+ let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData);
+ let x: internal::Smaht<dyn internal::Foo, u64> = x;
+
+ // This can't pick the `TraitCandidate` impl, because `Foo` is not
+ // imported. However, this also can't pick the `ObjectCandidate`
+ // impl, because it only applies to `X<u32>` (and not `X<u64>`).
+ //
+ // Therefore, neither of the candidates is applicable, and we pick
+ // the `FinalFoo` impl after another deref, which will return `u8`.
+ let z = x.foo();
+
+ // Observe the type of `z` is `u8`
+ let _seetype: () = z; //~ ERROR mismatched types
+ //~| expected (), found u8
+}
+
+fn both_impls() {
+ use internal::X;
+
+ let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData);
+ let x: internal::Smaht<dyn internal::Foo, u32> = x;
+
+ // This can pick both the `TraitCandidate` and the `ObjectCandidate` impl.
+ //
+ // However, the `ObjectCandidate` is considered an "inherent candidate",
+ // and therefore has priority over both the `TraitCandidate` as well as
+ // any other "nuisance" candidate" (if present).
+ let z = x.foo();
+
+ // Observe the type of `z` is `u32`
+ let _seetype: () = z; //~ ERROR mismatched types
+ //~| expected (), found u32
+}
+
+
+fn both_impls_with_nuisance() {
+ // Similar to the `both_impls` example, except with a nuisance impl to
+ // make sure the `ObjectCandidate` indeed has a higher priority.
+
+ use internal::X;
+ use nuisance_foo::NuisanceFoo;
+
+ let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData);
+ let x: internal::Smaht<dyn internal::Foo, u32> = x;
+ let z = x.foo();
+
+ // Observe the type of `z` is `u32`
+ let _seetype: () = z; //~ ERROR mismatched types
+ //~| expected (), found u32
+}
+
+fn main() {
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:85:24
+ |
+LL | let _seetype: () = z; //~ ERROR mismatched types
+ | ^ expected (), found u32
+ |
+ = note: expected type `()`
+ found type `u32`
+
+error[E0308]: mismatched types
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:102:24
+ |
+LL | let _seetype: () = z; //~ ERROR mismatched types
+ | ^ expected (), found u64
+ |
+ = note: expected type `()`
+ found type `u64`
+
+error[E0034]: multiple applicable items in scope
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:120:15
+ |
+LL | let z = x.foo(); //~ ERROR multiple applicable items in scope
+ | ^^^ multiple `foo` found
+ |
+note: candidate #1 is defined in an impl of the trait `internal::X` for the type `_`
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:43:9
+ |
+LL | fn foo(self: Smaht<Self, u64>) -> u64 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `_`
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:70:9
+ |
+LL | fn foo(self) {}
+ | ^^^^^^^^^^^^
+note: candidate #3 is defined in the trait `FinalFoo`
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:57:5
+ |
+LL | fn foo(&self) -> u8;
+ | ^^^^^^^^^^^^^^^^^^^^
+ = help: to disambiguate the method call, write `FinalFoo::foo(x)` instead
+
+error[E0308]: mismatched types
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:137:24
+ |
+LL | let _seetype: () = z; //~ ERROR mismatched types
+ | ^ expected (), found u8
+ |
+ = note: expected type `()`
+ found type `u8`
+
+error[E0308]: mismatched types
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:155:24
+ |
+LL | let _seetype: () = z; //~ ERROR mismatched types
+ | ^ expected (), found u32
+ |
+ = note: expected type `()`
+ found type `u32`
+
+error[E0308]: mismatched types
+ --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:172:24
+ |
+LL | let _seetype: () = z; //~ ERROR mismatched types
+ | ^ expected (), found u32
+ |
+ = note: expected type `()`
+ found type `u32`
+
+error: aborting due to 6 previous errors
+
+Some errors occurred: E0034, E0308.
+For more information about an error, try `rustc --explain E0034`.
--- /dev/null
+// compile-pass
+
+// Check that method probing ObjectCandidate works in the presence of
+// auto traits and/or HRTBs.
+
+mod internal {
+ pub trait MyObject<'a> {
+ type Output;
+
+ fn foo(&self) -> Self::Output;
+ }
+
+ impl<'a> MyObject<'a> for () {
+ type Output = &'a u32;
+
+ fn foo(&self) -> Self::Output { &4 }
+ }
+}
+
+fn t1(d: &dyn for<'a> internal::MyObject<'a, Output=&'a u32>) {
+ d.foo();
+}
+
+fn t2(d: &dyn internal::MyObject<'static, Output=&'static u32>) {
+ d.foo();
+}
+
+fn t3(d: &(dyn for<'a> internal::MyObject<'a, Output=&'a u32> + Sync)) {
+ d.foo();
+}
+
+fn t4(d: &(dyn internal::MyObject<'static, Output=&'static u32> + Sync)) {
+ d.foo();
+}
+
+fn main() {
+ t1(&());
+ t2(&());
+ t3(&());
+ t4(&());
+}
-// error-pattern:can't use type parameters from outer function
+// error-pattern:can't use generic parameters from outer function
fn hd<U>(v: Vec<U> ) -> U {
fn hd1(w: [U]) -> U { return w[0]; }
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/nested-ty-params.rs:3:16
|
LL | fn hd<U>(v: Vec<U> ) -> U {
| - type variable from outer function
LL | fn hd1(w: [U]) -> U { return w[0]; }
- | --- ^ use of type variable from outer function
+ | --- ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `hd1<U>`
+ | help: try using a local generic parameter instead: `hd1<U>`
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/nested-ty-params.rs:3:23
|
LL | fn hd<U>(v: Vec<U> ) -> U {
| - type variable from outer function
LL | fn hd1(w: [U]) -> U { return w[0]; }
- | --- ^ use of type variable from outer function
+ | --- ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `hd1<U>`
+ | help: try using a local generic parameter instead: `hd1<U>`
error: aborting due to 2 previous errors
--- /dev/null
+// run-pass
+
+#![allow(dead_code)]
+
+trait Range {
+ const FIRST: u8;
+ const LAST: u8;
+}
+
+struct OneDigit;
+impl Range for OneDigit {
+ const FIRST: u8 = 0;
+ const LAST: u8 = 9;
+}
+
+struct TwoDigits;
+impl Range for TwoDigits {
+ const FIRST: u8 = 10;
+ const LAST: u8 = 99;
+}
+
+struct ThreeDigits;
+impl Range for ThreeDigits {
+ const FIRST: u8 = 100;
+ const LAST: u8 = 255;
+}
+
+fn digits(x: u8) -> u32 {
+ match x {
+ OneDigit::FIRST...OneDigit::LAST => 1,
+ TwoDigits::FIRST...TwoDigits::LAST => 2,
+ ThreeDigits::FIRST...ThreeDigits::LAST => 3,
+ _ => unreachable!(),
+ }
+}
+
+fn main() {
+ assert_eq!(digits(100), 3);
+}
+error: unexpected token: `;`
+ --> $DIR/parser-recovery-2.rs:12:15
+ |
+LL | let x = y.; //~ ERROR unexpected token
+ | ^
+
error: incorrect close delimiter: `)`
--> $DIR/parser-recovery-2.rs:8:5
|
LL | ) //~ ERROR incorrect close delimiter: `)`
| ^ incorrect close delimiter
-error: unexpected token: `;`
- --> $DIR/parser-recovery-2.rs:12:15
- |
-LL | let x = y.; //~ ERROR unexpected token
- | ^
-
error[E0425]: cannot find function `foo` in this scope
--> $DIR/parser-recovery-2.rs:7:17
|
type A = for<'a: 'b,> fn(); // OK(rejected later by ast_validation)
type A = for<'a: 'b +> fn(); // OK (rejected later by ast_validation)
type A = for<'a, T> fn(); // OK (rejected later by ast_validation)
-type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,`
+type A = for<,> fn(); //~ ERROR expected one of `>`, `const`, identifier, or lifetime, found `,`
fn main() {}
-error: expected one of `>`, identifier, or lifetime, found `,`
+error: expected one of `>`, `const`, identifier, or lifetime, found `,`
--> $DIR/bounds-lifetime.rs:9:14
|
-LL | type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,`
- | ^ expected one of `>`, identifier, or lifetime here
+LL | type A = for<,> fn(); //~ ERROR expected one of `>`, `const`, identifier, or lifetime, found `,`
+ | ^ expected one of `>`, `const`, identifier, or lifetime here
error: aborting due to previous error
option.map(|some| 42;
//~^ ERROR: expected one of
-} //~ ERROR: incorrect close delimiter
+}
//~^ ERROR: expected expression, found `)`
fn main() {}
-error: incorrect close delimiter: `}`
- --> $DIR/issue-10636-2.rs:8:1
- |
-LL | pub fn trace_option(option: Option<isize>) {
- | - close delimiter possibly meant for this
-LL | option.map(|some| 42;
- | - un-closed delimiter
-...
-LL | } //~ ERROR: incorrect close delimiter
- | ^ incorrect close delimiter
-
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/issue-10636-2.rs:5:25
|
LL | option.map(|some| 42;
- | ^ expected one of `)`, `,`, `.`, `?`, or an operator here
+ | - ^
+ | | |
+ | | help: `)` may belong here
+ | unclosed delimiter
error: expected expression, found `)`
--> $DIR/issue-10636-2.rs:8:1
|
-LL | } //~ ERROR: incorrect close delimiter
+LL | }
| ^ expected expression
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
--> $DIR/issue-14303-enum.rs:1:15
|
LL | enum X<'a, T, 'b> {
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | enum X<'a, 'b, T> {
- | ^^^ --
+ | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
error: aborting due to previous error
--> $DIR/issue-14303-fn-def.rs:1:15
|
LL | fn foo<'a, T, 'b>(x: &'a T) {}
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | fn foo<'a, 'b, T>(x: &'a T) {}
- | ^^^ --
+ | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
error: aborting due to previous error
let _x = (*start..*end)
.map(|x| S { a: start, b: end })
.collect::<Vec<S<_, 'a>>>();
- //~^ ERROR lifetime parameters must be declared prior to type parameters
+ //~^ ERROR lifetime arguments must be declared prior to type arguments
}
fn main() {}
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime arguments must be declared prior to type arguments
--> $DIR/issue-14303-fncall.rs:13:29
|
LL | .collect::<Vec<S<_, 'a>>>();
- | ^^ must be declared prior to type parameters
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | .collect::<Vec<S<'a, _>>>();
- | ^^^ --
+ | ^^
error: aborting due to previous error
--> $DIR/issue-14303-impl.rs:3:13
|
LL | impl<'a, T, 'b> X<T> {}
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | impl<'a, 'b, T> X<T> {}
- | ^^^ --
+ | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
error: aborting due to previous error
}
fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
-//~^ ERROR lifetime parameters must be declared prior to type parameters
+//~^ ERROR lifetime arguments must be declared prior to type arguments
fn main() {}
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime arguments must be declared prior to type arguments
--> $DIR/issue-14303-path.rs:10:40
|
LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {}
- | ^^ ^^ must be declared prior to type parameters
- | |
- | must be declared prior to type parameters
-help: move the lifetime parameters prior to the first type parameter
- |
-LL | fn bar<'a, 'b, 'c, T>(x: foo::X<'a, 'b, 'c, T>) {}
- | ^^^ ^^^ --
+ | ^^ ^^
error: aborting due to previous error
--> $DIR/issue-14303-struct.rs:1:17
|
LL | struct X<'a, T, 'b> {
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | struct X<'a, 'b, T> {
- | ^^^ --
+ | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
error: aborting due to previous error
--> $DIR/issue-14303-trait.rs:1:18
|
LL | trait Foo<'a, T, 'b> {}
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | trait Foo<'a, 'b, T> {}
- | ^^^ --
+ | --------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T>`
error: aborting due to previous error
trait Trait<T> { type Item; }
pub fn test<W, I: Trait<Item=(), W> >() {}
-//~^ ERROR type parameters must be declared prior to associated type bindings
+//~^ ERROR associated type bindings must be declared after generic parameters
fn main() { }
-error: type parameters must be declared prior to associated type bindings
- --> $DIR/issue-32214.rs:5:34
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/issue-32214.rs:5:25
|
LL | pub fn test<W, I: Trait<Item=(), W> >() {}
- | ^ must be declared prior to associated type bindings
-help: move the type parameter prior to the first associated type binding
- |
-LL | pub fn test<W, I: Trait<W, Item=()> >() {}
- | ^^ --
+ | -------^^^
+ | |
+ | this associated type binding should be moved after the generic parameters
error: aborting due to previous error
+error: unexpected close delimiter: `}`
+ --> $DIR/macro-mismatched-delim-paren-brace.rs:5:1
+ |
+LL | } //~ ERROR unexpected close delimiter: `}`
+ | ^ unexpected close delimiter
+
error: incorrect close delimiter: `}`
--> $DIR/macro-mismatched-delim-paren-brace.rs:4:5
|
LL | } //~ ERROR incorrect close delimiter
| ^ incorrect close delimiter
-error: unexpected close delimiter: `}`
- --> $DIR/macro-mismatched-delim-paren-brace.rs:5:1
- |
-LL | } //~ ERROR unexpected close delimiter: `}`
- | ^ unexpected close delimiter
-
error: aborting due to 2 previous errors
-type mut_box = Box<mut isize>; //~ ERROR expected one of `>`, lifetime, or type, found `mut`
+type mut_box = Box<mut isize>; //~ ERROR expected one of `>`, const, lifetime, or type, found `mut`
-error: expected one of `>`, lifetime, or type, found `mut`
+error: expected one of `>`, const, lifetime, or type, found `mut`
--> $DIR/removed-syntax-uniq-mut-ty.rs:1:20
|
-LL | type mut_box = Box<mut isize>; //~ ERROR expected one of `>`, lifetime, or type, found `mut`
- | ^^^ expected one of `>`, lifetime, or type here
+LL | type mut_box = Box<mut isize>; //~ ERROR expected one of `>`, const, lifetime, or type, found `mut`
+ | ^^^ expected one of `>`, const, lifetime, or type here
error: aborting due to previous error
fn outer(&self) {
enum Foo<B> {
Variance(A)
- //~^ ERROR can't use type parameters from outer function
+ //~^ ERROR can't use generic parameters from outer function
}
}
}
trait TraitB<A> {
fn outer(&self) {
struct Foo<B>(A);
- //~^ ERROR can't use type parameters from outer function
+ //~^ ERROR can't use generic parameters from outer function
}
}
trait TraitC<A> {
fn outer(&self) {
struct Foo<B> { a: A }
- //~^ ERROR can't use type parameters from outer function
+ //~^ ERROR can't use generic parameters from outer function
}
}
trait TraitD<A> {
fn outer(&self) {
fn foo<B>(a: A) { }
- //~^ ERROR can't use type parameters from outer function
+ //~^ ERROR can't use generic parameters from outer function
}
}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/resolve-type-param-in-item-in-trait.rs:8:22
|
LL | trait TraitA<A> {
| - type variable from outer function
LL | fn outer(&self) {
- | ----- try adding a local type parameter in this method instead
+ | ----- try adding a local generic parameter in this method instead
LL | enum Foo<B> {
LL | Variance(A)
- | ^ use of type variable from outer function
+ | ^ use of generic parameter from outer function
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/resolve-type-param-in-item-in-trait.rs:16:23
|
LL | trait TraitB<A> {
| - type variable from outer function
LL | fn outer(&self) {
- | ----- try adding a local type parameter in this method instead
+ | ----- try adding a local generic parameter in this method instead
LL | struct Foo<B>(A);
- | ^ use of type variable from outer function
+ | ^ use of generic parameter from outer function
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/resolve-type-param-in-item-in-trait.rs:23:28
|
LL | trait TraitC<A> {
| - type variable from outer function
LL | fn outer(&self) {
- | ----- try adding a local type parameter in this method instead
+ | ----- try adding a local generic parameter in this method instead
LL | struct Foo<B> { a: A }
- | ^ use of type variable from outer function
+ | ^ use of generic parameter from outer function
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/resolve-type-param-in-item-in-trait.rs:30:22
|
LL | trait TraitD<A> {
| - type variable from outer function
LL | fn outer(&self) {
LL | fn foo<B>(a: A) { }
- | ------ ^ use of type variable from outer function
+ | ------ ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `foo<B, A>`
+ | help: try using a local generic parameter instead: `foo<B, A>`
error: aborting due to 4 previous errors
//~| expected type `()`
//~| found type `std::result::Result<bool, std::io::Error>`
//~| expected one of
- } else { //~ ERROR: incorrect close delimiter: `}`
+ } else {
//~^ ERROR: expected one of
//~| unexpected token
Ok(false);
-error: incorrect close delimiter: `}`
- --> $DIR/token-error-correct-3.rs:20:9
- |
-LL | if !is_directory(path.as_ref()) { //~ ERROR: cannot find function `is_directory`
- | - close delimiter possibly meant for this
-LL | callback(path.as_ref(); //~ ERROR expected one of
- | - un-closed delimiter
-...
-LL | } else { //~ ERROR: incorrect close delimiter: `}`
- | ^ incorrect close delimiter
-
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
--> $DIR/token-error-correct-3.rs:14:35
|
LL | callback(path.as_ref(); //~ ERROR expected one of
- | ^ expected one of `)`, `,`, `.`, `?`, or an operator here
+ | - ^
+ | | |
+ | | help: `)` may belong here
+ | unclosed delimiter
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
--> $DIR/token-error-correct-3.rs:20:9
LL | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
| - expected one of `.`, `;`, `?`, `}`, or an operator here
...
-LL | } else { //~ ERROR: incorrect close delimiter: `}`
+LL | } else {
| ^ unexpected token
error[E0425]: cannot find function `is_directory` in this scope
= note: expected type `()`
found type `std::result::Result<bool, std::io::Error>`
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
Some errors occurred: E0308, E0425.
For more information about an error, try `rustc --explain E0308`.
fn main() {
foo(bar(;
- //~^ ERROR: expected expression, found `;`
+ //~^ ERROR cannot find function `bar` in this scope
}
//~^ ERROR: incorrect close delimiter: `}`
+
+fn foo(_: usize) {}
| - close delimiter possibly meant for this
LL | foo(bar(;
| - un-closed delimiter
-LL | //~^ ERROR: expected expression, found `;`
+LL | //~^ ERROR cannot find function `bar` in this scope
LL | }
| ^ incorrect close delimiter
-error: expected expression, found `;`
- --> $DIR/token-error-correct.rs:4:13
+error[E0425]: cannot find function `bar` in this scope
+ --> $DIR/token-error-correct.rs:4:9
|
LL | foo(bar(;
- | ^ expected expression
+ | ^^^ not found in this scope
error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0425`.
trait Foo {
type Bar<,>;
- //~^ ERROR expected one of `>`, identifier, or lifetime, found `,`
+ //~^ ERROR expected one of `>`, `const`, identifier, or lifetime, found `,`
}
fn main() {}
-error: expected one of `>`, identifier, or lifetime, found `,`
+error: expected one of `>`, `const`, identifier, or lifetime, found `,`
--> $DIR/empty_generics.rs:5:14
|
LL | type Bar<,>;
- | ^ expected one of `>`, identifier, or lifetime here
+ | ^ expected one of `>`, `const`, identifier, or lifetime here
warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
--> $DIR/empty_generics.rs:1:12
--> $DIR/suggest-move-lifetimes.rs:1:13
|
LL | struct A<T, 'a> { //~ ERROR lifetime parameters must be declared
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | struct A<'a, T> { //~ ERROR lifetime parameters must be declared
- | ^^^ --
+ | ----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:5:13
|
LL | struct B<T, 'a, U> { //~ ERROR lifetime parameters must be declared
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | struct B<'a, T, U> { //~ ERROR lifetime parameters must be declared
- | ^^^ --
+ | ----^^---- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:10:16
|
LL | struct C<T, U, 'a> { //~ ERROR lifetime parameters must be declared
- | ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | struct C<'a, T, U> { //~ ERROR lifetime parameters must be declared
- | ^^^ --
+ | -------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, U>`
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:15:16
|
LL | struct D<T, U, 'a, 'b, V, 'c> { //~ ERROR lifetime parameters must be declared
- | ^^ ^^ ^^
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | struct D<'a, 'b, 'c, T, U, V> { //~ ERROR lifetime parameters must be declared
- | ^^^ ^^^ ^^^ -- --
+ | -------^^--^^-----^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, 'c, T, U, V>`
error: aborting due to 4 previous errors
type C;
}
-struct A<T, M: One<A=(), T>> { //~ ERROR type parameters must be declared
+struct A<T, M: One<A=(), T>> { //~ ERROR associated type bindings must be declared after generic parameters
m: M,
t: T,
}
struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
-//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
+//~^ ERROR associated type bindings must be declared after generic parameters
+//~^^ ERROR lifetime arguments must be declared prior to type arguments
m: M,
t: &'a T,
}
-struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR type parameters must be declared
+struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR associated type bindings must be declared after generic parameters
m: M,
t: T,
u: U,
}
struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
-//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
+//~^ ERROR associated type bindings must be declared after generic parameters
+//~^^ ERROR lifetime arguments must be declared prior to type arguments
m: M,
t: &'a T,
u: &'b U,
v: &'c V,
}
-struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR type parameters must be declared
+struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR associated type bindings must be declared after generic parameters
m: M,
t: T,
u: U,
}
struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
-//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
+//~^ ERROR associated type bindings must be declared after generic parameters
+//~^^ ERROR lifetime arguments must be declared prior to type arguments
m: M,
t: &'a T,
u: &'b U,
v: &'c V,
}
-struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR type parameters must be declared
+struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR associated type bindings must be declared after generic parameters
m: M,
t: T,
u: U,
}
struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
-//~^ ERROR generic arguments must declare lifetimes, types and associated type bindings in that order
+//~^ ERROR associated type bindings must be declared after generic parameters
+//~^^ ERROR lifetime arguments must be declared prior to type arguments
m: M,
t: &'a T,
u: &'b U,
-error: type parameters must be declared prior to associated type bindings
- --> $DIR/suggest-move-types.rs:28:26
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:28:20
|
-LL | struct A<T, M: One<A=(), T>> { //~ ERROR type parameters must be declared
- | ^ must be declared prior to associated type bindings
-help: move the type parameter prior to the first associated type binding
- |
-LL | struct A<T, M: One<T, A=()>> { //~ ERROR type parameters must be declared
- | ^^ --
+LL | struct A<T, M: One<A=(), T>> { //~ ERROR associated type bindings must be declared after generic parameters
+ | ----^^^
+ | |
+ | this associated type binding should be moved after the generic parameters
-error: generic arguments must declare lifetimes, types and associated type bindings in that order
- --> $DIR/suggest-move-types.rs:34:46
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:34:37
|
LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
- | ^ ^^ must be declared prior to type parameters
- | |
- | must be declared prior to associated type bindings
-help: move the parameters
- |
-LL | struct Al<'a, T, M: OneWithLifetime<'a, T, A=()>> {
- | ^^^ ^^ --
+ | ----^^^^^^^
+ | |
+ | this associated type binding should be moved after the generic parameters
-error: type parameters must be declared prior to associated type bindings
- --> $DIR/suggest-move-types.rs:40:46
- |
-LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR type parameters must be declared
- | ^ ^ ^ must be declared prior to associated type bindings
- | | |
- | | must be declared prior to associated type bindings
- | must be declared prior to associated type bindings
-help: move the type parameters prior to the first associated type binding
- |
-LL | struct B<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
- | ^^ ^^ ^^ --
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:41:28
+ |
+LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR associated type bindings must be declared after generic parameters
+ | ----^^----^^----^^^^^^^^^
+ | | | |
+ | | | this associated type binding should be moved after the generic parameters
+ | | this associated type binding should be moved after the generic parameters
+ | this associated type binding should be moved after the generic parameters
-error: generic arguments must declare lifetimes, types and associated type bindings in that order
- --> $DIR/suggest-move-types.rs:47:80
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:48:53
|
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
- | ^ ^ ^ ^^ ^^ ^^ must be declared prior to type parameters
- | | | | | |
- | | | | | must be declared prior to type parameters
- | | | | must be declared prior to type parameters
- | | | must be declared prior to associated type bindings
- | | must be declared prior to associated type bindings
- | must be declared prior to associated type bindings
-help: move the parameters
- |
-LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
- | ^^^ ^^^ ^^^ ^^ ^^ ^^ --
+ | ----^^----^^----^^^^^^^^^^^^^^^^^^^^^
+ | | | |
+ | | | this associated type binding should be moved after the generic parameters
+ | | this associated type binding should be moved after the generic parameters
+ | this associated type binding should be moved after the generic parameters
-error: type parameters must be declared prior to associated type bindings
- --> $DIR/suggest-move-types.rs:55:49
- |
-LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR type parameters must be declared
- | ^ ^ must be declared prior to associated type bindings
- | |
- | must be declared prior to associated type bindings
-help: move the type parameters prior to the first associated type binding
- |
-LL | struct C<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
- | ^^ ^^ --
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:57:28
+ |
+LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR associated type bindings must be declared after generic parameters
+ | ^^^----^^----^^----^^^^^^
+ | | | |
+ | | | this associated type binding should be moved after the generic parameters
+ | | this associated type binding should be moved after the generic parameters
+ | this associated type binding should be moved after the generic parameters
-error: generic arguments must declare lifetimes, types and associated type bindings in that order
- --> $DIR/suggest-move-types.rs:62:56
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:64:53
|
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
- | ^^ ^ ^^ ^ ^^ must be declared prior to type parameters
- | | | | |
- | | | | must be declared prior to associated type bindings
- | | | must be declared prior to type parameters
- | | must be declared prior to associated type bindings
- | must be declared prior to type parameters
-help: move the parameters
+ | ^^^^^^^----^^----^^----^^^^^^^^^^^^^^
+ | | | |
+ | | | this associated type binding should be moved after the generic parameters
+ | | this associated type binding should be moved after the generic parameters
+ | this associated type binding should be moved after the generic parameters
+
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:73:28
+ |
+LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR associated type bindings must be declared after generic parameters
+ | ^^^----^^----^^^^^----^^^
+ | | | |
+ | | | this associated type binding should be moved after the generic parameters
+ | | this associated type binding should be moved after the generic parameters
+ | this associated type binding should be moved after the generic parameters
+
+error: associated type bindings must be declared after generic parameters
+ --> $DIR/suggest-move-types.rs:80:53
|
-LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
- | ^^^ ^^^ ^^^ -- ^^ ^^ --
+LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
+ | ^^^^^^^----^^----^^^^^^^^^----^^^^^^^
+ | | | |
+ | | | this associated type binding should be moved after the generic parameters
+ | | this associated type binding should be moved after the generic parameters
+ | this associated type binding should be moved after the generic parameters
-error: type parameters must be declared prior to associated type bindings
- --> $DIR/suggest-move-types.rs:70:43
+error: lifetime arguments must be declared prior to type arguments
+ --> $DIR/suggest-move-types.rs:34:46
|
-LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR type parameters must be declared
- | ^ ^ must be declared prior to associated type bindings
- | |
- | must be declared prior to associated type bindings
-help: move the type parameters prior to the first associated type binding
+LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
+ | ^^
+
+error: lifetime arguments must be declared prior to type arguments
+ --> $DIR/suggest-move-types.rs:48:80
|
-LL | struct D<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> { //~ ERROR type parameters must be declared
- | ^^ ^^ -- --
+LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
+ | ^^ ^^ ^^
-error: generic arguments must declare lifetimes, types and associated type bindings in that order
- --> $DIR/suggest-move-types.rs:77:56
+error: lifetime arguments must be declared prior to type arguments
+ --> $DIR/suggest-move-types.rs:64:56
|
-LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
- | ^^ ^ ^^ ^ ^^ must be declared prior to type parameters
- | | | | |
- | | | | must be declared prior to associated type bindings
- | | | must be declared prior to type parameters
- | | must be declared prior to associated type bindings
- | must be declared prior to type parameters
-help: move the parameters
+LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
+ | ^^ ^^ ^^
+
+error: lifetime arguments must be declared prior to type arguments
+ --> $DIR/suggest-move-types.rs:80:56
|
-LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A=(), B=(), C=()>> {
- | ^^^ ^^^ ^^^ -- ^^ ^^ -- --
+LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
+ | ^^ ^^ ^^
-error: aborting due to 8 previous errors
+error: aborting due to 12 previous errors
//~^ ERROR wrong number of lifetime arguments: expected 1, found 2
//~| ERROR wrong number of type arguments: expected 1, found 0
let _: S<'static +, 'static>;
- //~^ ERROR lifetime parameters must be declared prior to type parameters
+ //~^ ERROR lifetime arguments must be declared prior to type arguments
//~| ERROR at least one non-builtin trait is required for an object type
}
-error: lifetime parameters must be declared prior to type parameters
+error: lifetime arguments must be declared prior to type arguments
--> $DIR/trait-object-vs-lifetime.rs:14:25
|
LL | let _: S<'static +, 'static>;
- | ^^^^^^^ must be declared prior to type parameters
-help: move the lifetime parameter prior to the first type parameter
- |
-LL | let _: S<'static, 'static +>;
- | ^^^^^^^^ --
+ | ^^^^^^^
error[E0224]: at least one non-builtin trait is required for an object type
--> $DIR/trait-object-vs-lifetime.rs:9:23
-// error-pattern:can't use type parameters from outer function
+// error-pattern:can't use generic parameters from outer function
fn foo<T>(x: T) {
fn bar(f: Box<FnMut(T) -> T>) { }
}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/type-arg-out-of-scope.rs:3:25
|
LL | fn foo<T>(x: T) {
| - type variable from outer function
LL | fn bar(f: Box<FnMut(T) -> T>) { }
- | --- ^ use of type variable from outer function
+ | --- ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `bar<T>`
+ | help: try using a local generic parameter instead: `bar<T>`
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/type-arg-out-of-scope.rs:3:31
|
LL | fn foo<T>(x: T) {
| - type variable from outer function
LL | fn bar(f: Box<FnMut(T) -> T>) { }
- | --- ^ use of type variable from outer function
+ | --- ^ use of generic parameter from outer function
| |
- | help: try using a local type parameter instead: `bar<T>`
+ | help: try using a local generic parameter instead: `bar<T>`
error: aborting due to 2 previous errors
fn main() {
let v = vec![0];
- const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item
+ const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant
let s: [u32; l] = v.into_iter().collect();
//~^ ERROR evaluation of constant value failed
}
-error[E0434]: can't capture dynamic environment in a fn item
+error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/type-dependent-def-issue-49241.rs:3:22
|
-LL | const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item
- | ^
- |
- = help: use the `|| { ... }` closure form instead
+LL | const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant
+ | ^ non-constant value
error[E0080]: evaluation of constant value failed
--> $DIR/type-dependent-def-issue-49241.rs:4:18
error: aborting due to 2 previous errors
-Some errors occurred: E0080, E0434.
+Some errors occurred: E0080, E0435.
For more information about an error, try `rustc --explain E0080`.
//~^ NOTE `Self` type implicitly declared here, by this `impl`
fn banana(&mut self) {
fn peach(this: &Self) {
- //~^ ERROR can't use type parameters from outer function
- //~| NOTE use of type variable from outer function
+ //~^ ERROR can't use generic parameters from outer function
+ //~| NOTE use of generic parameter from outer function
//~| NOTE use a type here instead
}
}
-error[E0401]: can't use type parameters from outer function
+error[E0401]: can't use generic parameters from outer function
--> $DIR/use-self-in-inner-fn.rs:6:25
|
LL | impl A {
LL | fn peach(this: &Self) {
| ^^^^
| |
- | use of type variable from outer function
+ | use of generic parameter from outer function
| use a type here instead
error: aborting due to previous error
authors = ["The Rust Project Developers"]
name = "compiletest"
version = "0.0.0"
+edition = "2018"
[dependencies]
diff = "0.1.10"
use std::str::FromStr;
use test::ColorConfig;
-use util::PathBufExt;
+use crate::util::PathBufExt;
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Mode {
}
impl fmt::Display for Mode {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match *self {
CompileFail => "compile-fail",
RunFail => "run-fail",
}
impl fmt::Display for ErrorKind {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ErrorKind::Help => write!(f, "help message"),
ErrorKind::Error => write!(f, "error"),
use std::io::BufReader;
use std::path::{Path, PathBuf};
-use common::{self, CompareMode, Config, Mode};
-use util;
+use crate::common::{self, CompareMode, Config, Mode};
+use crate::util;
-use extract_gdb_version;
+use crate::extract_gdb_version;
/// Whether to ignore the test.
#[derive(Clone, Copy, PartialEq, Debug)]
-use errors::{Error, ErrorKind};
-use runtest::ProcRes;
+use crate::errors::{Error, ErrorKind};
+use crate::runtest::ProcRes;
use serde_json;
use std::path::Path;
use std::str::FromStr;
#![crate_name = "compiletest"]
#![feature(test)]
-#![deny(warnings)]
+#![deny(warnings, rust_2018_idioms)]
-extern crate diff;
-extern crate env_logger;
-extern crate filetime;
-extern crate getopts;
#[cfg(unix)]
extern crate libc;
#[macro_use]
extern crate log;
-extern crate regex;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate serde_derive;
-extern crate serde_json;
extern crate test;
-extern crate rustfix;
-extern crate walkdir;
-use common::CompareMode;
-use common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
-use common::{Config, TestPaths};
-use common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
+use crate::common::CompareMode;
+use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
+use crate::common::{Config, TestPaths};
+use crate::common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
use filetime::FileTime;
use getopts::Options;
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
use test::ColorConfig;
-use util::logv;
+use crate::util::logv;
use walkdir::WalkDir;
+use env_logger;
+use getopts;
use self::header::{EarlyProps, Ignore};
#[cfg(windows)]
mod imp {
- extern crate miow;
- extern crate winapi;
-
use std::io;
use std::os::windows::prelude::*;
use std::process::{ChildStderr, ChildStdout};
use std::slice;
- use self::miow::iocp::{CompletionPort, CompletionStatus};
- use self::miow::pipe::NamedPipe;
- use self::miow::Overlapped;
- use self::winapi::shared::winerror::ERROR_BROKEN_PIPE;
+ use miow::iocp::{CompletionPort, CompletionStatus};
+ use miow::pipe::NamedPipe;
+ use miow::Overlapped;
+ use winapi::shared::winerror::ERROR_BROKEN_PIPE;
struct Pipe<'a> {
dst: &'a mut Vec<u8>,
-use common::CompareMode;
-use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
-use common::{output_base_dir, output_base_name, output_testname_unique};
-use common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc};
-use common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind};
-use common::{Config, TestPaths};
-use common::{Incremental, MirOpt, RunMake, Ui};
+use crate::common::CompareMode;
+use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
+use crate::common::{output_base_dir, output_base_name, output_testname_unique};
+use crate::common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc};
+use crate::common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind};
+use crate::common::{Config, TestPaths};
+use crate::common::{Incremental, MirOpt, RunMake, Ui};
use diff;
-use errors::{self, Error, ErrorKind};
+use crate::errors::{self, Error, ErrorKind};
use filetime::FileTime;
-use header::TestProps;
-use json;
+use crate::header::TestProps;
+use crate::json;
use regex::Regex;
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
-use util::{logv, PathBufExt};
+use crate::util::{logv, PathBufExt};
use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet, VecDeque};
use std::process::{Child, Command, ExitStatus, Output, Stdio};
use std::str;
-use extract_gdb_version;
-use is_android_gdb_target;
+use crate::extract_gdb_version;
+use crate::is_android_gdb_target;
#[cfg(windows)]
fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
}
fn make_cmdline(&self, command: &Command, libpath: &str) -> String {
- use util;
+ use crate::util;
// Linux and mac don't require adjusting the library search path
if cfg!(unix) {
}
fn create_stamp(&self) {
- let stamp = ::stamp(&self.config, self.testpaths, self.revision);
+ let stamp = crate::stamp(&self.config, self.testpaths, self.revision);
fs::write(&stamp, compute_stamp_hash(&self.config)).unwrap();
}
}
where
T: AsRef<str> + fmt::Debug,
{
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
if let &ExpectedLine::Text(ref t) = self {
write!(formatter, "{:?}", t)
} else {
}
fn read2_abbreviated(mut child: Child) -> io::Result<Output> {
- use read2::read2;
+ use crate::read2::read2;
use std::mem::replace;
const HEAD_LEN: usize = 160 * 1024;
use std::ffi::OsStr;
use std::env;
use std::path::PathBuf;
-use common::Config;
+use crate::common::Config;
/// Conversion table from triple OS name to Rust SYSNAME
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
authors = ["The Rust Project Developers"]
name = "error_index_generator"
version = "0.0.0"
+edition = "2018"
[dependencies]
rustdoc = { path = "../../librustdoc" }
#![feature(rustc_private)]
+#![deny(rust_2018_idioms)]
+
extern crate env_logger;
extern crate syntax;
-extern crate rustdoc;
extern crate serialize as rustc_serialize;
use std::collections::BTreeMap;
name = "rustdoc-tool"
version = "0.0.0"
authors = ["The Rust Project Developers"]
+edition = "2018"
# Cargo adds a number of paths to the dylib search path on windows, which results in
# the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
+#![deny(rust_2018_idioms)]
+
#![feature(link_args)]
#[allow(unused_attributes)]
// See src/rustc/rustc.rs for the corresponding rustc settings.
extern {}
-extern crate rustdoc;
-
fn main() { rustdoc::main() }