Auto merge of #66180 - Centril:rollup-c1ji943, r=Centril

Rollup of 5 pull requests

Successful merges:

 - #59789 (Revert two unapproved changes to rustc_typeck.)
 - #65752 (Use structured suggestions for missing associated items)
 - #65884 (syntax: ABI-oblivious grammar)
 - #65974 (A scheme for more macro-matcher friendly pre-expansion gating)
 - #66017 (Add future incompatibility lint for `array.into_iter()`)

Failed merges:

 - #66056 (rustc_metadata: Some reorganization of the module structure)

r? @ghost
This commit is contained in:
bors 2019-11-07 07:55:39 +00:00
commit 50f8aadd74
82 changed files with 1469 additions and 1062 deletions

View file

@ -3762,7 +3762,6 @@ dependencies = [
"rustc", "rustc",
"rustc_codegen_utils", "rustc_codegen_utils",
"rustc_data_structures", "rustc_data_structures",
"rustc_target",
"serde_json", "serde_json",
"syntax", "syntax",
"syntax_pos", "syntax_pos",
@ -4362,7 +4361,6 @@ dependencies = [
"rustc_errors", "rustc_errors",
"rustc_index", "rustc_index",
"rustc_lexer", "rustc_lexer",
"rustc_target",
"scoped-tls", "scoped-tls",
"serialize", "serialize",
"smallvec 1.0.0", "smallvec 1.0.0",
@ -4380,7 +4378,6 @@ dependencies = [
"rustc_errors", "rustc_errors",
"rustc_index", "rustc_index",
"rustc_lexer", "rustc_lexer",
"rustc_target",
"scoped-tls", "scoped-tls",
"serialize", "serialize",
"smallvec 1.0.0", "smallvec 1.0.0",

View file

@ -205,6 +205,7 @@ pub trait FromIterator<A>: Sized {
/// .collect() /// .collect()
/// } /// }
/// ``` /// ```
#[rustc_diagnostic_item = "IntoIterator"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait IntoIterator { pub trait IntoIterator {
/// The type of the elements being iterated over. /// The type of the elements being iterated over.

View file

@ -2336,6 +2336,7 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC.
E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0657, // `impl Trait` can only capture lifetimes bound at the fn level
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
E0703, // invalid ABI
// E0707, // multiple elided lifetimes used in arguments of `async fn` // E0707, // multiple elided lifetimes used in arguments of `async fn`
E0708, // `async` non-`move` closures with parameters are not currently E0708, // `async` non-`move` closures with parameters are not currently
// supported // supported

View file

@ -1216,7 +1216,7 @@ impl<'a> LoweringContext<'a> {
ImplTraitContext::disallowed(), ImplTraitContext::disallowed(),
), ),
unsafety: this.lower_unsafety(f.unsafety), unsafety: this.lower_unsafety(f.unsafety),
abi: f.abi, abi: this.lower_abi(f.abi),
decl: this.lower_fn_decl(&f.decl, None, false, None), decl: this.lower_fn_decl(&f.decl, None, false, None),
param_names: this.lower_fn_params_to_names(&f.decl), param_names: this.lower_fn_params_to_names(&f.decl),
})) }))

View file

@ -12,6 +12,7 @@ use crate::hir::def::{Res, DefKind};
use crate::util::nodemap::NodeMap; use crate::util::nodemap::NodeMap;
use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::thin_vec::ThinVec;
use rustc_target::spec::abi;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -735,7 +736,7 @@ impl LoweringContext<'_> {
fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod { fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
hir::ForeignMod { hir::ForeignMod {
abi: fm.abi, abi: self.lower_abi(fm.abi),
items: fm.items items: fm.items
.iter() .iter()
.map(|x| self.lower_foreign_item(x)) .map(|x| self.lower_foreign_item(x))
@ -1291,10 +1292,30 @@ impl LoweringContext<'_> {
unsafety: self.lower_unsafety(h.unsafety), unsafety: self.lower_unsafety(h.unsafety),
asyncness: self.lower_asyncness(h.asyncness.node), asyncness: self.lower_asyncness(h.asyncness.node),
constness: self.lower_constness(h.constness), constness: self.lower_constness(h.constness),
abi: h.abi, abi: self.lower_abi(h.abi),
} }
} }
pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
self.error_on_invalid_abi(abi);
abi::Abi::Rust
})
}
fn error_on_invalid_abi(&self, abi: Abi) {
struct_span_err!(
self.sess,
abi.span,
E0703,
"invalid ABI: found `{}`",
abi.symbol
)
.span_label(abi.span, "invalid ABI")
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
.emit();
}
pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety { pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
match u { match u {
Unsafety::Unsafe => hir::Unsafety::Unsafe, Unsafety::Unsafe => hir::Unsafety::Unsafe,

View file

@ -1075,6 +1075,13 @@ impl Mutability {
MutImmutable => MutMutable, MutImmutable => MutMutable,
} }
} }
pub fn prefix_str(&self) -> &'static str {
match self {
MutMutable => "mut ",
MutImmutable => "",
}
}
} }
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)] #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
@ -2184,6 +2191,15 @@ pub enum Unsafety {
Normal, Normal,
} }
impl Unsafety {
pub fn prefix_str(&self) -> &'static str {
match self {
Unsafety::Unsafe => "unsafe ",
Unsafety::Normal => "",
}
}
}
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)] #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum Constness { pub enum Constness {
Const, Const,

View file

@ -1734,9 +1734,7 @@ impl<'a> State<'a> {
_ => false, _ => false,
}; };
self.s.word("&"); self.s.word("&");
if mutbl == hir::MutMutable { self.s.word(mutbl.prefix_str());
self.s.word("mut ");
}
if is_range_inner { if is_range_inner {
self.popen(); self.popen();
} }

View file

@ -124,7 +124,6 @@ for ::syntax::attr::StabilityLevel {
impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion }); impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion });
impl_stable_hash_for!(enum ::syntax::attr::IntType { impl_stable_hash_for!(enum ::syntax::attr::IntType {
SignedInt(int_ty), SignedInt(int_ty),
UnsignedInt(uint_ty) UnsignedInt(uint_ty)
@ -136,6 +135,11 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
Unsuffixed Unsuffixed
}); });
impl_stable_hash_for!(enum ::syntax::ast::LitFloatType {
Suffixed(float_ty),
Unsuffixed
});
impl_stable_hash_for!(struct ::syntax::ast::Lit { impl_stable_hash_for!(struct ::syntax::ast::Lit {
kind, kind,
token, token,
@ -148,8 +152,7 @@ impl_stable_hash_for!(enum ::syntax::ast::LitKind {
Byte(value), Byte(value),
Char(value), Char(value),
Int(value, lit_int_type), Int(value, lit_int_type),
Float(value, float_ty), Float(value, lit_float_type),
FloatUnsuffixed(value),
Bool(value), Bool(value),
Err(value) Err(value)
}); });
@ -159,6 +162,7 @@ impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 }); impl_stable_hash_for!(enum ::syntax::ast::IntTy { Isize, I8, I16, I32, I64, I128 });
impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 }); impl_stable_hash_for!(enum ::syntax::ast::UintTy { Usize, U8, U16, U32, U64, U128 });
impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 }); impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
impl_stable_hash_for!(enum ::rustc_target::abi::FloatTy { F32, F64 });
impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal }); impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst }); impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final }); impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });

View file

@ -897,11 +897,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} else { } else {
r.push(' '); r.push(' ');
} }
s.push_highlighted(format!( s.push_highlighted(format!("&{}{}", r, mutbl.prefix_str()));
"&{}{}",
r,
if mutbl == hir::MutMutable { "mut " } else { "" }
));
s.push_normal(ty.to_string()); s.push_normal(ty.to_string());
} }

View file

@ -538,7 +538,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
ty::Uint(ity) => { ty::Uint(ity) => {
scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false)) scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false))
} }
ty::Float(fty) => scalar(Float(fty)), ty::Float(fty) => scalar(Float(match fty {
ast::FloatTy::F32 => FloatTy::F32,
ast::FloatTy::F64 => FloatTy::F64,
})),
ty::FnPtr(_) => { ty::FnPtr(_) => {
let mut ptr = scalar_unit(Pointer); let mut ptr = scalar_unit(Pointer);
ptr.valid_range = 1..=*ptr.valid_range.end(); ptr.valid_range = 1..=*ptr.valid_range.end();

View file

@ -12,7 +12,6 @@ use rustc::ty::{self, Const, Instance, Ty, TyCtxt};
use rustc::{bug, hir}; use rustc::{bug, hir};
use std::fmt::Write; use std::fmt::Write;
use std::iter; use std::iter;
use syntax::ast;
/// Same as `unique_type_name()` but with the result pushed onto the given /// Same as `unique_type_name()` but with the result pushed onto the given
/// `output` parameter. /// `output` parameter.
@ -39,20 +38,9 @@ impl DefPathBasedNames<'tcx> {
ty::Char => output.push_str("char"), ty::Char => output.push_str("char"),
ty::Str => output.push_str("str"), ty::Str => output.push_str("str"),
ty::Never => output.push_str("!"), ty::Never => output.push_str("!"),
ty::Int(ast::IntTy::Isize) => output.push_str("isize"), ty::Int(ty) => output.push_str(ty.name_str()),
ty::Int(ast::IntTy::I8) => output.push_str("i8"), ty::Uint(ty) => output.push_str(ty.name_str()),
ty::Int(ast::IntTy::I16) => output.push_str("i16"), ty::Float(ty) => output.push_str(ty.name_str()),
ty::Int(ast::IntTy::I32) => output.push_str("i32"),
ty::Int(ast::IntTy::I64) => output.push_str("i64"),
ty::Int(ast::IntTy::I128) => output.push_str("i128"),
ty::Uint(ast::UintTy::Usize) => output.push_str("usize"),
ty::Uint(ast::UintTy::U8) => output.push_str("u8"),
ty::Uint(ast::UintTy::U16) => output.push_str("u16"),
ty::Uint(ast::UintTy::U32) => output.push_str("u32"),
ty::Uint(ast::UintTy::U64) => output.push_str("u64"),
ty::Uint(ast::UintTy::U128) => output.push_str("u128"),
ty::Float(ast::FloatTy::F32) => output.push_str("f32"),
ty::Float(ast::FloatTy::F64) => output.push_str("f64"),
ty::Adt(adt_def, substs) => { ty::Adt(adt_def, substs) => {
self.push_def_path(adt_def.did, output); self.push_def_path(adt_def.did, output);
self.push_generic_params(substs, iter::empty(), output, debug); self.push_generic_params(substs, iter::empty(), output, debug);
@ -80,9 +68,7 @@ impl DefPathBasedNames<'tcx> {
} }
ty::Ref(_, inner_type, mutbl) => { ty::Ref(_, inner_type, mutbl) => {
output.push('&'); output.push('&');
if mutbl == hir::MutMutable { output.push_str(mutbl.prefix_str());
output.push_str("mut ");
}
self.push_type_name(inner_type, output, debug); self.push_type_name(inner_type, output, debug);
} }
@ -114,9 +100,7 @@ impl DefPathBasedNames<'tcx> {
ty::Foreign(did) => self.push_def_path(did, output), ty::Foreign(did) => self.push_def_path(did, output),
ty::FnDef(..) | ty::FnPtr(_) => { ty::FnDef(..) | ty::FnPtr(_) => {
let sig = t.fn_sig(self.tcx); let sig = t.fn_sig(self.tcx);
if sig.unsafety() == hir::Unsafety::Unsafe { output.push_str(sig.unsafety().prefix_str());
output.push_str("unsafe ");
}
let abi = sig.abi(); let abi = sig.abi();
if abi != ::rustc_target::spec::abi::Abi::Rust { if abi != ::rustc_target::spec::abi::Abi::Rust {

View file

@ -466,9 +466,9 @@ pub trait PrettyPrinter<'tcx>:
match ty.kind { match ty.kind {
ty::Bool => p!(write("bool")), ty::Bool => p!(write("bool")),
ty::Char => p!(write("char")), ty::Char => p!(write("char")),
ty::Int(t) => p!(write("{}", t.ty_to_string())), ty::Int(t) => p!(write("{}", t.name_str())),
ty::Uint(t) => p!(write("{}", t.ty_to_string())), ty::Uint(t) => p!(write("{}", t.name_str())),
ty::Float(t) => p!(write("{}", t.ty_to_string())), ty::Float(t) => p!(write("{}", t.name_str())),
ty::RawPtr(ref tm) => { ty::RawPtr(ref tm) => {
p!(write("*{} ", match tm.mutbl { p!(write("*{} ", match tm.mutbl {
hir::MutMutable => "mut", hir::MutMutable => "mut",
@ -895,10 +895,11 @@ pub trait PrettyPrinter<'tcx>:
let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size(); let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
let max = truncate(u128::max_value(), bit_size); let max = truncate(u128::max_value(), bit_size);
let ui_str = ui.name_str();
if data == max { if data == max {
p!(write("std::{}::MAX", ui)) p!(write("std::{}::MAX", ui_str))
} else { } else {
p!(write("{}{}", data, ui)) p!(write("{}{}", data, ui_str))
}; };
}, },
(ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Int(i)) => { (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Int(i)) => {
@ -911,10 +912,11 @@ pub trait PrettyPrinter<'tcx>:
let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty)) let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty))
.unwrap() .unwrap()
.size; .size;
let i_str = i.name_str();
match data { match data {
d if d == min => p!(write("std::{}::MIN", i)), d if d == min => p!(write("std::{}::MIN", i_str)),
d if d == max => p!(write("std::{}::MAX", i)), d if d == max => p!(write("std::{}::MAX", i_str)),
_ => p!(write("{}{}", sign_extend(data, size) as i128, i)) _ => p!(write("{}{}", sign_extend(data, size) as i128, i_str))
} }
}, },
(ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Char) => (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Char) =>
@ -1666,8 +1668,7 @@ define_print_and_forward_display! {
} }
ty::TypeAndMut<'tcx> { ty::TypeAndMut<'tcx> {
p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }), p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
print(self.ty))
} }
ty::ExistentialTraitRef<'tcx> { ty::ExistentialTraitRef<'tcx> {
@ -1693,9 +1694,7 @@ define_print_and_forward_display! {
} }
ty::FnSig<'tcx> { ty::FnSig<'tcx> {
if self.unsafety == hir::Unsafety::Unsafe { p!(write("{}", self.unsafety.prefix_str()));
p!(write("unsafe "));
}
if self.abi != Abi::Rust { if self.abi != Abi::Rust {
p!(write("extern {} ", self.abi)); p!(write("extern {} ", self.abi));

View file

@ -843,13 +843,13 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
ty::Bool => ("bool", DW_ATE_boolean), ty::Bool => ("bool", DW_ATE_boolean),
ty::Char => ("char", DW_ATE_unsigned_char), ty::Char => ("char", DW_ATE_unsigned_char),
ty::Int(int_ty) => { ty::Int(int_ty) => {
(int_ty.ty_to_string(), DW_ATE_signed) (int_ty.name_str(), DW_ATE_signed)
}, },
ty::Uint(uint_ty) => { ty::Uint(uint_ty) => {
(uint_ty.ty_to_string(), DW_ATE_unsigned) (uint_ty.name_str(), DW_ATE_unsigned)
}, },
ty::Float(float_ty) => { ty::Float(float_ty) => {
(float_ty.ty_to_string(), DW_ATE_float) (float_ty.name_str(), DW_ATE_float)
}, },
_ => bug!("debuginfo::basic_type_metadata - t is invalid type") _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
}; };

View file

@ -18,8 +18,8 @@ use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive};
use rustc::mir::interpret::GlobalId; use rustc::mir::interpret::GlobalId;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc::hir; use rustc::hir;
use syntax::ast::{self, FloatTy}; use rustc_target::abi::{FloatTy, HasDataLayout};
use rustc_target::abi::HasDataLayout; use syntax::ast;
use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::traits::*;
@ -1335,7 +1335,7 @@ fn generic_simd_intrinsic(
}, },
ty::Float(f) => { ty::Float(f) => {
return_error!("unsupported element type `{}` of floating-point vector `{}`", return_error!("unsupported element type `{}` of floating-point vector `{}`",
f, in_ty); f.name_str(), in_ty);
}, },
_ => { _ => {
return_error!("`{}` is not a floating-point type", in_ty); return_error!("`{}` is not a floating-point type", in_ty);

View file

@ -37,9 +37,9 @@ pub fn push_debuginfo_type_name<'tcx>(
ty::Char => output.push_str("char"), ty::Char => output.push_str("char"),
ty::Str => output.push_str("str"), ty::Str => output.push_str("str"),
ty::Never => output.push_str("!"), ty::Never => output.push_str("!"),
ty::Int(int_ty) => output.push_str(int_ty.ty_to_string()), ty::Int(int_ty) => output.push_str(int_ty.name_str()),
ty::Uint(uint_ty) => output.push_str(uint_ty.ty_to_string()), ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
ty::Float(float_ty) => output.push_str(float_ty.ty_to_string()), ty::Float(float_ty) => output.push_str(float_ty.name_str()),
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output), ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
ty::Adt(def, substs) => { ty::Adt(def, substs) => {
push_item_name(tcx, def.did, qualified, output); push_item_name(tcx, def.did, qualified, output);
@ -76,9 +76,7 @@ pub fn push_debuginfo_type_name<'tcx>(
if !cpp_like_names { if !cpp_like_names {
output.push('&'); output.push('&');
} }
if mutbl == hir::MutMutable { output.push_str(mutbl.prefix_str());
output.push_str("mut ");
}
push_debuginfo_type_name(tcx, inner_type, true, output, visited); push_debuginfo_type_name(tcx, inner_type, true, output, visited);
@ -140,9 +138,7 @@ pub fn push_debuginfo_type_name<'tcx>(
let sig = t.fn_sig(tcx); let sig = t.fn_sig(tcx);
if sig.unsafety() == hir::Unsafety::Unsafe { output.push_str(sig.unsafety().prefix_str());
output.push_str("unsafe ");
}
let abi = sig.abi(); let abi = sig.abi();
if abi != rustc_target::spec::abi::Abi::Rust { if abi != rustc_target::spec::abi::Abi::Rust {

View file

@ -27,7 +27,6 @@ rustc_codegen_utils = { path = "../librustc_codegen_utils" }
rustc_metadata = { path = "../librustc_metadata" } rustc_metadata = { path = "../librustc_metadata" }
rustc_mir = { path = "../librustc_mir" } rustc_mir = { path = "../librustc_mir" }
rustc_passes = { path = "../librustc_passes" } rustc_passes = { path = "../librustc_passes" }
rustc_target = { path = "../librustc_target" }
rustc_typeck = { path = "../librustc_typeck" } rustc_typeck = { path = "../librustc_typeck" }
rustc_lint = { path = "../librustc_lint" } rustc_lint = { path = "../librustc_lint" }
rustc_errors = { path = "../librustc_errors" } rustc_errors = { path = "../librustc_errors" }
@ -36,3 +35,6 @@ rustc_privacy = { path = "../librustc_privacy" }
rustc_resolve = { path = "../librustc_resolve" } rustc_resolve = { path = "../librustc_resolve" }
tempfile = "3.0.5" tempfile = "3.0.5"
once_cell = "1" once_cell = "1"
[dev-dependencies]
rustc_target = { path = "../librustc_target" }

View file

@ -0,0 +1,91 @@
use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
use rustc::{
lint::FutureIncompatibleInfo,
hir,
ty::{
self,
adjustment::{Adjust, Adjustment},
},
};
use syntax::{
errors::Applicability,
symbol::sym,
};
declare_lint! {
pub ARRAY_INTO_ITER,
Warn,
"detects calling `into_iter` on arrays",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #66145 <https://github.com/rust-lang/rust/issues/66145>",
edition: None,
};
}
declare_lint_pass!(
/// Checks for instances of calling `into_iter` on arrays.
ArrayIntoIter => [ARRAY_INTO_ITER]
);
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
// We only care about method call expressions.
if let hir::ExprKind::MethodCall(call, span, args) = &expr.kind {
if call.ident.name != sym::into_iter {
return;
}
// Check if the method call actually calls the libcore
// `IntoIterator::into_iter`.
let def_id = cx.tables.type_dependent_def_id(expr.hir_id).unwrap();
match cx.tcx.trait_of_item(def_id) {
Some(trait_id) if cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_id) => {},
_ => return,
};
// As this is a method call expression, we have at least one
// argument.
let receiver_arg = &args[0];
// Test if the original `self` type is an array type.
match cx.tables.expr_ty(receiver_arg).kind {
ty::Array(..) => {}
_ => return,
}
// Make sure that the first adjustment is an autoref coercion.
match cx.tables.expr_adjustments(receiver_arg).get(0) {
Some(Adjustment { kind: Adjust::Borrow(_), .. }) => {}
_ => return,
}
// Emit lint diagnostic.
let target = match cx.tables.expr_ty_adjusted(receiver_arg).kind {
ty::Ref(_, ty::TyS { kind: ty::Array(..), ..}, _) => "[T; N]",
ty::Ref(_, ty::TyS { kind: ty::Slice(..), ..}, _) => "[T]",
// We know the original first argument type is an array type,
// we know that the first adjustment was an autoref coercion
// and we know that `IntoIterator` is the trait involved. The
// array cannot be coerced to something other than a reference
// to an array or to a slice.
_ => bug!("array type coerced to something other than array or slice"),
};
let msg = format!(
"this method call currently resolves to `<&{} as IntoIterator>::into_iter` (due \
to autoref coercions), but that might change in the future when \
`IntoIterator` impls for arrays are added.",
target,
);
cx.struct_span_lint(ARRAY_INTO_ITER, *span, &msg)
.span_suggestion(
call.ident.span,
"use `.iter()` instead of `.into_iter()` to avoid ambiguity",
"iter".into(),
Applicability::MachineApplicable,
)
.emit();
}
}
}

View file

@ -22,6 +22,7 @@
#[macro_use] #[macro_use]
extern crate rustc; extern crate rustc;
mod array_into_iter;
mod error_codes; mod error_codes;
mod nonstandard_style; mod nonstandard_style;
mod redundant_semicolon; mod redundant_semicolon;
@ -57,6 +58,7 @@ use types::*;
use unused::*; use unused::*;
use non_ascii_idents::*; use non_ascii_idents::*;
use rustc::lint::internal::*; use rustc::lint::internal::*;
use array_into_iter::ArrayIntoIter;
/// Useful for other parts of the compiler. /// Useful for other parts of the compiler.
pub use builtin::SoftLints; pub use builtin::SoftLints;
@ -131,6 +133,8 @@ macro_rules! late_lint_passes {
// FIXME: Turn the computation of types which implement Debug into a query // FIXME: Turn the computation of types which implement Debug into a query
// and change this to a module lint pass // and change this to a module lint pass
MissingDebugImplementations: MissingDebugImplementations::default(), MissingDebugImplementations: MissingDebugImplementations::default(),
ArrayIntoIter: ArrayIntoIter,
]); ]);
) )
} }

View file

@ -68,7 +68,7 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>(
max: u128, max: u128,
expr: &'tcx hir::Expr, expr: &'tcx hir::Expr,
parent_expr: &'tcx hir::Expr, parent_expr: &'tcx hir::Expr,
ty: impl std::fmt::Debug, ty: &str,
) -> bool { ) -> bool {
// We only want to handle exclusive (`..`) ranges, // We only want to handle exclusive (`..`) ranges,
// which are represented as `ExprKind::Struct`. // which are represented as `ExprKind::Struct`.
@ -83,15 +83,15 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>(
let mut err = cx.struct_span_lint( let mut err = cx.struct_span_lint(
OVERFLOWING_LITERALS, OVERFLOWING_LITERALS,
parent_expr.span, parent_expr.span,
&format!("range endpoint is out of range for `{:?}`", ty), &format!("range endpoint is out of range for `{}`", ty),
); );
if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) { if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
use ast::{LitKind, LitIntType}; use ast::{LitKind, LitIntType};
// We need to preserve the literal's suffix, // We need to preserve the literal's suffix,
// as it may determine typing information. // as it may determine typing information.
let suffix = match lit.node { let suffix = match lit.node {
LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s), LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s.name_str()),
LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s), LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s.name_str()),
LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(), LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(),
_ => bug!(), _ => bug!(),
}; };
@ -161,11 +161,11 @@ fn report_bin_hex_error(
let (t, actually) = match ty { let (t, actually) = match ty {
attr::IntType::SignedInt(t) => { attr::IntType::SignedInt(t) => {
let actually = sign_extend(val, size) as i128; let actually = sign_extend(val, size) as i128;
(format!("{:?}", t), actually.to_string()) (t.name_str(), actually.to_string())
} }
attr::IntType::UnsignedInt(t) => { attr::IntType::UnsignedInt(t) => {
let actually = truncate(val, size); let actually = truncate(val, size);
(format!("{:?}", t), actually.to_string()) (t.name_str(), actually.to_string())
} }
}; };
let mut err = cx.struct_span_lint( let mut err = cx.struct_span_lint(
@ -204,7 +204,7 @@ fn report_bin_hex_error(
// - `uX` => `uY` // - `uX` => `uY`
// //
// No suggestion for: `isize`, `usize`. // No suggestion for: `isize`, `usize`.
fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> { fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> {
use syntax::ast::IntTy::*; use syntax::ast::IntTy::*;
use syntax::ast::UintTy::*; use syntax::ast::UintTy::*;
macro_rules! find_fit { macro_rules! find_fit {
@ -215,10 +215,10 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> {
match $ty { match $ty {
$($type => { $($type => {
$(if !negative && val <= uint_ty_range($utypes).1 { $(if !negative && val <= uint_ty_range($utypes).1 {
return Some(format!("{:?}", $utypes)) return Some($utypes.name_str())
})* })*
$(if val <= int_ty_range($itypes).1 as u128 + _neg { $(if val <= int_ty_range($itypes).1 as u128 + _neg {
return Some(format!("{:?}", $itypes)) return Some($itypes.name_str())
})* })*
None None
},)+ },)+
@ -281,7 +281,7 @@ fn lint_int_literal<'a, 'tcx>(
if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) { if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
if let hir::ExprKind::Struct(..) = par_e.kind { if let hir::ExprKind::Struct(..) = par_e.kind {
if is_range_literal(cx.sess(), par_e) if is_range_literal(cx.sess(), par_e)
&& lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t) && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
{ {
// The overflowing literal lint was overridden. // The overflowing literal lint was overridden.
return; return;
@ -292,7 +292,7 @@ fn lint_int_literal<'a, 'tcx>(
cx.span_lint( cx.span_lint(
OVERFLOWING_LITERALS, OVERFLOWING_LITERALS,
e.span, e.span,
&format!("literal out of range for `{:?}`", t), &format!("literal out of range for `{}`", t.name_str()),
); );
} }
} }
@ -338,6 +338,7 @@ fn lint_uint_literal<'a, 'tcx>(
} }
hir::ExprKind::Struct(..) hir::ExprKind::Struct(..)
if is_range_literal(cx.sess(), par_e) => { if is_range_literal(cx.sess(), par_e) => {
let t = t.name_str();
if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) { if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
// The overflowing literal lint was overridden. // The overflowing literal lint was overridden.
return; return;
@ -353,7 +354,7 @@ fn lint_uint_literal<'a, 'tcx>(
cx.span_lint( cx.span_lint(
OVERFLOWING_LITERALS, OVERFLOWING_LITERALS,
e.span, e.span,
&format!("literal out of range for `{:?}`", t), &format!("literal out of range for `{}`", t.name_str()),
); );
} }
} }
@ -379,8 +380,7 @@ fn lint_literal<'a, 'tcx>(
} }
ty::Float(t) => { ty::Float(t) => {
let is_infinite = match lit.node { let is_infinite = match lit.node {
ast::LitKind::Float(v, _) | ast::LitKind::Float(v, _) => {
ast::LitKind::FloatUnsuffixed(v) => {
match t { match t {
ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
@ -389,9 +389,11 @@ fn lint_literal<'a, 'tcx>(
_ => bug!(), _ => bug!(),
}; };
if is_infinite == Ok(true) { if is_infinite == Ok(true) {
cx.span_lint(OVERFLOWING_LITERALS, cx.span_lint(
OVERFLOWING_LITERALS,
e.span, e.span,
&format!("literal out of range for `{:?}`", t)); &format!("literal out of range for `{}`", t.name_str()),
);
} }
} }
_ => {} _ => {}

View file

@ -95,8 +95,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
generics_of => { generics_of => {
tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess)) tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess))
} }
predicates_of => { cdata.get_predicates(def_id.index, tcx) } explicit_predicates_of => { cdata.get_explicit_predicates(def_id.index, tcx) }
predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) } inferred_outlives_of => { cdata.get_inferred_outlives(def_id.index, tcx) }
super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) } super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
trait_def => { trait_def => {
tcx.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess)) tcx.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess))

View file

@ -658,20 +658,22 @@ impl<'a, 'tcx> CrateMetadata {
tcx.alloc_adt_def(did, adt_kind, variants, repr) tcx.alloc_adt_def(did, adt_kind, variants, repr)
} }
crate fn get_predicates( crate fn get_explicit_predicates(
&self, &self,
item_id: DefIndex, item_id: DefIndex,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> ty::GenericPredicates<'tcx> { ) -> ty::GenericPredicates<'tcx> {
self.root.per_def.predicates.get(self, item_id).unwrap().decode((self, tcx)) self.root.per_def.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx))
} }
crate fn get_predicates_defined_on( crate fn get_inferred_outlives(
&self, &self,
item_id: DefIndex, item_id: DefIndex,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> ty::GenericPredicates<'tcx> { ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
self.root.per_def.predicates_defined_on.get(self, item_id).unwrap().decode((self, tcx)) self.root.per_def.inferred_outlives.get(self, item_id).map(|predicates| {
predicates.decode((self, tcx))
}).unwrap_or_default()
} }
crate fn get_super_predicates( crate fn get_super_predicates(

View file

@ -76,8 +76,8 @@ struct PerDefTables<'tcx> {
inherent_impls: PerDefTable<Lazy<[DefIndex]>>, inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
variances: PerDefTable<Lazy<[ty::Variance]>>, variances: PerDefTable<Lazy<[ty::Variance]>>,
generics: PerDefTable<Lazy<ty::Generics>>, generics: PerDefTable<Lazy<ty::Generics>>,
predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>, explicit_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
predicates_defined_on: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>, inferred_outlives: PerDefTable<Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>,
super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>, super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
mir: PerDefTable<Lazy<mir::Body<'tcx>>>, mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
@ -524,8 +524,8 @@ impl<'tcx> EncodeContext<'tcx> {
inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque), inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque),
variances: self.per_def.variances.encode(&mut self.opaque), variances: self.per_def.variances.encode(&mut self.opaque),
generics: self.per_def.generics.encode(&mut self.opaque), generics: self.per_def.generics.encode(&mut self.opaque),
predicates: self.per_def.predicates.encode(&mut self.opaque), explicit_predicates: self.per_def.explicit_predicates.encode(&mut self.opaque),
predicates_defined_on: self.per_def.predicates_defined_on.encode(&mut self.opaque), inferred_outlives: self.per_def.inferred_outlives.encode(&mut self.opaque),
super_predicates: self.per_def.super_predicates.encode(&mut self.opaque), super_predicates: self.per_def.super_predicates.encode(&mut self.opaque),
mir: self.per_def.mir.encode(&mut self.opaque), mir: self.per_def.mir.encode(&mut self.opaque),
@ -675,7 +675,8 @@ impl EncodeContext<'tcx> {
self.encode_variances_of(def_id); self.encode_variances_of(def_id);
} }
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
self.encode_optimized_mir(def_id); self.encode_optimized_mir(def_id);
self.encode_promoted_mir(def_id); self.encode_promoted_mir(def_id);
} }
@ -718,7 +719,8 @@ impl EncodeContext<'tcx> {
self.encode_variances_of(def_id); self.encode_variances_of(def_id);
} }
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
self.encode_optimized_mir(def_id); self.encode_optimized_mir(def_id);
self.encode_promoted_mir(def_id); self.encode_promoted_mir(def_id);
} }
@ -776,7 +778,8 @@ impl EncodeContext<'tcx> {
self.encode_deprecation(def_id); self.encode_deprecation(def_id);
self.encode_item_type(def_id); self.encode_item_type(def_id);
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
} }
fn encode_struct_ctor(&mut self, adt_def_id: DefId, def_id: DefId) { fn encode_struct_ctor(&mut self, adt_def_id: DefId, def_id: DefId) {
@ -819,7 +822,8 @@ impl EncodeContext<'tcx> {
self.encode_variances_of(def_id); self.encode_variances_of(def_id);
} }
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
self.encode_optimized_mir(def_id); self.encode_optimized_mir(def_id);
self.encode_promoted_mir(def_id); self.encode_promoted_mir(def_id);
} }
@ -829,15 +833,18 @@ impl EncodeContext<'tcx> {
record!(self.per_def.generics[def_id] <- self.tcx.generics_of(def_id)); record!(self.per_def.generics[def_id] <- self.tcx.generics_of(def_id));
} }
fn encode_predicates(&mut self, def_id: DefId) { fn encode_explicit_predicates(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_predicates({:?})", def_id); debug!("EncodeContext::encode_explicit_predicates({:?})", def_id);
record!(self.per_def.predicates[def_id] <- self.tcx.predicates_of(def_id)); record!(self.per_def.explicit_predicates[def_id] <-
self.tcx.explicit_predicates_of(def_id));
} }
fn encode_predicates_defined_on(&mut self, def_id: DefId) { fn encode_inferred_outlives(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id); debug!("EncodeContext::encode_inferred_outlives({:?})", def_id);
record!(self.per_def.predicates_defined_on[def_id] <- let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
self.tcx.predicates_defined_on(def_id)) if !inferred_outlives.is_empty() {
record!(self.per_def.inferred_outlives[def_id] <- inferred_outlives);
}
} }
fn encode_super_predicates(&mut self, def_id: DefId) { fn encode_super_predicates(&mut self, def_id: DefId) {
@ -919,7 +926,8 @@ impl EncodeContext<'tcx> {
self.encode_variances_of(def_id); self.encode_variances_of(def_id);
} }
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
self.encode_optimized_mir(def_id); self.encode_optimized_mir(def_id);
self.encode_promoted_mir(def_id); self.encode_promoted_mir(def_id);
} }
@ -986,7 +994,8 @@ impl EncodeContext<'tcx> {
self.encode_variances_of(def_id); self.encode_variances_of(def_id);
} }
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
let mir = match ast_item.kind { let mir = match ast_item.kind {
hir::ImplItemKind::Const(..) => true, hir::ImplItemKind::Const(..) => true,
hir::ImplItemKind::Method(ref sig, _) => { hir::ImplItemKind::Method(ref sig, _) => {
@ -1260,22 +1269,11 @@ impl EncodeContext<'tcx> {
hir::ItemKind::Trait(..) | hir::ItemKind::Trait(..) |
hir::ItemKind::TraitAlias(..) => { hir::ItemKind::TraitAlias(..) => {
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
} }
_ => {} _ => {}
} }
// The only time that `predicates_defined_on` is used (on
// an external item) is for traits, during chalk lowering,
// so only encode it in that case as an efficiency
// hack. (No reason not to expand it in the future if
// necessary.)
match item.kind {
hir::ItemKind::Trait(..) |
hir::ItemKind::TraitAlias(..) => {
self.encode_predicates_defined_on(def_id);
}
_ => {} // not *wrong* for other kinds of items, but not needed
}
match item.kind { match item.kind {
hir::ItemKind::Trait(..) | hir::ItemKind::Trait(..) |
hir::ItemKind::TraitAlias(..) => { hir::ItemKind::TraitAlias(..) => {
@ -1377,7 +1375,8 @@ impl EncodeContext<'tcx> {
record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
self.encode_item_type(def_id); self.encode_item_type(def_id);
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
self.encode_optimized_mir(def_id); self.encode_optimized_mir(def_id);
self.encode_promoted_mir(def_id); self.encode_promoted_mir(def_id);
} }
@ -1588,7 +1587,8 @@ impl EncodeContext<'tcx> {
self.encode_variances_of(def_id); self.encode_variances_of(def_id);
} }
self.encode_generics(def_id); self.encode_generics(def_id);
self.encode_predicates(def_id); self.encode_explicit_predicates(def_id);
self.encode_inferred_outlives(def_id);
} }
} }

View file

@ -244,8 +244,13 @@ crate struct LazyPerDefTables<'tcx> {
pub inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>), pub inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
pub variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>), pub variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
pub generics: Lazy!(PerDefTable<Lazy<ty::Generics>>), pub generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
pub predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>), pub explicit_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
pub predicates_defined_on: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>), // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
// doesn't handle shorthands in its own (de)serialization impls,
// as it's an `enum` for which we want to derive (de)serialization,
// so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
// Also, as an optimization, a missing entry indicates an empty `&[]`.
pub inferred_outlives: Lazy!(PerDefTable<Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>),
pub super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>), pub super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
pub mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>), pub mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),

View file

@ -45,10 +45,7 @@ crate fn lit_to_const<'tcx>(
trunc(n as u128)? trunc(n as u128)?
}, },
LitKind::Int(n, _) => trunc(n)?, LitKind::Int(n, _) => trunc(n)?,
LitKind::Float(n, fty) => { LitKind::Float(n, _) => {
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
}
LitKind::FloatUnsuffixed(n) => {
let fty = match ty.kind { let fty = match ty.kind {
ty::Float(fty) => fty, ty::Float(fty) => fty,
_ => bug!() _ => bug!()

View file

@ -293,10 +293,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
match self.ty.kind { match self.ty.kind {
ty::Adt(def, _) if def.is_box() => write!(f, "box ")?, ty::Adt(def, _) if def.is_box() => write!(f, "box ")?,
ty::Ref(_, _, mutbl) => { ty::Ref(_, _, mutbl) => {
write!(f, "&")?; write!(f, "&{}", mutbl.prefix_str())?;
if mutbl == hir::MutMutable {
write!(f, "mut ")?;
}
} }
_ => bug!("{} is a bad Deref pattern type", self.ty) _ => bug!("{} is a bad Deref pattern type", self.ty)
} }

View file

@ -13,7 +13,6 @@ log = "0.4"
rustc = { path = "../librustc" } rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" } rustc_data_structures = { path = "../librustc_data_structures" }
rustc_codegen_utils = { path = "../librustc_codegen_utils" } rustc_codegen_utils = { path = "../librustc_codegen_utils" }
rustc_target = { path = "../librustc_target" }
serde_json = "1" serde_json = "1"
syntax = { path = "../libsyntax" } syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" } syntax_pos = { path = "../libsyntax_pos" }

View file

@ -32,7 +32,7 @@ use rls_data::{SigElement, Signature};
use rustc::hir::def::{Res, DefKind}; use rustc::hir::def::{Res, DefKind};
use syntax::ast::{self, NodeId}; use syntax::ast::{self, NodeId};
use syntax::print::pprust; use syntax::print::pprust;
use syntax_pos::sym;
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 { if !scx.config.signatures {
@ -157,6 +157,12 @@ fn text_sig(text: String) -> Signature {
} }
} }
fn push_abi(text: &mut String, abi: ast::Abi) {
if abi.symbol != sym::Rust {
text.push_str(&format!("extern \"{}\" ", abi.symbol));
}
}
impl Sig for ast::Ty { 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); let id = Some(self.id);
@ -231,11 +237,7 @@ impl Sig for ast::Ty {
if f.unsafety == ast::Unsafety::Unsafe { if f.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe "); text.push_str("unsafe ");
} }
if f.abi != rustc_target::spec::abi::Abi::Rust { push_abi(&mut text, f.abi);
text.push_str("extern");
text.push_str(&f.abi.to_string());
text.push(' ');
}
text.push_str("fn("); text.push_str("fn(");
let mut defs = vec![]; let mut defs = vec![];
@ -385,11 +387,7 @@ impl Sig for ast::Item {
if header.unsafety == ast::Unsafety::Unsafe { if header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe "); text.push_str("unsafe ");
} }
if header.abi != rustc_target::spec::abi::Abi::Rust { push_abi(&mut text, header.abi);
text.push_str("extern");
text.push_str(&header.abi.to_string());
text.push(' ');
}
text.push_str("fn "); text.push_str("fn ");
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
@ -948,11 +946,7 @@ fn make_method_signature(
if m.header.unsafety == ast::Unsafety::Unsafe { if m.header.unsafety == ast::Unsafety::Unsafe {
text.push_str("unsafe "); text.push_str("unsafe ");
} }
if m.header.abi != rustc_target::spec::abi::Abi::Rust { push_abi(&mut text, m.header.abi);
text.push_str("extern");
text.push_str(&m.header.abi.to_string());
text.push(' ');
}
text.push_str("fn "); text.push_str("fn ");
let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?; let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;

View file

@ -3,11 +3,9 @@ pub use Primitive::*;
use crate::spec::Target; use crate::spec::Target;
use std::fmt;
use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive};
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use syntax_pos::symbol::{sym, Symbol};
use syntax_pos::Span; use syntax_pos::Span;
pub mod call; pub mod call;
@ -534,49 +532,13 @@ impl Integer {
} }
} }
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy,
PartialOrd, Ord)] PartialOrd, Ord, Debug)]
pub enum FloatTy { pub enum FloatTy {
F32, F32,
F64, F64,
} }
impl fmt::Debug for FloatTy {
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 {
write!(f, "{}", self.ty_to_string())
}
}
impl FloatTy {
pub fn ty_to_string(self) -> &'static str {
match self {
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
}
}
pub fn to_symbol(self) -> Symbol {
match self {
FloatTy::F32 => sym::f32,
FloatTy::F64 => sym::f64,
}
}
pub fn bit_width(self) -> usize {
match self {
FloatTy::F32 => 32,
FloatTy::F64 => 64,
}
}
}
/// Fundamental unit of memory access and layout. /// Fundamental unit of memory access and layout.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum Primitive { pub enum Primitive {

View file

@ -341,10 +341,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
tstr); tstr);
match self.expr_ty.kind { match self.expr_ty.kind {
ty::Ref(_, _, mt) => { ty::Ref(_, _, mt) => {
let mtstr = match mt { let mtstr = mt.prefix_str();
hir::MutMutable => "mut ",
hir::MutImmutable => "",
};
if self.cast_ty.is_trait() { if self.cast_ty.is_trait() {
match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) { match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
Ok(s) => { Ok(s) => {

View file

@ -592,20 +592,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
cause.span, cause.span,
target_id, target_id,
); );
let val = match ty.kind { if let Some(val) = ty_kind_suggestion(ty) {
ty::Bool => "true",
ty::Char => "'a'",
ty::Int(_) | ty::Uint(_) => "42",
ty::Float(_) => "3.14159",
ty::Error | ty::Never => return,
_ => "value",
};
let msg = "give it a value of the expected type";
let label = destination.label let label = destination.label
.map(|l| format!(" {}", l.ident)) .map(|l| format!(" {}", l.ident))
.unwrap_or_else(String::new); .unwrap_or_else(String::new);
let sugg = format!("break{} {}", label, val); err.span_suggestion(
err.span_suggestion(expr.span, msg, sugg, Applicability::HasPlaceholders); expr.span,
"give it a value of the expected type",
format!("break{} {}", label, val),
Applicability::HasPlaceholders,
);
}
}, false); }, false);
} }
} else { } else {
@ -1725,3 +1722,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.mk_unit() self.tcx.mk_unit()
} }
} }
pub(super) fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
Some(match ty.kind {
ty::Bool => "true",
ty::Char => "'a'",
ty::Int(_) | ty::Uint(_) => "42",
ty::Float(_) => "3.14159",
ty::Error | ty::Never => return None,
_ => "value",
})
}

View file

@ -127,7 +127,7 @@ use syntax::ast;
use syntax::attr; use syntax::attr;
use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax::source_map::{DUMMY_SP, original_sp}; use syntax::source_map::{DUMMY_SP, original_sp};
use syntax::symbol::{kw, sym}; use syntax::symbol::{kw, sym, Ident};
use syntax::util::parser::ExprPrecedence; use syntax::util::parser::ExprPrecedence;
use std::cell::{Cell, RefCell, Ref, RefMut}; use std::cell::{Cell, RefCell, Ref, RefMut};
@ -1800,12 +1800,12 @@ fn check_specialization_validity<'tcx>(
fn check_impl_items_against_trait<'tcx>( fn check_impl_items_against_trait<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
impl_span: Span, full_impl_span: Span,
impl_id: DefId, impl_id: DefId,
impl_trait_ref: ty::TraitRef<'tcx>, impl_trait_ref: ty::TraitRef<'tcx>,
impl_item_refs: &[hir::ImplItemRef], impl_item_refs: &[hir::ImplItemRef],
) { ) {
let impl_span = tcx.sess.source_map().def_span(impl_span); let impl_span = tcx.sess.source_map().def_span(full_impl_span);
// If the trait reference itself is erroneous (so the compilation is going // If the trait reference itself is erroneous (so the compilation is going
// to fail), skip checking the items here -- the `impl_item` table in `tcx` // to fail), skip checking the items here -- the `impl_item` table in `tcx`
@ -1925,35 +1925,132 @@ fn check_impl_items_against_trait<'tcx>(
} }
if !missing_items.is_empty() { if !missing_items.is_empty() {
let mut err = struct_span_err!(tcx.sess, impl_span, E0046, missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
"not all trait items implemented, missing: `{}`",
missing_items.iter()
.map(|trait_item| trait_item.ident.to_string())
.collect::<Vec<_>>().join("`, `"));
err.span_label(impl_span, format!("missing `{}` in implementation",
missing_items.iter()
.map(|trait_item| trait_item.ident.to_string())
.collect::<Vec<_>>().join("`, `")));
for trait_item in missing_items {
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
err.span_label(span, format!("`{}` from trait", trait_item.ident));
} else {
err.note_trait_signature(trait_item.ident.to_string(),
trait_item.signature(tcx));
}
}
err.emit();
} }
if !invalidated_items.is_empty() { if !invalidated_items.is_empty() {
let invalidator = overridden_associated_type.unwrap(); let invalidator = overridden_associated_type.unwrap();
span_err!(tcx.sess, invalidator.span, E0399, span_err!(
"the following trait items need to be reimplemented \ tcx.sess,
as `{}` was overridden: `{}`", invalidator.span,
E0399,
"the following trait items need to be reimplemented as `{}` was overridden: `{}`",
invalidator.ident, invalidator.ident,
invalidated_items.iter() invalidated_items.iter()
.map(|name| name.to_string()) .map(|name| name.to_string())
.collect::<Vec<_>>().join("`, `")) .collect::<Vec<_>>().join("`, `")
)
}
}
fn missing_items_err(
tcx: TyCtxt<'_>,
impl_span: Span,
missing_items: &[ty::AssocItem],
full_impl_span: Span,
) {
let missing_items_msg = missing_items.iter()
.map(|trait_item| trait_item.ident.to_string())
.collect::<Vec<_>>().join("`, `");
let mut err = struct_span_err!(
tcx.sess,
impl_span,
E0046,
"not all trait items implemented, missing: `{}`",
missing_items_msg
);
err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
// `Span` before impl block closing brace.
let hi = full_impl_span.hi() - BytePos(1);
// Point at the place right before the closing brace of the relevant `impl` to suggest
// adding the associated item at the end of its body.
let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
// Obtain the level of indentation ending in `sugg_sp`.
let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
// Make the whitespace that will make the suggestion have the right indentation.
let padding: String = (0..indentation).map(|_| " ").collect();
for trait_item in missing_items {
let snippet = suggestion_signature(&trait_item, tcx);
let code = format!("{}{}\n{}", padding, snippet, padding);
let msg = format!("implement the missing item: `{}`", snippet);
let appl = Applicability::HasPlaceholders;
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
err.span_label(span, format!("`{}` from trait", trait_item.ident));
err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
} else {
err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
}
}
err.emit();
}
/// Return placeholder code for the given function.
fn fn_sig_suggestion(sig: &ty::FnSig<'_>, ident: Ident) -> String {
let args = sig.inputs()
.iter()
.map(|ty| Some(match ty.kind {
ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
ty::Ref(reg, ref_ty, mutability) => {
let reg = match &format!("{}", reg)[..] {
"'_" | "" => String::new(),
reg => format!("{} ", reg),
};
match ref_ty.kind {
ty::Param(param) if param.name == kw::SelfUpper => {
format!("&{}{}self", reg, mutability.prefix_str())
}
_ => format!("_: {:?}", ty),
}
}
_ => format!("_: {:?}", ty),
}))
.chain(std::iter::once(if sig.c_variadic {
Some("...".to_string())
} else {
None
}))
.filter_map(|arg| arg)
.collect::<Vec<String>>()
.join(", ");
let output = sig.output();
let output = if !output.is_unit() {
format!(" -> {:?}", output)
} else {
String::new()
};
let unsafety = sig.unsafety.prefix_str();
// FIXME: this is not entirely correct, as the lifetimes from borrowed params will
// not be present in the `fn` definition, not will we account for renamed
// lifetimes between the `impl` and the `trait`, but this should be good enough to
// fill in a significant portion of the missing code, and other subsequent
// suggestions can help the user fix the code.
format!("{}fn {}({}){} {{ unimplemented!() }}", unsafety, ident, args, output)
}
/// Return placeholder code for the given associated item.
/// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
/// structured suggestion.
fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
match assoc.kind {
ty::AssocKind::Method => {
// We skip the binder here because the binder would deanonymize all
// late-bound regions, and we don't want method signatures to show up
// `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
// regions just fine, showing `fn(&MyType)`.
fn_sig_suggestion(tcx.fn_sig(assoc.def_id).skip_binder(), assoc.ident)
}
ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
// FIXME(type_alias_impl_trait): we should print bounds here too.
ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
ty::AssocKind::Const => {
let ty = tcx.type_of(assoc.def_id);
let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
format!("const {}: {:?} = {};", assoc.ident, ty, val)
}
} }
} }
@ -3660,8 +3757,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}); });
opt_ty.unwrap_or_else(|| self.next_int_var()) opt_ty.unwrap_or_else(|| self.next_int_var())
} }
ast::LitKind::Float(_, t) => tcx.mk_mach_float(t), ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
ast::LitKind::FloatUnsuffixed(_) => { ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
let opt_ty = expected.to_option(self).and_then(|ty| { let opt_ty = expected.to_option(self).and_then(|ty| {
match ty.kind { match ty.kind {
ty::Float(_) => Some(ty), ty::Float(_) => Some(ty),

View file

@ -1146,10 +1146,6 @@ fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) {
); );
} }
fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
checked_type_of(tcx, def_id, true).unwrap()
}
fn infer_placeholder_type( fn infer_placeholder_type(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
@ -1193,26 +1189,14 @@ fn infer_placeholder_type(
ty ty
} }
/// Same as [`type_of`] but returns [`Option`] instead of failing. fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
///
/// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
/// you'd better just call [`type_of`] directly.
pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<'_>> {
use rustc::hir::*; use rustc::hir::*;
let hir_id = match tcx.hir().as_local_hir_id(def_id) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
Some(hir_id) => hir_id,
None => {
if !fail {
return None;
}
bug!("invalid node");
}
};
let icx = ItemCtxt::new(tcx, def_id); let icx = ItemCtxt::new(tcx, def_id);
Some(match tcx.hir().get(hir_id) { match tcx.hir().get(hir_id) {
Node::TraitItem(item) => match item.kind { Node::TraitItem(item) => match item.kind {
TraitItemKind::Method(..) => { TraitItemKind::Method(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id); let substs = InternalSubsts::identity_for_item(tcx, def_id);
@ -1229,9 +1213,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
}, },
TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty), TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
TraitItemKind::Type(_, None) => { TraitItemKind::Type(_, None) => {
if !fail {
return None;
}
span_bug!(item.span, "associated type missing default"); span_bug!(item.span, "associated type missing default");
} }
}, },
@ -1325,9 +1306,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
| ItemKind::GlobalAsm(..) | ItemKind::GlobalAsm(..)
| ItemKind::ExternCrate(..) | ItemKind::ExternCrate(..)
| ItemKind::Use(..) => { | ItemKind::Use(..) => {
if !fail {
return None;
}
span_bug!( span_bug!(
item.span, item.span,
"compute_type_of_item: unexpected item type: {:?}", "compute_type_of_item: unexpected item type: {:?}",
@ -1365,7 +1343,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
.. ..
}) => { }) => {
if gen.is_some() { if gen.is_some() {
return Some(tcx.typeck_tables_of(def_id).node_type(hir_id)); return tcx.typeck_tables_of(def_id).node_type(hir_id);
} }
let substs = InternalSubsts::identity_for_item(tcx, def_id); let substs = InternalSubsts::identity_for_item(tcx, def_id);
@ -1440,13 +1418,9 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
.map(|(index, _)| index) .map(|(index, _)| index)
.next() .next()
}) })
.or_else(|| { .unwrap_or_else(|| {
if !fail { bug!("no arg matching AnonConst in path");
None });
} else {
bug!("no arg matching AnonConst in path")
}
})?;
// We've encountered an `AnonConst` in some path, so we need to // We've encountered an `AnonConst` in some path, so we need to
// figure out which generic parameter it corresponds to and return // figure out which generic parameter it corresponds to and return
@ -1456,8 +1430,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
tcx.generics_of(tcx.parent(def_id).unwrap()) tcx.generics_of(tcx.parent(def_id).unwrap())
} }
Res::Def(_, def_id) => tcx.generics_of(def_id), Res::Def(_, def_id) => tcx.generics_of(def_id),
Res::Err => return Some(tcx.types.err), Res::Err => return tcx.types.err,
_ if !fail => return None,
res => { res => {
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
DUMMY_SP, DUMMY_SP,
@ -1466,7 +1439,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
res, res,
), ),
); );
return Some(tcx.types.err); return tcx.types.err;
} }
}; };
@ -1484,9 +1457,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
// probably from an extra arg where one is not needed. // probably from an extra arg where one is not needed.
.unwrap_or(tcx.types.err) .unwrap_or(tcx.types.err)
} else { } else {
if !fail {
return None;
}
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
DUMMY_SP, DUMMY_SP,
&format!( &format!(
@ -1494,14 +1464,11 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
parent_node, parent_node,
), ),
); );
return Some(tcx.types.err); return tcx.types.err;
} }
} }
x => { x => {
if !fail {
return None;
}
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
DUMMY_SP, DUMMY_SP,
&format!( &format!(
@ -1551,21 +1518,13 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
} }
ty ty
} }
x => { x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
if !fail {
return None;
}
bug!("unexpected non-type Node::GenericParam: {:?}", x)
},
}, },
x => { x => {
if !fail {
return None;
}
bug!("unexpected sort of node in type_of_def_id(): {:?}", x); bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
} }
}) }
} }
fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
@ -2075,10 +2034,7 @@ fn explicit_predicates_of(
} }
} }
let hir_id = match tcx.hir().as_local_hir_id(def_id) { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
Some(hir_id) => hir_id,
None => return tcx.predicates_of(def_id),
};
let node = tcx.hir().get(hir_id); let node = tcx.hir().get(hir_id);
let mut is_trait = None; let mut is_trait = None;

View file

@ -109,8 +109,6 @@ use util::common::time;
use std::iter; use std::iter;
use astconv::{AstConv, Bounds}; use astconv::{AstConv, Bounds};
pub use collect::checked_type_of;
pub struct TypeAndSubsts<'tcx> { pub struct TypeAndSubsts<'tcx> {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,

View file

@ -1492,12 +1492,13 @@ impl GenericParamDefKind {
} }
} }
pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> { // FIXME(eddyb) this either returns the default of a type parameter, or the
match *self { // type of a `const` parameter. It seems that the intention is to *visit*
GenericParamDefKind::Type { did, .. } => { // any embedded types, but `get_type` seems to be the wrong name for that.
rustc_typeck::checked_type_of(cx.tcx, did, false).map(|t| t.clean(cx)) pub fn get_type(&self) -> Option<Type> {
} match self {
GenericParamDefKind::Const { ref ty, .. } => Some(ty.clone()), GenericParamDefKind::Type { default, .. } => default.clone(),
GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
GenericParamDefKind::Lifetime => None, GenericParamDefKind::Lifetime => None,
} }
} }
@ -1523,8 +1524,8 @@ impl GenericParamDef {
self.kind.is_type() self.kind.is_type()
} }
pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> { pub fn get_type(&self) -> Option<Type> {
self.kind.get_type(cx) self.kind.get_type()
} }
pub fn get_bounds(&self) -> Option<&[GenericBound]> { pub fn get_bounds(&self) -> Option<&[GenericBound]> {
@ -1892,7 +1893,7 @@ fn get_real_types(
if !x.is_type() { if !x.is_type() {
continue continue
} }
if let Some(ty) = x.get_type(cx) { if let Some(ty) = x.get_type() {
let adds = get_real_types(generics, &ty, cx, recurse + 1); let adds = get_real_types(generics, &ty, cx, recurse + 1);
if !adds.is_empty() { if !adds.is_empty() {
res.extend(adds); res.extend(adds);

View file

@ -20,5 +20,4 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
rustc_data_structures = { path = "../librustc_data_structures" } rustc_data_structures = { path = "../librustc_data_structures" }
rustc_index = { path = "../librustc_index" } rustc_index = { path = "../librustc_index" }
rustc_lexer = { path = "../librustc_lexer" } rustc_lexer = { path = "../librustc_lexer" }
rustc_target = { path = "../librustc_target" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] } smallvec = { version = "1.0", features = ["union", "may_dangle"] }

View file

@ -22,7 +22,6 @@ pub use GenericArgs::*;
pub use UnsafeSource::*; pub use UnsafeSource::*;
pub use crate::util::parser::ExprPrecedence; pub use crate::util::parser::ExprPrecedence;
pub use rustc_target::abi::FloatTy;
pub use syntax_pos::symbol::{Ident, Symbol as Name}; pub use syntax_pos::symbol::{Ident, Symbol as Name};
use crate::parse::token::{self, DelimToken}; use crate::parse::token::{self, DelimToken};
@ -38,7 +37,6 @@ use rustc_data_structures::sync::Lrc;
use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::thin_vec::ThinVec;
use rustc_index::vec::Idx; use rustc_index::vec::Idx;
use rustc_serialize::{self, Decoder, Encoder}; use rustc_serialize::{self, Decoder, Encoder};
use rustc_target::spec::abi::Abi;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use rustc_data_structures::static_assert_size; use rustc_data_structures::static_assert_size;
@ -1401,7 +1399,7 @@ pub struct Lit {
// Clippy uses Hash and PartialEq // Clippy uses Hash and PartialEq
/// Type of the integer literal based on provided suffix. /// Type of the integer literal based on provided suffix.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)] #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
pub enum LitIntType { pub enum LitIntType {
/// e.g. `42_i32`. /// e.g. `42_i32`.
Signed(IntTy), Signed(IntTy),
@ -1411,6 +1409,15 @@ pub enum LitIntType {
Unsuffixed, Unsuffixed,
} }
/// Type of the float literal based on provided suffix.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
pub enum LitFloatType {
/// A float literal with a suffix (`1f32` or `1E10f32`).
Suffixed(FloatTy),
/// A float literal without a suffix (`1.0 or 1.0E10`).
Unsuffixed,
}
/// Literal kind. /// Literal kind.
/// ///
/// E.g., `"foo"`, `42`, `12.34`, or `bool`. /// E.g., `"foo"`, `42`, `12.34`, or `bool`.
@ -1428,9 +1435,7 @@ pub enum LitKind {
/// An integer literal (`1`). /// An integer literal (`1`).
Int(u128, LitIntType), Int(u128, LitIntType),
/// A float literal (`1f64` or `1E10f64`). /// A float literal (`1f64` or `1E10f64`).
Float(Symbol, FloatTy), Float(Symbol, LitFloatType),
/// A float literal without a suffix (`1.0 or 1.0E10`).
FloatUnsuffixed(Symbol),
/// A boolean literal. /// A boolean literal.
Bool(bool), Bool(bool),
/// Placeholder for a literal that wasn't well-formed in some way. /// Placeholder for a literal that wasn't well-formed in some way.
@ -1457,7 +1462,7 @@ impl LitKind {
/// Returns `true` if this is a numeric literal. /// Returns `true` if this is a numeric literal.
pub fn is_numeric(&self) -> bool { pub fn is_numeric(&self) -> bool {
match *self { match *self {
LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => true, LitKind::Int(..) | LitKind::Float(..) => true,
_ => false, _ => false,
} }
} }
@ -1474,14 +1479,14 @@ impl LitKind {
// suffixed variants // suffixed variants
LitKind::Int(_, LitIntType::Signed(..)) LitKind::Int(_, LitIntType::Signed(..))
| LitKind::Int(_, LitIntType::Unsigned(..)) | LitKind::Int(_, LitIntType::Unsigned(..))
| LitKind::Float(..) => true, | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
// unsuffixed variants // unsuffixed variants
LitKind::Str(..) LitKind::Str(..)
| LitKind::ByteStr(..) | LitKind::ByteStr(..)
| LitKind::Byte(..) | LitKind::Byte(..)
| LitKind::Char(..) | LitKind::Char(..)
| LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Int(_, LitIntType::Unsuffixed)
| LitKind::FloatUnsuffixed(..) | LitKind::Float(_, LitFloatType::Unsuffixed)
| LitKind::Bool(..) | LitKind::Bool(..)
| LitKind::Err(..) => false, | LitKind::Err(..) => false,
} }
@ -1553,7 +1558,36 @@ pub enum ImplItemKind {
Macro(Mac), Macro(Mac),
} }
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum FloatTy {
F32,
F64,
}
impl FloatTy {
pub fn name_str(self) -> &'static str {
match self {
FloatTy::F32 => "f32",
FloatTy::F64 => "f64",
}
}
pub fn name(self) -> Symbol {
match self {
FloatTy::F32 => sym::f32,
FloatTy::F64 => sym::f64,
}
}
pub fn bit_width(self) -> usize {
match self {
FloatTy::F32 => 32,
FloatTy::F64 => 64,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum IntTy { pub enum IntTy {
Isize, Isize,
I8, I8,
@ -1563,20 +1597,8 @@ pub enum IntTy {
I128, I128,
} }
impl fmt::Debug for IntTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for IntTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ty_to_string())
}
}
impl IntTy { impl IntTy {
pub fn ty_to_string(&self) -> &'static str { pub fn name_str(&self) -> &'static str {
match *self { match *self {
IntTy::Isize => "isize", IntTy::Isize => "isize",
IntTy::I8 => "i8", IntTy::I8 => "i8",
@ -1587,7 +1609,7 @@ impl IntTy {
} }
} }
pub fn to_symbol(&self) -> Symbol { pub fn name(&self) -> Symbol {
match *self { match *self {
IntTy::Isize => sym::isize, IntTy::Isize => sym::isize,
IntTy::I8 => sym::i8, IntTy::I8 => sym::i8,
@ -1602,7 +1624,7 @@ impl IntTy {
// Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
// are parsed as `u128`, so we wouldn't want to print an extra negative // are parsed as `u128`, so we wouldn't want to print an extra negative
// sign. // sign.
format!("{}{}", val as u128, self.ty_to_string()) format!("{}{}", val as u128, self.name_str())
} }
pub fn bit_width(&self) -> Option<usize> { pub fn bit_width(&self) -> Option<usize> {
@ -1617,7 +1639,7 @@ impl IntTy {
} }
} }
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy, Debug)]
pub enum UintTy { pub enum UintTy {
Usize, Usize,
U8, U8,
@ -1628,7 +1650,7 @@ pub enum UintTy {
} }
impl UintTy { impl UintTy {
pub fn ty_to_string(&self) -> &'static str { pub fn name_str(&self) -> &'static str {
match *self { match *self {
UintTy::Usize => "usize", UintTy::Usize => "usize",
UintTy::U8 => "u8", UintTy::U8 => "u8",
@ -1639,7 +1661,7 @@ impl UintTy {
} }
} }
pub fn to_symbol(&self) -> Symbol { pub fn name(&self) -> Symbol {
match *self { match *self {
UintTy::Usize => sym::usize, UintTy::Usize => sym::usize,
UintTy::U8 => sym::u8, UintTy::U8 => sym::u8,
@ -1651,7 +1673,7 @@ impl UintTy {
} }
pub fn val_to_string(&self, val: u128) -> String { pub fn val_to_string(&self, val: u128) -> String {
format!("{}{}", val, self.ty_to_string()) format!("{}{}", val, self.name_str())
} }
pub fn bit_width(&self) -> Option<usize> { pub fn bit_width(&self) -> Option<usize> {
@ -1666,18 +1688,6 @@ impl UintTy {
} }
} }
impl fmt::Debug for UintTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for UintTy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.ty_to_string())
}
}
/// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or /// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
/// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`). /// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@ -2358,6 +2368,27 @@ impl Item {
} }
} }
/// A reference to an ABI.
///
/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
pub struct Abi {
pub symbol: Symbol,
pub span: Span,
}
impl Abi {
pub fn new(symbol: Symbol, span: Span) -> Self {
Self { symbol, span }
}
}
impl Default for Abi {
fn default() -> Self {
Self::new(sym::Rust, DUMMY_SP)
}
}
/// A function header. /// A function header.
/// ///
/// All the information between the visibility and the name of the function is /// All the information between the visibility and the name of the function is
@ -2376,7 +2407,7 @@ impl Default for FnHeader {
unsafety: Unsafety::Normal, unsafety: Unsafety::Normal,
asyncness: dummy_spanned(IsAsync::NotAsync), asyncness: dummy_spanned(IsAsync::NotAsync),
constness: dummy_spanned(Constness::NotConst), constness: dummy_spanned(Constness::NotConst),
abi: Abi::Rust, abi: Abi::default(),
} }
} }
} }

View file

@ -540,6 +540,5 @@ equivalent in Rust would be to use macros directly.
E0630, E0630,
E0693, // incorrect `repr(align)` attribute format E0693, // incorrect `repr(align)` attribute format
// E0694, // an unknown tool name found in scoped attributes // E0694, // an unknown tool name found in scoped attributes
E0703, // invalid ABI
E0717, // rustc_promotable without stability attribute E0717, // rustc_promotable without stability attribute
} }

View file

@ -18,7 +18,6 @@ use crate::tokenstream::TokenTree;
use errors::{Applicability, DiagnosticBuilder, Handler}; use errors::{Applicability, DiagnosticBuilder, Handler};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_target::spec::abi::Abi;
use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use log::debug; use log::debug;
@ -192,62 +191,70 @@ macro_rules! gate_feature_post {
} }
impl<'a> PostExpansionVisitor<'a> { impl<'a> PostExpansionVisitor<'a> {
fn check_abi(&self, abi: Abi, span: Span) { fn check_abi(&self, abi: ast::Abi) {
match abi { let ast::Abi { symbol, span } = abi;
Abi::RustIntrinsic => {
match &*symbol.as_str() {
// Stable
"Rust" |
"C" |
"cdecl" |
"stdcall" |
"fastcall" |
"aapcs" |
"win64" |
"sysv64" |
"system" => {}
"rust-intrinsic" => {
gate_feature_post!(&self, intrinsics, span, gate_feature_post!(&self, intrinsics, span,
"intrinsics are subject to change"); "intrinsics are subject to change");
}, },
Abi::PlatformIntrinsic => { "platform-intrinsic" => {
gate_feature_post!(&self, platform_intrinsics, span, gate_feature_post!(&self, platform_intrinsics, span,
"platform intrinsics are experimental and possibly buggy"); "platform intrinsics are experimental and possibly buggy");
}, },
Abi::Vectorcall => { "vectorcall" => {
gate_feature_post!(&self, abi_vectorcall, span, gate_feature_post!(&self, abi_vectorcall, span,
"vectorcall is experimental and subject to change"); "vectorcall is experimental and subject to change");
}, },
Abi::Thiscall => { "thiscall" => {
gate_feature_post!(&self, abi_thiscall, span, gate_feature_post!(&self, abi_thiscall, span,
"thiscall is experimental and subject to change"); "thiscall is experimental and subject to change");
}, },
Abi::RustCall => { "rust-call" => {
gate_feature_post!(&self, unboxed_closures, span, gate_feature_post!(&self, unboxed_closures, span,
"rust-call ABI is subject to change"); "rust-call ABI is subject to change");
}, },
Abi::PtxKernel => { "ptx-kernel" => {
gate_feature_post!(&self, abi_ptx, span, gate_feature_post!(&self, abi_ptx, span,
"PTX ABIs are experimental and subject to change"); "PTX ABIs are experimental and subject to change");
}, },
Abi::Unadjusted => { "unadjusted" => {
gate_feature_post!(&self, abi_unadjusted, span, gate_feature_post!(&self, abi_unadjusted, span,
"unadjusted ABI is an implementation detail and perma-unstable"); "unadjusted ABI is an implementation detail and perma-unstable");
}, },
Abi::Msp430Interrupt => { "msp430-interrupt" => {
gate_feature_post!(&self, abi_msp430_interrupt, span, gate_feature_post!(&self, abi_msp430_interrupt, span,
"msp430-interrupt ABI is experimental and subject to change"); "msp430-interrupt ABI is experimental and subject to change");
}, },
Abi::X86Interrupt => { "x86-interrupt" => {
gate_feature_post!(&self, abi_x86_interrupt, span, gate_feature_post!(&self, abi_x86_interrupt, span,
"x86-interrupt ABI is experimental and subject to change"); "x86-interrupt ABI is experimental and subject to change");
}, },
Abi::AmdGpuKernel => { "amdgpu-kernel" => {
gate_feature_post!(&self, abi_amdgpu_kernel, span, gate_feature_post!(&self, abi_amdgpu_kernel, span,
"amdgpu-kernel ABI is experimental and subject to change"); "amdgpu-kernel ABI is experimental and subject to change");
}, },
Abi::EfiApi => { "efiapi" => {
gate_feature_post!(&self, abi_efiapi, span, gate_feature_post!(&self, abi_efiapi, span,
"efiapi ABI is experimental and subject to change"); "efiapi ABI is experimental and subject to change");
}, },
// Stable abi => {
Abi::Cdecl | self.parse_sess.span_diagnostic.delay_span_bug(
Abi::Stdcall | span,
Abi::Fastcall | &format!("unrecognized ABI not caught in lowering: {}", abi),
Abi::Aapcs | )
Abi::Win64 | }
Abi::SysV64 |
Abi::Rust |
Abi::C |
Abi::System => {}
} }
} }
@ -373,7 +380,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_item(&mut self, i: &'a ast::Item) { fn visit_item(&mut self, i: &'a ast::Item) {
match i.kind { match i.kind {
ast::ItemKind::ForeignMod(ref foreign_module) => { ast::ItemKind::ForeignMod(ref foreign_module) => {
self.check_abi(foreign_module.abi, i.span); self.check_abi(foreign_module.abi);
} }
ast::ItemKind::Fn(..) => { ast::ItemKind::Fn(..) => {
@ -503,7 +510,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_ty(&mut self, ty: &'a ast::Ty) { fn visit_ty(&mut self, ty: &'a ast::Ty) {
match ty.kind { match ty.kind {
ast::TyKind::BareFn(ref bare_fn_ty) => { ast::TyKind::BareFn(ref bare_fn_ty) => {
self.check_abi(bare_fn_ty.abi, ty.span); self.check_abi(bare_fn_ty.abi);
} }
ast::TyKind::Never => { ast::TyKind::Never => {
gate_feature_post!(&self, never_type, ty.span, gate_feature_post!(&self, never_type, ty.span,
@ -597,7 +604,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
// Stability of const fn methods are covered in // Stability of const fn methods are covered in
// `visit_trait_item` and `visit_impl_item` below; this is // `visit_trait_item` and `visit_impl_item` below; this is
// because default methods don't pass through this point. // because default methods don't pass through this point.
self.check_abi(header.abi, span); self.check_abi(header.abi);
} }
if fn_decl.c_variadic() { if fn_decl.c_variadic() {
@ -631,7 +638,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
match ti.kind { match ti.kind {
ast::TraitItemKind::Method(ref sig, ref block) => { ast::TraitItemKind::Method(ref sig, ref block) => {
if block.is_none() { if block.is_none() {
self.check_abi(sig.header.abi, ti.span); self.check_abi(sig.header.abi);
} }
if sig.decl.c_variadic() { if sig.decl.c_variadic() {
gate_feature_post!(&self, c_variadic, ti.span, gate_feature_post!(&self, c_variadic, ti.span,
@ -863,18 +870,17 @@ pub fn check_crate(krate: &ast::Crate,
maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable); maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
let mut visitor = PostExpansionVisitor { parse_sess, features }; let mut visitor = PostExpansionVisitor { parse_sess, features };
let spans = parse_sess.gated_spans.spans.borrow();
macro_rules! gate_all { macro_rules! gate_all {
($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); }; ($gate:ident, $msg:literal) => {
($spans:ident, $gate:ident, $msg:literal) => { for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
for span in &*parse_sess.gated_spans.$spans.borrow() {
gate_feature!(&visitor, $gate, *span, $msg); gate_feature!(&visitor, $gate, *span, $msg);
} }
} }
} }
gate_all!(let_chains, "`let` expressions in this position are experimental"); gate_all!(let_chains, "`let` expressions in this position are experimental");
gate_all!(async_closure, "async closures are unstable"); gate_all!(async_closure, "async closures are unstable");
gate_all!(yields, generators, "yield syntax is experimental"); gate_all!(generators, "yield syntax is experimental");
gate_all!(or_patterns, "or-patterns syntax is experimental"); gate_all!(or_patterns, "or-patterns syntax is experimental");
gate_all!(const_extern_fn, "`const extern fn` definitions are unstable"); gate_all!(const_extern_fn, "`const extern fn` definitions are unstable");
@ -885,7 +891,7 @@ pub fn check_crate(krate: &ast::Crate,
// FIXME(eddyb) do something more useful than always // FIXME(eddyb) do something more useful than always
// disabling these uses of early feature-gatings. // disabling these uses of early feature-gatings.
if false { if false {
for span in &*parse_sess.gated_spans.$gate.borrow() { for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
gate_feature!(&visitor, $gate, *span, $msg); gate_feature!(&visitor, $gate, *span, $msg);
} }
} }
@ -902,7 +908,6 @@ pub fn check_crate(krate: &ast::Crate,
gate_all!(try_blocks, "`try` blocks are unstable"); gate_all!(try_blocks, "`try` blocks are unstable");
gate_all!(label_break_value, "labels on blocks are unstable"); gate_all!(label_break_value, "labels on blocks are unstable");
gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead"); gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
// To avoid noise about type ascription in common syntax errors, // To avoid noise about type ascription in common syntax errors,
// only emit if it is the *only* error. (Also check it last.) // only emit if it is the *only* error. (Also check it last.)
if parse_sess.span_diagnostic.err_count() == 0 { if parse_sess.span_diagnostic.err_count() == 0 {

View file

@ -157,17 +157,18 @@ impl LitKind {
} }
LitKind::Int(n, ty) => { LitKind::Int(n, ty) => {
let suffix = match ty { let suffix = match ty {
ast::LitIntType::Unsigned(ty) => Some(ty.to_symbol()), ast::LitIntType::Unsigned(ty) => Some(ty.name()),
ast::LitIntType::Signed(ty) => Some(ty.to_symbol()), ast::LitIntType::Signed(ty) => Some(ty.name()),
ast::LitIntType::Unsuffixed => None, ast::LitIntType::Unsuffixed => None,
}; };
(token::Integer, sym::integer(n), suffix) (token::Integer, sym::integer(n), suffix)
} }
LitKind::Float(symbol, ty) => { LitKind::Float(symbol, ty) => {
(token::Float, symbol, Some(ty.to_symbol())) let suffix = match ty {
} ast::LitFloatType::Suffixed(ty) => Some(ty.name()),
LitKind::FloatUnsuffixed(symbol) => { ast::LitFloatType::Unsuffixed => None,
(token::Float, symbol, None) };
(token::Float, symbol, suffix)
} }
LitKind::Bool(value) => { LitKind::Bool(value) => {
let symbol = if value { kw::True } else { kw::False }; let symbol = if value { kw::True } else { kw::False };
@ -244,12 +245,12 @@ fn filtered_float_lit(symbol: Symbol, suffix: Option<Symbol>, base: u32)
return Err(LitError::NonDecimalFloat(base)); return Err(LitError::NonDecimalFloat(base));
} }
Ok(match suffix { Ok(match suffix {
Some(suf) => match suf { Some(suf) => LitKind::Float(symbol, ast::LitFloatType::Suffixed(match suf {
sym::f32 => LitKind::Float(symbol, ast::FloatTy::F32), sym::f32 => ast::FloatTy::F32,
sym::f64 => LitKind::Float(symbol, ast::FloatTy::F64), sym::f64 => ast::FloatTy::F64,
_ => return Err(LitError::InvalidFloatSuffix), _ => return Err(LitError::InvalidFloatSuffix),
} })),
None => LitKind::FloatUnsuffixed(symbol) None => LitKind::Float(symbol, ast::LitFloatType::Unsuffixed)
}) })
} }

View file

@ -12,7 +12,7 @@ mod diagnostics;
use diagnostics::Error; use diagnostics::Error;
use crate::ast::{ use crate::ast::{
self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident, self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety, IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
}; };
use crate::parse::{PResult, Directory, DirectoryOwnership}; use crate::parse::{PResult, Directory, DirectoryOwnership};
@ -28,7 +28,6 @@ use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
use crate::ThinVec; use crate::ThinVec;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
use rustc_target::spec::abi::{self, Abi};
use syntax_pos::{Span, BytePos, DUMMY_SP, FileName}; use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
use log::debug; use log::debug;
@ -1121,7 +1120,7 @@ impl<'a> Parser<'a> {
self.expected_tokens.push(TokenType::Keyword(kw::Crate)); self.expected_tokens.push(TokenType::Keyword(kw::Crate));
if self.is_crate_vis() { if self.is_crate_vis() {
self.bump(); // `crate` self.bump(); // `crate`
self.sess.gated_spans.crate_visibility_modifier.borrow_mut().push(self.prev_span); self.sess.gated_spans.gate(sym::crate_visibility_modifier, self.prev_span);
return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate))); return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate)));
} }
@ -1206,49 +1205,42 @@ impl<'a> Parser<'a> {
Ok(()) Ok(())
} }
/// Parses `extern` followed by an optional ABI string, or nothing. /// Parses `extern string_literal?`.
/// If `extern` is not found, the Rust ABI is used.
/// If `extern` is found and a `string_literal` does not follow, the C ABI is used.
fn parse_extern_abi(&mut self) -> PResult<'a, Abi> { fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
if self.eat_keyword(kw::Extern) { Ok(if self.eat_keyword(kw::Extern) {
Ok(self.parse_opt_abi()?.unwrap_or(Abi::C)) self.parse_opt_abi()?
} else { } else {
Ok(Abi::Rust) Abi::default()
} })
} }
/// Parses a string as an ABI spec on an extern type or module. Consumes /// Parses a string literal as an ABI spec.
/// the `extern` keyword, if one is found. /// If one is not found, the "C" ABI is used.
fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> { fn parse_opt_abi(&mut self) -> PResult<'a, Abi> {
match self.token.kind { let span = if self.token.can_begin_literal_or_bool() {
token::Literal(token::Lit { kind: token::Str, symbol, suffix }) | let ast::Lit { span, kind, .. } = self.parse_lit()?;
token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => { match kind {
self.expect_no_suffix(self.token.span, "an ABI spec", suffix); ast::LitKind::Str(symbol, _) => return Ok(Abi::new(symbol, span)),
self.bump(); ast::LitKind::Err(_) => {}
match abi::lookup(&symbol.as_str()) { _ => {
Some(abi) => Ok(Some(abi)), self.struct_span_err(span, "non-string ABI literal")
None => { .span_suggestion(
self.error_on_invalid_abi(symbol); span,
Ok(None) "specify the ABI with a string literal",
} "\"C\"".to_string(),
} Applicability::MaybeIncorrect,
}
_ => Ok(None),
}
}
/// Emit an error where `symbol` is an invalid ABI.
fn error_on_invalid_abi(&self, symbol: Symbol) {
let prev_span = self.prev_span;
struct_span_err!(
self.sess.span_diagnostic,
prev_span,
E0703,
"invalid ABI: found `{}`",
symbol
) )
.span_label(prev_span, "invalid ABI")
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
.emit(); .emit();
} }
}
span
} else {
self.prev_span
};
Ok(Abi::new(sym::C, span))
}
/// We are parsing `async fn`. If we are on Rust 2015, emit an error. /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
fn ban_async_in_2015(&self, async_span: Span) { fn ban_async_in_2015(&self, async_span: Span) {

View file

@ -16,10 +16,10 @@ use crate::parse::token::{self, Token, TokenKind};
use crate::print::pprust; use crate::print::pprust;
use crate::ptr::P; use crate::ptr::P;
use crate::source_map::{self, Span}; use crate::source_map::{self, Span};
use crate::symbol::{kw, sym};
use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par}; use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
use errors::Applicability; use errors::Applicability;
use syntax_pos::symbol::{kw, sym};
use syntax_pos::Symbol; use syntax_pos::Symbol;
use std::mem; use std::mem;
use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::thin_vec::ThinVec;
@ -252,7 +252,7 @@ impl<'a> Parser<'a> {
self.last_type_ascription = Some((self.prev_span, maybe_path)); self.last_type_ascription = Some((self.prev_span, maybe_path));
lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?; lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
self.sess.gated_spans.type_ascription.borrow_mut().push(lhs.span); self.sess.gated_spans.gate(sym::type_ascription, lhs.span);
continue continue
} else if op == AssocOp::DotDot || op == AssocOp::DotDotEq { } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
// If we didnt have to handle `x..`/`x..=`, it would be pretty easy to // If we didnt have to handle `x..`/`x..=`, it would be pretty easy to
@ -455,7 +455,7 @@ impl<'a> Parser<'a> {
let e = self.parse_prefix_expr(None); let e = self.parse_prefix_expr(None);
let (span, e) = self.interpolated_or_expr_span(e)?; let (span, e) = self.interpolated_or_expr_span(e)?;
let span = lo.to(span); let span = lo.to(span);
self.sess.gated_spans.box_syntax.borrow_mut().push(span); self.sess.gated_spans.gate(sym::box_syntax, span);
(span, ExprKind::Box(e)) (span, ExprKind::Box(e))
} }
token::Ident(..) if self.token.is_ident_named(sym::not) => { token::Ident(..) if self.token.is_ident_named(sym::not) => {
@ -1045,7 +1045,7 @@ impl<'a> Parser<'a> {
} }
let span = lo.to(hi); let span = lo.to(hi);
self.sess.gated_spans.yields.borrow_mut().push(span); self.sess.gated_spans.gate(sym::generators, span);
} else if self.eat_keyword(kw::Let) { } else if self.eat_keyword(kw::Let) {
return self.parse_let_expr(attrs); return self.parse_let_expr(attrs);
} else if is_span_rust_2018 && self.eat_keyword(kw::Await) { } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
@ -1116,7 +1116,11 @@ impl<'a> Parser<'a> {
Err(self.span_fatal(token.span, &msg)) Err(self.span_fatal(token.span, &msg))
} }
Err(err) => { Err(err) => {
let (lit, span) = (token.expect_lit(), token.span); let span = token.span;
let lit = match token.kind {
token::Literal(lit) => lit,
_ => unreachable!(),
};
self.bump(); self.bump();
self.error_literal_from_token(err, lit, span); self.error_literal_from_token(err, lit, span);
// Pack possible quotes and prefixes from the original literal into // Pack possible quotes and prefixes from the original literal into
@ -1264,7 +1268,7 @@ impl<'a> Parser<'a> {
outer_attrs: ThinVec<Attribute>, outer_attrs: ThinVec<Attribute>,
) -> PResult<'a, P<Expr>> { ) -> PResult<'a, P<Expr>> {
if let Some(label) = opt_label { if let Some(label) = opt_label {
self.sess.gated_spans.label_break_value.borrow_mut().push(label.ident.span); self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
} }
self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::OpenDelim(token::Brace))?;
@ -1293,7 +1297,7 @@ impl<'a> Parser<'a> {
}; };
if asyncness.is_async() { if asyncness.is_async() {
// Feature-gate `async ||` closures. // Feature-gate `async ||` closures.
self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span); self.sess.gated_spans.gate(sym::async_closure, self.prev_span);
} }
let capture_clause = self.parse_capture_clause(); let capture_clause = self.parse_capture_clause();
@ -1415,8 +1419,7 @@ impl<'a> Parser<'a> {
if let ExprKind::Let(..) = cond.kind { if let ExprKind::Let(..) = cond.kind {
// Remove the last feature gating of a `let` expression since it's stable. // Remove the last feature gating of a `let` expression since it's stable.
let last = self.sess.gated_spans.let_chains.borrow_mut().pop(); self.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
debug_assert_eq!(cond.span, last.unwrap());
} }
Ok(cond) Ok(cond)
@ -1433,7 +1436,7 @@ impl<'a> Parser<'a> {
|this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
)?; )?;
let span = lo.to(expr.span); let span = lo.to(expr.span);
self.sess.gated_spans.let_chains.borrow_mut().push(span); self.sess.gated_spans.gate(sym::let_chains, span);
Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs)) Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs))
} }
@ -1654,7 +1657,7 @@ impl<'a> Parser<'a> {
Err(error) Err(error)
} else { } else {
let span = span_lo.to(body.span); let span = span_lo.to(body.span);
self.sess.gated_spans.try_blocks.borrow_mut().push(span); self.sess.gated_spans.gate(sym::try_blocks, span);
Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs)) Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
} }
} }

View file

@ -3,7 +3,8 @@ use super::{Parser, PResult};
use crate::ast::{self, WhereClause, GenericParam, GenericParamKind, GenericBounds, Attribute}; use crate::ast::{self, WhereClause, GenericParam, GenericParamKind, GenericBounds, Attribute};
use crate::parse::token; use crate::parse::token;
use crate::source_map::DUMMY_SP; use crate::source_map::DUMMY_SP;
use crate::symbol::kw;
use syntax_pos::symbol::{kw, sym};
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
/// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`. /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@ -62,7 +63,7 @@ impl<'a> Parser<'a> {
self.expect(&token::Colon)?; self.expect(&token::Colon)?;
let ty = self.parse_ty()?; let ty = self.parse_ty()?;
self.sess.gated_spans.const_generics.borrow_mut().push(lo.to(self.prev_span)); self.sess.gated_spans.gate(sym::const_generics, lo.to(self.prev_span));
Ok(GenericParam { Ok(GenericParam {
ident, ident,

View file

@ -3,7 +3,7 @@ use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim};
use crate::maybe_whole; use crate::maybe_whole;
use crate::ptr::P; use crate::ptr::P;
use crate::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item}; use crate::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
use crate::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind}; use crate::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness}; use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
@ -17,7 +17,6 @@ use crate::ThinVec;
use log::debug; use log::debug;
use std::mem; use std::mem;
use rustc_target::spec::abi::Abi;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
use syntax_pos::BytePos; use syntax_pos::BytePos;
@ -111,7 +110,7 @@ impl<'a> Parser<'a> {
return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?)); return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
} }
let opt_abi = self.parse_opt_abi()?; let abi = self.parse_opt_abi()?;
if self.eat_keyword(kw::Fn) { if self.eat_keyword(kw::Fn) {
// EXTERN FUNCTION ITEM // EXTERN FUNCTION ITEM
@ -120,12 +119,12 @@ impl<'a> Parser<'a> {
unsafety: Unsafety::Normal, unsafety: Unsafety::Normal,
asyncness: respan(fn_span, IsAsync::NotAsync), asyncness: respan(fn_span, IsAsync::NotAsync),
constness: respan(fn_span, Constness::NotConst), constness: respan(fn_span, Constness::NotConst),
abi: opt_abi.unwrap_or(Abi::C), abi,
}; };
return self.parse_item_fn(lo, vis, attrs, header); return self.parse_item_fn(lo, vis, attrs, header);
} else if self.check(&token::OpenDelim(token::Brace)) { } else if self.check(&token::OpenDelim(token::Brace)) {
return Ok(Some( return Ok(Some(
self.parse_item_foreign_mod(lo, opt_abi, vis, attrs, extern_sp)?, self.parse_item_foreign_mod(lo, abi, vis, attrs, extern_sp)?,
)); ));
} }
@ -147,9 +146,7 @@ impl<'a> Parser<'a> {
let unsafety = self.parse_unsafety(); let unsafety = self.parse_unsafety();
if self.check_keyword(kw::Extern) { if self.check_keyword(kw::Extern) {
self.sess.gated_spans.const_extern_fn.borrow_mut().push( self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span));
lo.to(self.token.span)
);
} }
let abi = self.parse_extern_abi()?; let abi = self.parse_extern_abi()?;
self.bump(); // `fn` self.bump(); // `fn`
@ -201,7 +198,7 @@ impl<'a> Parser<'a> {
unsafety, unsafety,
asyncness, asyncness,
constness: respan(fn_span, Constness::NotConst), constness: respan(fn_span, Constness::NotConst),
abi: Abi::Rust, abi: Abi::new(sym::Rust, fn_span),
}; };
return self.parse_item_fn(lo, vis, attrs, header); return self.parse_item_fn(lo, vis, attrs, header);
} }
@ -238,7 +235,7 @@ impl<'a> Parser<'a> {
unsafety: Unsafety::Normal, unsafety: Unsafety::Normal,
asyncness: respan(fn_span, IsAsync::NotAsync), asyncness: respan(fn_span, IsAsync::NotAsync),
constness: respan(fn_span, Constness::NotConst), constness: respan(fn_span, Constness::NotConst),
abi: Abi::Rust, abi: Abi::new(sym::Rust, fn_span),
}; };
return self.parse_item_fn(lo, vis, attrs, header); return self.parse_item_fn(lo, vis, attrs, header);
} }
@ -832,7 +829,7 @@ impl<'a> Parser<'a> {
.emit(); .emit();
} }
self.sess.gated_spans.trait_alias.borrow_mut().push(whole_span); self.sess.gated_spans.gate(sym::trait_alias, whole_span);
Ok((ident, ItemKind::TraitAlias(tps, bounds), None)) Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
} else { } else {
@ -1115,15 +1112,13 @@ impl<'a> Parser<'a> {
fn parse_item_foreign_mod( fn parse_item_foreign_mod(
&mut self, &mut self,
lo: Span, lo: Span,
opt_abi: Option<Abi>, abi: Abi,
visibility: Visibility, visibility: Visibility,
mut attrs: Vec<Attribute>, mut attrs: Vec<Attribute>,
extern_sp: Span, extern_sp: Span,
) -> PResult<'a, P<Item>> { ) -> PResult<'a, P<Item>> {
self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::OpenDelim(token::Brace))?;
let abi = opt_abi.unwrap_or(Abi::C);
attrs.extend(self.parse_inner_attributes()?); attrs.extend(self.parse_inner_attributes()?);
let mut foreign_items = vec![]; let mut foreign_items = vec![];
@ -1714,7 +1709,7 @@ impl<'a> Parser<'a> {
let span = lo.to(self.prev_span); let span = lo.to(self.prev_span);
if !def.legacy { if !def.legacy {
self.sess.gated_spans.decl_macro.borrow_mut().push(span); self.sess.gated_spans.gate(sym::decl_macro, span);
} }
Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec()))) Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
@ -1801,7 +1796,7 @@ impl<'a> Parser<'a> {
) -> PResult<'a, Option<P<Item>>> { ) -> PResult<'a, Option<P<Item>>> {
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: false, is_self_allowed: false,
allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe, allow_c_variadic: header.abi.symbol == sym::C && header.unsafety == Unsafety::Unsafe,
is_name_required: |_| true, is_name_required: |_| true,
})?; })?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
@ -1930,7 +1925,7 @@ impl<'a> Parser<'a> {
let asyncness = respan(self.prev_span, asyncness); let asyncness = respan(self.prev_span, asyncness);
let unsafety = self.parse_unsafety(); let unsafety = self.parse_unsafety();
let (constness, unsafety, abi) = if is_const_fn { let (constness, unsafety, abi) = if is_const_fn {
(respan(const_span, Constness::Const), unsafety, Abi::Rust) (respan(const_span, Constness::Const), unsafety, Abi::default())
} else { } else {
let abi = self.parse_extern_abi()?; let abi = self.parse_extern_abi()?;
(respan(self.prev_span, Constness::NotConst), unsafety, abi) (respan(self.prev_span, Constness::NotConst), unsafety, abi)

View file

@ -8,9 +8,8 @@ use crate::mut_visit::{noop_visit_pat, noop_visit_mac, MutVisitor};
use crate::parse::token::{self}; use crate::parse::token::{self};
use crate::print::pprust; use crate::print::pprust;
use crate::source_map::{respan, Span, Spanned}; use crate::source_map::{respan, Span, Spanned};
use crate::symbol::kw;
use crate::ThinVec; use crate::ThinVec;
use syntax_pos::symbol::{kw, sym};
use errors::{Applicability, DiagnosticBuilder}; use errors::{Applicability, DiagnosticBuilder};
type Expected = Option<&'static str>; type Expected = Option<&'static str>;
@ -52,11 +51,8 @@ impl<'a> Parser<'a> {
// and no other gated or-pattern has been parsed thus far, // and no other gated or-pattern has been parsed thus far,
// then we should really gate the leading `|`. // then we should really gate the leading `|`.
// This complicated procedure is done purely for diagnostics UX. // This complicated procedure is done purely for diagnostics UX.
if gated_leading_vert { if gated_leading_vert && self.sess.gated_spans.is_ungated(sym::or_patterns) {
let mut or_pattern_spans = self.sess.gated_spans.or_patterns.borrow_mut(); self.sess.gated_spans.gate(sym::or_patterns, leading_vert_span);
if or_pattern_spans.is_empty() {
or_pattern_spans.push(leading_vert_span);
}
} }
Ok(pat) Ok(pat)
@ -117,7 +113,7 @@ impl<'a> Parser<'a> {
// Feature gate the or-pattern if instructed: // Feature gate the or-pattern if instructed:
if gate_or == GateOr::Yes { if gate_or == GateOr::Yes {
self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span); self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
} }
Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats))) Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
@ -325,7 +321,7 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(kw::Box) { } else if self.eat_keyword(kw::Box) {
// Parse `box pat` // Parse `box pat`
let pat = self.parse_pat_with_range_pat(false, None)?; let pat = self.parse_pat_with_range_pat(false, None)?;
self.sess.gated_spans.box_patterns.borrow_mut().push(lo.to(self.prev_span)); self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_span));
PatKind::Box(pat) PatKind::Box(pat)
} else if self.can_be_ident_pat() { } else if self.can_be_ident_pat() {
// Parse `ident @ pat` // Parse `ident @ pat`
@ -612,7 +608,7 @@ impl<'a> Parser<'a> {
} }
fn excluded_range_end(&self, span: Span) -> RangeEnd { fn excluded_range_end(&self, span: Span) -> RangeEnd {
self.sess.gated_spans.exclusive_range_pattern.borrow_mut().push(span); self.sess.gated_spans.gate(sym::exclusive_range_pattern, span);
RangeEnd::Excluded RangeEnd::Excluded
} }

View file

@ -5,7 +5,7 @@ use crate::ast::{self, QSelf, Path, PathSegment, Ident, ParenthesizedArgs, Angle
use crate::ast::{AnonConst, GenericArg, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode}; use crate::ast::{AnonConst, GenericArg, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
use crate::parse::token::{self, Token}; use crate::parse::token::{self, Token};
use crate::source_map::{Span, BytePos}; use crate::source_map::{Span, BytePos};
use crate::symbol::kw; use syntax_pos::symbol::{kw, sym};
use std::mem; use std::mem;
use log::debug; use log::debug;
@ -426,7 +426,7 @@ impl<'a> Parser<'a> {
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`. // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
if let AssocTyConstraintKind::Bound { .. } = kind { if let AssocTyConstraintKind::Bound { .. } = kind {
self.sess.gated_spans.associated_type_bounds.borrow_mut().push(span); self.sess.gated_spans.gate(sym::associated_type_bounds, span);
} }
constraints.push(AssocTyConstraint { constraints.push(AssocTyConstraint {

View file

@ -381,9 +381,7 @@ impl Token {
match self.kind { match self.kind {
OpenDelim(Brace) => true, OpenDelim(Brace) => true,
Interpolated(ref nt) => match **nt { Interpolated(ref nt) => match **nt {
NtExpr(..) => true, NtExpr(..) | NtBlock(..) | NtLiteral(..) => true,
NtBlock(..) => true,
NtLiteral(..) => true,
_ => false, _ => false,
} }
_ => self.can_begin_literal_or_bool(), _ => self.can_begin_literal_or_bool(),
@ -404,13 +402,6 @@ impl Token {
} }
} }
crate fn expect_lit(&self) -> Lit {
match self.kind {
Literal(lit) => lit,
_ => panic!("`expect_lit` called on non-literal"),
}
}
/// Returns `true` if the token is any literal, a minus (which can prefix 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). /// for example a '-42', or one of the boolean idents).
pub fn can_begin_literal_or_bool(&self) -> bool { pub fn can_begin_literal_or_bool(&self) -> bool {

View file

@ -14,7 +14,6 @@ use crate::sess::ParseSess;
use crate::symbol::{kw, sym}; use crate::symbol::{kw, sym};
use crate::tokenstream::{self, TokenStream, TokenTree}; use crate::tokenstream::{self, TokenStream, TokenTree};
use rustc_target::spec::abi::{self, Abi};
use syntax_pos::{self, BytePos}; use syntax_pos::{self, BytePos};
use syntax_pos::{FileName, Span}; use syntax_pos::{FileName, Span};
@ -1230,7 +1229,7 @@ impl<'a> State<'a> {
} }
ast::ItemKind::ForeignMod(ref nmod) => { ast::ItemKind::ForeignMod(ref nmod) => {
self.head("extern"); self.head("extern");
self.word_nbsp(nmod.abi.to_string()); self.print_abi(nmod.abi);
self.bopen(); self.bopen();
self.print_foreign_mod(nmod, &item.attrs); self.print_foreign_mod(nmod, &item.attrs);
self.bclose(item.span); self.bclose(item.span);
@ -2823,7 +2822,7 @@ impl<'a> State<'a> {
} }
crate fn print_ty_fn(&mut self, crate fn print_ty_fn(&mut self,
abi: abi::Abi, abi: ast::Abi,
unsafety: ast::Unsafety, unsafety: ast::Unsafety,
decl: &ast::FnDecl, decl: &ast::FnDecl,
name: Option<ast::Ident>, name: Option<ast::Ident>,
@ -2884,14 +2883,18 @@ impl<'a> State<'a> {
self.print_asyncness(header.asyncness.node); self.print_asyncness(header.asyncness.node);
self.print_unsafety(header.unsafety); self.print_unsafety(header.unsafety);
if header.abi != Abi::Rust { if header.abi.symbol != sym::Rust {
self.word_nbsp("extern"); self.word_nbsp("extern");
self.word_nbsp(header.abi.to_string()); self.print_abi(header.abi);
} }
self.s.word("fn") self.s.word("fn")
} }
fn print_abi(&mut self, abi: ast::Abi) {
self.word_nbsp(format!("\"{}\"", abi.symbol));
}
crate fn print_unsafety(&mut self, s: ast::Unsafety) { crate fn print_unsafety(&mut self, s: ast::Unsafety) {
match s { match s {
ast::Unsafety::Normal => {}, ast::Unsafety::Normal => {},

View file

@ -34,12 +34,7 @@ fn test_fun_to_string() {
assert_eq!( assert_eq!(
fun_to_string( fun_to_string(
&decl, &decl,
ast::FnHeader { ast::FnHeader::default(),
unsafety: ast::Unsafety::Normal,
constness: source_map::dummy_spanned(ast::Constness::NotConst),
asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),
abi: Abi::Rust,
},
abba_ident, abba_ident,
&generics &generics
), ),

View file

@ -19,39 +19,53 @@ use std::str;
/// Collected spans during parsing for places where a certain feature was /// Collected spans during parsing for places where a certain feature was
/// used and should be feature gated accordingly in `check_crate`. /// used and should be feature gated accordingly in `check_crate`.
#[derive(Default)] #[derive(Default)]
crate struct GatedSpans { pub struct GatedSpans {
/// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`. pub spans: Lock<FxHashMap<Symbol, Vec<Span>>>,
crate let_chains: Lock<Vec<Span>>, }
/// Spans collected for gating `async_closure`, e.g. `async || ..`.
crate async_closure: Lock<Vec<Span>>, impl GatedSpans {
/// Spans collected for gating `yield e?` expressions (`generators` gate). /// Feature gate the given `span` under the given `feature`
crate yields: Lock<Vec<Span>>, /// which is same `Symbol` used in `active.rs`.
/// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`. pub fn gate(&self, feature: Symbol, span: Span) {
crate or_patterns: Lock<Vec<Span>>, self.spans
/// Spans collected for gating `const_extern_fn`, e.g. `const extern fn foo`. .borrow_mut()
crate const_extern_fn: Lock<Vec<Span>>, .entry(feature)
/// Spans collected for gating `trait_alias`, e.g. `trait Foo = Ord + Eq;`. .or_default()
pub trait_alias: Lock<Vec<Span>>, .push(span);
/// Spans collected for gating `associated_type_bounds`, e.g. `Iterator<Item: Ord>`. }
pub associated_type_bounds: Lock<Vec<Span>>,
/// Spans collected for gating `crate_visibility_modifier`, e.g. `crate fn`. /// Ungate the last span under the given `feature`.
pub crate_visibility_modifier: Lock<Vec<Span>>, /// Panics if the given `span` wasn't the last one.
/// Spans collected for gating `const_generics`, e.g. `const N: usize`. ///
pub const_generics: Lock<Vec<Span>>, /// Using this is discouraged unless you have a really good reason to.
/// Spans collected for gating `decl_macro`, e.g. `macro m() {}`. pub fn ungate_last(&self, feature: Symbol, span: Span) {
pub decl_macro: Lock<Vec<Span>>, let removed_span = self.spans
/// Spans collected for gating `box_patterns`, e.g. `box 0`. .borrow_mut()
pub box_patterns: Lock<Vec<Span>>, .entry(feature)
/// Spans collected for gating `exclusive_range_pattern`, e.g. `0..2`. .or_default()
pub exclusive_range_pattern: Lock<Vec<Span>>, .pop()
/// Spans collected for gating `try_blocks`, e.g. `try { a? + b? }`. .unwrap();
pub try_blocks: Lock<Vec<Span>>, debug_assert_eq!(span, removed_span);
/// Spans collected for gating `label_break_value`, e.g. `'label: { ... }`. }
pub label_break_value: Lock<Vec<Span>>,
/// Spans collected for gating `box_syntax`, e.g. `box $expr`. /// Is the provided `feature` gate ungated currently?
pub box_syntax: Lock<Vec<Span>>, ///
/// Spans collected for gating `type_ascription`, e.g. `42: usize`. /// Using this is discouraged unless you have a really good reason to.
pub type_ascription: Lock<Vec<Span>>, pub fn is_ungated(&self, feature: Symbol) -> bool {
self.spans
.borrow()
.get(&feature)
.map_or(true, |spans| spans.is_empty())
}
/// Prepend the given set of `spans` onto the set in `self`.
pub fn merge(&self, mut spans: FxHashMap<Symbol, Vec<Span>>) {
let mut inner = self.spans.borrow_mut();
for (gate, mut gate_spans) in inner.drain() {
spans.entry(gate).or_default().append(&mut gate_spans);
}
*inner = spans;
}
} }
/// Info about a parsing session. /// Info about a parsing session.
@ -72,7 +86,7 @@ pub struct ParseSess {
/// analysis. /// analysis.
pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>, pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
pub injected_crate_name: Once<Symbol>, pub injected_crate_name: Once<Symbol>,
crate gated_spans: GatedSpans, pub gated_spans: GatedSpans,
/// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors. /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
pub reached_eof: Lock<bool>, pub reached_eof: Lock<bool>,
} }

View file

@ -21,6 +21,5 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
rustc_data_structures = { path = "../librustc_data_structures" } rustc_data_structures = { path = "../librustc_data_structures" }
rustc_index = { path = "../librustc_index" } rustc_index = { path = "../librustc_index" }
rustc_lexer = { path = "../librustc_lexer" } rustc_lexer = { path = "../librustc_lexer" }
rustc_target = { path = "../librustc_target" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] } smallvec = { version = "1.0", features = ["union", "may_dangle"] }
syntax = { path = "../libsyntax" } syntax = { path = "../libsyntax" }

View file

@ -29,7 +29,7 @@ use syntax_pos::Span;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::slice; use std::{mem, slice};
use errors::Applicability; use errors::Applicability;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
@ -182,7 +182,6 @@ fn generic_extension<'cx>(
// Which arm's failure should we report? (the one furthest along) // Which arm's failure should we report? (the one furthest along)
let mut best_failure: Option<(Token, &str)> = None; let mut best_failure: Option<(Token, &str)> = None;
for (i, lhs) in lhses.iter().enumerate() { for (i, lhs) in lhses.iter().enumerate() {
// try each arm's matchers // try each arm's matchers
let lhs_tt = match *lhs { let lhs_tt = match *lhs {
@ -190,8 +189,18 @@ fn generic_extension<'cx>(
_ => cx.span_bug(sp, "malformed macro lhs"), _ => cx.span_bug(sp, "malformed macro lhs"),
}; };
// Take a snapshot of the state of pre-expansion gating at this point.
// This is used so that if a matcher is not `Success(..)`ful,
// then the spans which became gated when parsing the unsucessful matcher
// are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
let mut gated_spans_snaphot = mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut());
match parse_tt(cx, lhs_tt, arg.clone()) { match parse_tt(cx, lhs_tt, arg.clone()) {
Success(named_matches) => { Success(named_matches) => {
// The matcher was `Success(..)`ful.
// Merge the gated spans from parsing the matcher with the pre-existing ones.
cx.parse_sess.gated_spans.merge(gated_spans_snaphot);
let rhs = match rhses[i] { let rhs = match rhses[i] {
// ignore delimiters // ignore delimiters
mbe::TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(), mbe::TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(),
@ -248,6 +257,10 @@ fn generic_extension<'cx>(
}, },
Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]), Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]),
} }
// The matcher was not `Success(..)`ful.
// Restore to the state before snapshotting and maybe try again.
mem::swap(&mut gated_spans_snaphot, &mut cx.parse_sess.gated_spans.spans.borrow_mut());
} }
let (token, label) = best_failure.expect("ran no matchers"); let (token, label) = best_failure.expect("ran no matchers");

View file

@ -21,8 +21,7 @@ pub fn expand_concat(
match e.kind { match e.kind {
ast::ExprKind::Lit(ref lit) => match lit.kind { ast::ExprKind::Lit(ref lit) => match lit.kind {
ast::LitKind::Str(ref s, _) ast::LitKind::Str(ref s, _)
| ast::LitKind::Float(ref s, _) | ast::LitKind::Float(ref s, _) => {
| ast::LitKind::FloatUnsuffixed(ref s) => {
accumulator.push_str(&s.as_str()); accumulator.push_str(&s.as_str());
} }
ast::LitKind::Char(c) => { ast::LitKind::Char(c) => {

View file

@ -182,8 +182,7 @@ use std::iter;
use std::vec; use std::vec;
use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::thin_vec::ThinVec;
use rustc_target::spec::abi::Abi; use syntax::ast::{self, Abi, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
use syntax::ast::{VariantData, GenericParamKind, GenericArg}; use syntax::ast::{VariantData, GenericParamKind, GenericArg};
use syntax::attr; use syntax::attr;
use syntax::source_map::respan; use syntax::source_map::respan;
@ -738,7 +737,7 @@ impl<'a> TraitDef<'a> {
self, self,
type_ident, type_ident,
generics, generics,
Abi::Rust, sym::Rust,
explicit_self, explicit_self,
tys, tys,
body) body)
@ -793,7 +792,7 @@ impl<'a> TraitDef<'a> {
self, self,
type_ident, type_ident,
generics, generics,
Abi::Rust, sym::Rust,
explicit_self, explicit_self,
tys, tys,
body) body)
@ -919,7 +918,7 @@ impl<'a> MethodDef<'a> {
trait_: &TraitDef<'_>, trait_: &TraitDef<'_>,
type_ident: Ident, type_ident: Ident,
generics: &Generics, generics: &Generics,
abi: Abi, abi: Symbol,
explicit_self: Option<ast::ExplicitSelf>, explicit_self: Option<ast::ExplicitSelf>,
arg_types: Vec<(Ident, P<ast::Ty>)>, arg_types: Vec<(Ident, P<ast::Ty>)>,
body: P<Expr>) body: P<Expr>)
@ -949,23 +948,27 @@ impl<'a> MethodDef<'a> {
ast::Unsafety::Normal ast::Unsafety::Normal
}; };
let trait_lo_sp = trait_.span.shrink_to_lo();
let sig = ast::MethodSig {
header: ast::FnHeader {
unsafety,
abi: Abi::new(abi, trait_lo_sp),
..ast::FnHeader::default()
},
decl: fn_decl,
};
// Create the method. // Create the method.
ast::ImplItem { ast::ImplItem {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
attrs: self.attributes.clone(), attrs: self.attributes.clone(),
generics: fn_generics, generics: fn_generics,
span: trait_.span, span: trait_.span,
vis: respan(trait_.span.shrink_to_lo(), ast::VisibilityKind::Inherited), vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited),
defaultness: ast::Defaultness::Final, defaultness: ast::Defaultness::Final,
ident: method_ident, ident: method_ident,
kind: ast::ImplItemKind::Method(ast::MethodSig { kind: ast::ImplItemKind::Method(sig, body_block),
header: ast::FnHeader {
unsafety, abi,
..ast::FnHeader::default()
},
decl: fn_decl,
},
body_block),
tokens: None, tokens: None,
} }
} }

View file

@ -566,6 +566,7 @@ symbols! {
rust_2018_preview, rust_2018_preview,
rust_begin_unwind, rust_begin_unwind,
rustc, rustc,
Rust,
RustcDecodable, RustcDecodable,
RustcEncodable, RustcEncodable,
rustc_allocator, rustc_allocator,

View file

@ -269,7 +269,7 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
fn test_error_on_exceed() { fn test_error_on_exceed() {
let types = [TestType::UnitTest, TestType::IntegrationTest, TestType::DocTest]; let types = [TestType::UnitTest, TestType::IntegrationTest, TestType::DocTest];
for test_type in types.into_iter() { for test_type in types.iter() {
let result = time_test_failure_template(*test_type); let result = time_test_failure_template(*test_type);
assert_eq!(result, TestResult::TrTimedFail); assert_eq!(result, TestResult::TrTimedFail);
@ -320,7 +320,7 @@ fn test_time_options_threshold() {
(TestType::DocTest, doc.critical.as_millis(), true, true), (TestType::DocTest, doc.critical.as_millis(), true, true),
]; ];
for (test_type, time, expected_warn, expected_critical) in test_vector.into_iter() { for (test_type, time, expected_warn, expected_critical) in test_vector.iter() {
let test_desc = typed_test_desc(*test_type); let test_desc = typed_test_desc(*test_type);
let exec_time = test_exec_time(*time as u64); let exec_time = test_exec_time(*time as u64);

View file

@ -1,10 +1,8 @@
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gated-feature-in-macro-arg.rs:8:9 --> $DIR/feature-gated-feature-in-macro-arg.rs:8:16
| |
LL | / extern "rust-intrinsic" { LL | extern "rust-intrinsic" {
LL | | fn atomic_fence(); | ^^^^^^^^^^^^^^^^
LL | | }
| |_________^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable

View file

@ -1,8 +1,8 @@
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi-msp430-interrupt.rs:4:1 --> $DIR/feature-gate-abi-msp430-interrupt.rs:4:8
| |
LL | extern "msp430-interrupt" fn foo() {} LL | extern "msp430-interrupt" fn foo() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable

View file

@ -1,591 +1,591 @@
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-abi.rs:13:1 --> $DIR/feature-gate-abi.rs:13:8
| |
LL | extern "rust-intrinsic" fn f1() {} LL | extern "rust-intrinsic" fn f1() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy error[E0658]: platform intrinsics are experimental and possibly buggy
--> $DIR/feature-gate-abi.rs:15:1 --> $DIR/feature-gate-abi.rs:15:8
| |
LL | extern "platform-intrinsic" fn f2() {} LL | extern "platform-intrinsic" fn f2() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/27731 = note: for more information, see https://github.com/rust-lang/rust/issues/27731
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: vectorcall is experimental and subject to change error[E0658]: vectorcall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:17:1 --> $DIR/feature-gate-abi.rs:17:8
| |
LL | extern "vectorcall" fn f3() {} LL | extern "vectorcall" fn f3() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:18:1 --> $DIR/feature-gate-abi.rs:18:8
| |
LL | extern "rust-call" fn f4() {} LL | extern "rust-call" fn f4() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:19:1 --> $DIR/feature-gate-abi.rs:19:8
| |
LL | extern "msp430-interrupt" fn f5() {} LL | extern "msp430-interrupt" fn f5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
error[E0658]: PTX ABIs are experimental and subject to change error[E0658]: PTX ABIs are experimental and subject to change
--> $DIR/feature-gate-abi.rs:20:1 --> $DIR/feature-gate-abi.rs:20:8
| |
LL | extern "ptx-kernel" fn f6() {} LL | extern "ptx-kernel" fn f6() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38788 = note: for more information, see https://github.com/rust-lang/rust/issues/38788
= help: add `#![feature(abi_ptx)]` to the crate attributes to enable = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
error[E0658]: x86-interrupt ABI is experimental and subject to change error[E0658]: x86-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:21:1 --> $DIR/feature-gate-abi.rs:21:8
| |
LL | extern "x86-interrupt" fn f7() {} LL | extern "x86-interrupt" fn f7() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/40180 = note: for more information, see https://github.com/rust-lang/rust/issues/40180
= help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
error[E0658]: thiscall is experimental and subject to change error[E0658]: thiscall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:22:1 --> $DIR/feature-gate-abi.rs:22:8
| |
LL | extern "thiscall" fn f8() {} LL | extern "thiscall" fn f8() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: add `#![feature(abi_thiscall)]` to the crate attributes to enable = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
error[E0658]: amdgpu-kernel ABI is experimental and subject to change error[E0658]: amdgpu-kernel ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:23:1 --> $DIR/feature-gate-abi.rs:23:8
| |
LL | extern "amdgpu-kernel" fn f9() {} LL | extern "amdgpu-kernel" fn f9() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/51575 = note: for more information, see https://github.com/rust-lang/rust/issues/51575
= help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
error[E0658]: efiapi ABI is experimental and subject to change error[E0658]: efiapi ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:24:1 --> $DIR/feature-gate-abi.rs:24:8
| |
LL | extern "efiapi" fn f10() {} LL | extern "efiapi" fn f10() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/65815 = note: for more information, see https://github.com/rust-lang/rust/issues/65815
= help: add `#![feature(abi_efiapi)]` to the crate attributes to enable = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-abi.rs:28:5 --> $DIR/feature-gate-abi.rs:28:12
| |
LL | extern "rust-intrinsic" fn m1(); LL | extern "rust-intrinsic" fn m1();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy error[E0658]: platform intrinsics are experimental and possibly buggy
--> $DIR/feature-gate-abi.rs:30:5 --> $DIR/feature-gate-abi.rs:30:12
| |
LL | extern "platform-intrinsic" fn m2(); LL | extern "platform-intrinsic" fn m2();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/27731 = note: for more information, see https://github.com/rust-lang/rust/issues/27731
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: vectorcall is experimental and subject to change error[E0658]: vectorcall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:32:5 --> $DIR/feature-gate-abi.rs:32:12
| |
LL | extern "vectorcall" fn m3(); LL | extern "vectorcall" fn m3();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:33:5 --> $DIR/feature-gate-abi.rs:33:12
| |
LL | extern "rust-call" fn m4(); LL | extern "rust-call" fn m4();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:34:5 --> $DIR/feature-gate-abi.rs:34:12
| |
LL | extern "msp430-interrupt" fn m5(); LL | extern "msp430-interrupt" fn m5();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
error[E0658]: PTX ABIs are experimental and subject to change error[E0658]: PTX ABIs are experimental and subject to change
--> $DIR/feature-gate-abi.rs:35:5 --> $DIR/feature-gate-abi.rs:35:12
| |
LL | extern "ptx-kernel" fn m6(); LL | extern "ptx-kernel" fn m6();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38788 = note: for more information, see https://github.com/rust-lang/rust/issues/38788
= help: add `#![feature(abi_ptx)]` to the crate attributes to enable = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
error[E0658]: x86-interrupt ABI is experimental and subject to change error[E0658]: x86-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:36:5 --> $DIR/feature-gate-abi.rs:36:12
| |
LL | extern "x86-interrupt" fn m7(); LL | extern "x86-interrupt" fn m7();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/40180 = note: for more information, see https://github.com/rust-lang/rust/issues/40180
= help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
error[E0658]: thiscall is experimental and subject to change error[E0658]: thiscall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:37:5 --> $DIR/feature-gate-abi.rs:37:12
| |
LL | extern "thiscall" fn m8(); LL | extern "thiscall" fn m8();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: add `#![feature(abi_thiscall)]` to the crate attributes to enable = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
error[E0658]: amdgpu-kernel ABI is experimental and subject to change error[E0658]: amdgpu-kernel ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:38:5 --> $DIR/feature-gate-abi.rs:38:12
| |
LL | extern "amdgpu-kernel" fn m9(); LL | extern "amdgpu-kernel" fn m9();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/51575 = note: for more information, see https://github.com/rust-lang/rust/issues/51575
= help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
error[E0658]: efiapi ABI is experimental and subject to change error[E0658]: efiapi ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:39:5 --> $DIR/feature-gate-abi.rs:39:12
| |
LL | extern "efiapi" fn m10(); LL | extern "efiapi" fn m10();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/65815 = note: for more information, see https://github.com/rust-lang/rust/issues/65815
= help: add `#![feature(abi_efiapi)]` to the crate attributes to enable = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
error[E0658]: vectorcall is experimental and subject to change error[E0658]: vectorcall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:41:5 --> $DIR/feature-gate-abi.rs:41:12
| |
LL | extern "vectorcall" fn dm3() {} LL | extern "vectorcall" fn dm3() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:42:5 --> $DIR/feature-gate-abi.rs:42:12
| |
LL | extern "rust-call" fn dm4() {} LL | extern "rust-call" fn dm4() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:43:5 --> $DIR/feature-gate-abi.rs:43:12
| |
LL | extern "msp430-interrupt" fn dm5() {} LL | extern "msp430-interrupt" fn dm5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
error[E0658]: PTX ABIs are experimental and subject to change error[E0658]: PTX ABIs are experimental and subject to change
--> $DIR/feature-gate-abi.rs:44:5 --> $DIR/feature-gate-abi.rs:44:12
| |
LL | extern "ptx-kernel" fn dm6() {} LL | extern "ptx-kernel" fn dm6() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38788 = note: for more information, see https://github.com/rust-lang/rust/issues/38788
= help: add `#![feature(abi_ptx)]` to the crate attributes to enable = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
error[E0658]: x86-interrupt ABI is experimental and subject to change error[E0658]: x86-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:45:5 --> $DIR/feature-gate-abi.rs:45:12
| |
LL | extern "x86-interrupt" fn dm7() {} LL | extern "x86-interrupt" fn dm7() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/40180 = note: for more information, see https://github.com/rust-lang/rust/issues/40180
= help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
error[E0658]: thiscall is experimental and subject to change error[E0658]: thiscall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:46:5 --> $DIR/feature-gate-abi.rs:46:12
| |
LL | extern "thiscall" fn dm8() {} LL | extern "thiscall" fn dm8() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: add `#![feature(abi_thiscall)]` to the crate attributes to enable = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
error[E0658]: amdgpu-kernel ABI is experimental and subject to change error[E0658]: amdgpu-kernel ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:47:5 --> $DIR/feature-gate-abi.rs:47:12
| |
LL | extern "amdgpu-kernel" fn dm9() {} LL | extern "amdgpu-kernel" fn dm9() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/51575 = note: for more information, see https://github.com/rust-lang/rust/issues/51575
= help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
error[E0658]: efiapi ABI is experimental and subject to change error[E0658]: efiapi ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:48:5 --> $DIR/feature-gate-abi.rs:48:12
| |
LL | extern "efiapi" fn dm10() {} LL | extern "efiapi" fn dm10() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/65815 = note: for more information, see https://github.com/rust-lang/rust/issues/65815
= help: add `#![feature(abi_efiapi)]` to the crate attributes to enable = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-abi.rs:55:5 --> $DIR/feature-gate-abi.rs:55:12
| |
LL | extern "rust-intrinsic" fn m1() {} LL | extern "rust-intrinsic" fn m1() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy error[E0658]: platform intrinsics are experimental and possibly buggy
--> $DIR/feature-gate-abi.rs:57:5 --> $DIR/feature-gate-abi.rs:57:12
| |
LL | extern "platform-intrinsic" fn m2() {} LL | extern "platform-intrinsic" fn m2() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/27731 = note: for more information, see https://github.com/rust-lang/rust/issues/27731
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: vectorcall is experimental and subject to change error[E0658]: vectorcall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:59:5 --> $DIR/feature-gate-abi.rs:59:12
| |
LL | extern "vectorcall" fn m3() {} LL | extern "vectorcall" fn m3() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:60:5 --> $DIR/feature-gate-abi.rs:60:12
| |
LL | extern "rust-call" fn m4() {} LL | extern "rust-call" fn m4() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:61:5 --> $DIR/feature-gate-abi.rs:61:12
| |
LL | extern "msp430-interrupt" fn m5() {} LL | extern "msp430-interrupt" fn m5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
error[E0658]: PTX ABIs are experimental and subject to change error[E0658]: PTX ABIs are experimental and subject to change
--> $DIR/feature-gate-abi.rs:62:5 --> $DIR/feature-gate-abi.rs:62:12
| |
LL | extern "ptx-kernel" fn m6() {} LL | extern "ptx-kernel" fn m6() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38788 = note: for more information, see https://github.com/rust-lang/rust/issues/38788
= help: add `#![feature(abi_ptx)]` to the crate attributes to enable = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
error[E0658]: x86-interrupt ABI is experimental and subject to change error[E0658]: x86-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:63:5 --> $DIR/feature-gate-abi.rs:63:12
| |
LL | extern "x86-interrupt" fn m7() {} LL | extern "x86-interrupt" fn m7() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/40180 = note: for more information, see https://github.com/rust-lang/rust/issues/40180
= help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
error[E0658]: thiscall is experimental and subject to change error[E0658]: thiscall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:64:5 --> $DIR/feature-gate-abi.rs:64:12
| |
LL | extern "thiscall" fn m8() {} LL | extern "thiscall" fn m8() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: add `#![feature(abi_thiscall)]` to the crate attributes to enable = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
error[E0658]: amdgpu-kernel ABI is experimental and subject to change error[E0658]: amdgpu-kernel ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:65:5 --> $DIR/feature-gate-abi.rs:65:12
| |
LL | extern "amdgpu-kernel" fn m9() {} LL | extern "amdgpu-kernel" fn m9() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/51575 = note: for more information, see https://github.com/rust-lang/rust/issues/51575
= help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
error[E0658]: efiapi ABI is experimental and subject to change error[E0658]: efiapi ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:66:5 --> $DIR/feature-gate-abi.rs:66:12
| |
LL | extern "efiapi" fn m10() {} LL | extern "efiapi" fn m10() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/65815 = note: for more information, see https://github.com/rust-lang/rust/issues/65815
= help: add `#![feature(abi_efiapi)]` to the crate attributes to enable = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-abi.rs:71:5 --> $DIR/feature-gate-abi.rs:71:12
| |
LL | extern "rust-intrinsic" fn im1() {} LL | extern "rust-intrinsic" fn im1() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy error[E0658]: platform intrinsics are experimental and possibly buggy
--> $DIR/feature-gate-abi.rs:73:5 --> $DIR/feature-gate-abi.rs:73:12
| |
LL | extern "platform-intrinsic" fn im2() {} LL | extern "platform-intrinsic" fn im2() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/27731 = note: for more information, see https://github.com/rust-lang/rust/issues/27731
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: vectorcall is experimental and subject to change error[E0658]: vectorcall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:75:5 --> $DIR/feature-gate-abi.rs:75:12
| |
LL | extern "vectorcall" fn im3() {} LL | extern "vectorcall" fn im3() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:76:5 --> $DIR/feature-gate-abi.rs:76:12
| |
LL | extern "rust-call" fn im4() {} LL | extern "rust-call" fn im4() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:77:5 --> $DIR/feature-gate-abi.rs:77:12
| |
LL | extern "msp430-interrupt" fn im5() {} LL | extern "msp430-interrupt" fn im5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
error[E0658]: PTX ABIs are experimental and subject to change error[E0658]: PTX ABIs are experimental and subject to change
--> $DIR/feature-gate-abi.rs:78:5 --> $DIR/feature-gate-abi.rs:78:12
| |
LL | extern "ptx-kernel" fn im6() {} LL | extern "ptx-kernel" fn im6() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38788 = note: for more information, see https://github.com/rust-lang/rust/issues/38788
= help: add `#![feature(abi_ptx)]` to the crate attributes to enable = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
error[E0658]: x86-interrupt ABI is experimental and subject to change error[E0658]: x86-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:79:5 --> $DIR/feature-gate-abi.rs:79:12
| |
LL | extern "x86-interrupt" fn im7() {} LL | extern "x86-interrupt" fn im7() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/40180 = note: for more information, see https://github.com/rust-lang/rust/issues/40180
= help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
error[E0658]: thiscall is experimental and subject to change error[E0658]: thiscall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:80:5 --> $DIR/feature-gate-abi.rs:80:12
| |
LL | extern "thiscall" fn im8() {} LL | extern "thiscall" fn im8() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: add `#![feature(abi_thiscall)]` to the crate attributes to enable = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
error[E0658]: amdgpu-kernel ABI is experimental and subject to change error[E0658]: amdgpu-kernel ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:81:5 --> $DIR/feature-gate-abi.rs:81:12
| |
LL | extern "amdgpu-kernel" fn im9() {} LL | extern "amdgpu-kernel" fn im9() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/51575 = note: for more information, see https://github.com/rust-lang/rust/issues/51575
= help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
error[E0658]: efiapi ABI is experimental and subject to change error[E0658]: efiapi ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:82:5 --> $DIR/feature-gate-abi.rs:82:12
| |
LL | extern "efiapi" fn im10() {} LL | extern "efiapi" fn im10() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/65815 = note: for more information, see https://github.com/rust-lang/rust/issues/65815
= help: add `#![feature(abi_efiapi)]` to the crate attributes to enable = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-abi.rs:86:11 --> $DIR/feature-gate-abi.rs:86:18
| |
LL | type A1 = extern "rust-intrinsic" fn(); LL | type A1 = extern "rust-intrinsic" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy error[E0658]: platform intrinsics are experimental and possibly buggy
--> $DIR/feature-gate-abi.rs:87:11 --> $DIR/feature-gate-abi.rs:87:18
| |
LL | type A2 = extern "platform-intrinsic" fn(); LL | type A2 = extern "platform-intrinsic" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/27731 = note: for more information, see https://github.com/rust-lang/rust/issues/27731
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: vectorcall is experimental and subject to change error[E0658]: vectorcall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:88:11 --> $DIR/feature-gate-abi.rs:88:18
| |
LL | type A3 = extern "vectorcall" fn(); LL | type A3 = extern "vectorcall" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:89:11 --> $DIR/feature-gate-abi.rs:89:18
| |
LL | type A4 = extern "rust-call" fn(); LL | type A4 = extern "rust-call" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:90:11 --> $DIR/feature-gate-abi.rs:90:18
| |
LL | type A5 = extern "msp430-interrupt" fn(); LL | type A5 = extern "msp430-interrupt" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
error[E0658]: PTX ABIs are experimental and subject to change error[E0658]: PTX ABIs are experimental and subject to change
--> $DIR/feature-gate-abi.rs:91:11 --> $DIR/feature-gate-abi.rs:91:18
| |
LL | type A6 = extern "ptx-kernel" fn (); LL | type A6 = extern "ptx-kernel" fn ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38788 = note: for more information, see https://github.com/rust-lang/rust/issues/38788
= help: add `#![feature(abi_ptx)]` to the crate attributes to enable = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
error[E0658]: x86-interrupt ABI is experimental and subject to change error[E0658]: x86-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:92:11 --> $DIR/feature-gate-abi.rs:92:18
| |
LL | type A7 = extern "x86-interrupt" fn(); LL | type A7 = extern "x86-interrupt" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/40180 = note: for more information, see https://github.com/rust-lang/rust/issues/40180
= help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
error[E0658]: thiscall is experimental and subject to change error[E0658]: thiscall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:93:11 --> $DIR/feature-gate-abi.rs:93:18
| |
LL | type A8 = extern "thiscall" fn(); LL | type A8 = extern "thiscall" fn();
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: add `#![feature(abi_thiscall)]` to the crate attributes to enable = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
error[E0658]: amdgpu-kernel ABI is experimental and subject to change error[E0658]: amdgpu-kernel ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:94:11 --> $DIR/feature-gate-abi.rs:94:18
| |
LL | type A9 = extern "amdgpu-kernel" fn(); LL | type A9 = extern "amdgpu-kernel" fn();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/51575 = note: for more information, see https://github.com/rust-lang/rust/issues/51575
= help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
error[E0658]: efiapi ABI is experimental and subject to change error[E0658]: efiapi ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:95:12 --> $DIR/feature-gate-abi.rs:95:19
| |
LL | type A10 = extern "efiapi" fn(); LL | type A10 = extern "efiapi" fn();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/65815 = note: for more information, see https://github.com/rust-lang/rust/issues/65815
= help: add `#![feature(abi_efiapi)]` to the crate attributes to enable = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-abi.rs:98:1 --> $DIR/feature-gate-abi.rs:98:8
| |
LL | extern "rust-intrinsic" {} LL | extern "rust-intrinsic" {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: platform intrinsics are experimental and possibly buggy error[E0658]: platform intrinsics are experimental and possibly buggy
--> $DIR/feature-gate-abi.rs:99:1 --> $DIR/feature-gate-abi.rs:99:8
| |
LL | extern "platform-intrinsic" {} LL | extern "platform-intrinsic" {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/27731 = note: for more information, see https://github.com/rust-lang/rust/issues/27731
= help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
error[E0658]: vectorcall is experimental and subject to change error[E0658]: vectorcall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:100:1 --> $DIR/feature-gate-abi.rs:100:8
| |
LL | extern "vectorcall" {} LL | extern "vectorcall" {}
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:101:1 --> $DIR/feature-gate-abi.rs:101:8
| |
LL | extern "rust-call" {} LL | extern "rust-call" {}
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: msp430-interrupt ABI is experimental and subject to change error[E0658]: msp430-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:102:1 --> $DIR/feature-gate-abi.rs:102:8
| |
LL | extern "msp430-interrupt" {} LL | extern "msp430-interrupt" {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38487 = note: for more information, see https://github.com/rust-lang/rust/issues/38487
= help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
error[E0658]: PTX ABIs are experimental and subject to change error[E0658]: PTX ABIs are experimental and subject to change
--> $DIR/feature-gate-abi.rs:103:1 --> $DIR/feature-gate-abi.rs:103:8
| |
LL | extern "ptx-kernel" {} LL | extern "ptx-kernel" {}
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/38788 = note: for more information, see https://github.com/rust-lang/rust/issues/38788
= help: add `#![feature(abi_ptx)]` to the crate attributes to enable = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
error[E0658]: x86-interrupt ABI is experimental and subject to change error[E0658]: x86-interrupt ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:104:1 --> $DIR/feature-gate-abi.rs:104:8
| |
LL | extern "x86-interrupt" {} LL | extern "x86-interrupt" {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/40180 = note: for more information, see https://github.com/rust-lang/rust/issues/40180
= help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
error[E0658]: thiscall is experimental and subject to change error[E0658]: thiscall is experimental and subject to change
--> $DIR/feature-gate-abi.rs:105:1 --> $DIR/feature-gate-abi.rs:105:8
| |
LL | extern "thiscall" {} LL | extern "thiscall" {}
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
| |
= help: add `#![feature(abi_thiscall)]` to the crate attributes to enable = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
error[E0658]: amdgpu-kernel ABI is experimental and subject to change error[E0658]: amdgpu-kernel ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:106:1 --> $DIR/feature-gate-abi.rs:106:8
| |
LL | extern "amdgpu-kernel" {} LL | extern "amdgpu-kernel" {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/51575 = note: for more information, see https://github.com/rust-lang/rust/issues/51575
= help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
error[E0658]: efiapi ABI is experimental and subject to change error[E0658]: efiapi ABI is experimental and subject to change
--> $DIR/feature-gate-abi.rs:107:1 --> $DIR/feature-gate-abi.rs:107:8
| |
LL | extern "efiapi" {} LL | extern "efiapi" {}
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/65815 = note: for more information, see https://github.com/rust-lang/rust/issues/65815
= help: add `#![feature(abi_efiapi)]` to the crate attributes to enable = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable

View file

@ -1,10 +1,8 @@
error[E0658]: unadjusted ABI is an implementation detail and perma-unstable error[E0658]: unadjusted ABI is an implementation detail and perma-unstable
--> $DIR/feature-gate-abi_unadjusted.rs:1:1 --> $DIR/feature-gate-abi_unadjusted.rs:1:8
| |
LL | / extern "unadjusted" fn foo() { LL | extern "unadjusted" fn foo() {
LL | | | ^^^^^^^^^^^^
LL | | }
| |_^
| |
= help: add `#![feature(abi_unadjusted)]` to the crate attributes to enable = help: add `#![feature(abi_unadjusted)]` to the crate attributes to enable

View file

@ -1,18 +1,16 @@
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-intrinsics.rs:1:1 --> $DIR/feature-gate-intrinsics.rs:1:8
| |
LL | / extern "rust-intrinsic" { LL | extern "rust-intrinsic" {
LL | | fn bar(); | ^^^^^^^^^^^^^^^^
LL | | }
| |_^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable
error[E0658]: intrinsics are subject to change error[E0658]: intrinsics are subject to change
--> $DIR/feature-gate-intrinsics.rs:5:1 --> $DIR/feature-gate-intrinsics.rs:5:8
| |
LL | extern "rust-intrinsic" fn baz() {} LL | extern "rust-intrinsic" fn baz() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
| |
= help: add `#![feature(intrinsics)]` to the crate attributes to enable = help: add `#![feature(intrinsics)]` to the crate attributes to enable

View file

@ -1,35 +1,35 @@
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:12
| |
LL | extern "rust-call" fn call(self, args: ()) -> () {} LL | extern "rust-call" fn call(self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:12
| |
LL | extern "rust-call" fn call_once(self, args: ()) -> () {} LL | extern "rust-call" fn call_once(self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:12
| |
LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:5 --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:12
| |
LL | extern "rust-call" fn call_once(&self, args: ()) -> () {} LL | extern "rust-call" fn call_once(&self, args: ()) -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable

View file

@ -1,10 +1,8 @@
error[E0658]: rust-call ABI is subject to change error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-unboxed-closures.rs:9:5 --> $DIR/feature-gate-unboxed-closures.rs:9:12
| |
LL | / extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { LL | extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
LL | | a + b | ^^^^^^^^^^^
LL | | }
| |_____^
| |
= note: for more information, see https://github.com/rust-lang/rust/issues/29625 = note: for more information, see https://github.com/rust-lang/rust/issues/29625
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable

View file

@ -29,7 +29,7 @@ error[E0046]: not all trait items implemented, missing: `fmt`
LL | impl std::fmt::Display for MyType4 {} LL | impl std::fmt::Display for MyType4 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
| |
= note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` = help: implement the missing item: `fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { unimplemented!() }`
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp`
LL | impl PartialOrd for Thing { LL | impl PartialOrd for Thing {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
| |
= note: `partial_cmp` from trait: `fn(&Self, &Rhs) -> std::option::Option<std::cmp::Ordering>` = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> std::option::Option<std::cmp::Ordering> { unimplemented!() }`
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,33 @@
// run-pass
// run-rustfix
fn main() {
let small = [1, 2];
let big = [0u8; 33];
// Expressions that should trigger the lint
small.iter();
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
[1, 2].iter();
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
big.iter();
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
[0u8; 33].iter();
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
// Expressions that should not
(&[1, 2]).into_iter();
(&small).into_iter();
(&[0u8; 33]).into_iter();
(&big).into_iter();
for _ in &[1, 2] {}
(&small as &[_]).into_iter();
small[..].into_iter();
std::iter::IntoIterator::into_iter(&[1, 2]);
}

View file

@ -0,0 +1,33 @@
// run-pass
// run-rustfix
fn main() {
let small = [1, 2];
let big = [0u8; 33];
// Expressions that should trigger the lint
small.into_iter();
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
[1, 2].into_iter();
//~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
big.into_iter();
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
[0u8; 33].into_iter();
//~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
//~| WARNING this was previously accepted by the compiler but is being phased out
// Expressions that should not
(&[1, 2]).into_iter();
(&small).into_iter();
(&[0u8; 33]).into_iter();
(&big).into_iter();
for _ in &[1, 2] {}
(&small as &[_]).into_iter();
small[..].into_iter();
std::iter::IntoIterator::into_iter(&[1, 2]);
}

View file

@ -0,0 +1,37 @@
warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
--> $DIR/into-iter-on-arrays-lint.rs:9:11
|
LL | small.into_iter();
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= note: `#[warn(array_into_iter)]` 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
--> $DIR/into-iter-on-arrays-lint.rs:12:12
|
LL | [1, 2].into_iter();
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
--> $DIR/into-iter-on-arrays-lint.rs:15:9
|
LL | big.into_iter();
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= 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 #66145 <https://github.com/rust-lang/rust/issues/66145>
warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
--> $DIR/into-iter-on-arrays-lint.rs:18:15
|
LL | [0u8; 33].into_iter();
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= 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 #66145 <https://github.com/rust-lang/rust/issues/66145>

View file

@ -4,9 +4,9 @@ error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `met
LL | impl m1::X for X { LL | impl m1::X for X {
| ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method` in implementation | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method` in implementation
| |
= note: `CONSTANT` from trait: `const CONSTANT: u32;` = help: implement the missing item: `const CONSTANT: u32 = 42;`
= note: `Type` from trait: `type Type;` = help: implement the missing item: `type Type = Type;`
= note: `method` from trait: `fn(&Self, std::string::String) -> <Self as m1::X>::Type` = help: implement the missing item: `fn method(&self, _: std::string::String) -> <Self as m1::X>::Type { unimplemented!() }`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,9 +1,9 @@
extern extern
"C"suffix //~ ERROR suffixes on an ABI spec are invalid "C"suffix //~ ERROR suffixes on a string literal are invalid
fn foo() {} fn foo() {}
extern extern
"C"suffix //~ ERROR suffixes on an ABI spec are invalid "C"suffix //~ ERROR suffixes on a string literal are invalid
{} {}
fn main() { fn main() {

View file

@ -1,10 +1,10 @@
error: suffixes on an ABI spec are invalid error: suffixes on a string literal are invalid
--> $DIR/bad-lit-suffixes.rs:2:5 --> $DIR/bad-lit-suffixes.rs:2:5
| |
LL | "C"suffix LL | "C"suffix
| ^^^^^^^^^ invalid suffix `suffix` | ^^^^^^^^^ invalid suffix `suffix`
error: suffixes on an ABI spec are invalid error: suffixes on a string literal are invalid
--> $DIR/bad-lit-suffixes.rs:6:5 --> $DIR/bad-lit-suffixes.rs:6:5
| |
LL | "C"suffix LL | "C"suffix

View file

@ -0,0 +1,26 @@
// check-pass
// In this test we check that the parser accepts an ABI string when it
// comes from a macro `literal` fragment as opposed to a hardcoded string.
fn main() {}
macro_rules! abi_from_lit_frag {
($abi:literal) => {
extern $abi {
fn _import();
}
extern $abi fn _export() {}
type _PTR = extern $abi fn();
}
}
mod rust {
abi_from_lit_frag!("Rust");
}
mod c {
abi_from_lit_frag!("C");
}

View file

@ -0,0 +1,13 @@
// check-pass
// Check that the string literal in `extern lit` will accept raw strings.
fn main() {}
extern r#"C"# fn foo() {}
extern r#"C"# {
fn bar();
}
type T = extern r#"C"# fn();

View file

@ -0,0 +1,13 @@
// check-pass
// Check that the string literal in `extern lit` will escapes.
fn main() {}
extern "\x43" fn foo() {}
extern "\x43" {
fn bar();
}
type T = extern "\x43" fn();

View file

@ -0,0 +1,17 @@
// check-pass
// Check that from the grammar's point of view,
// the specific set of ABIs is not part of it.
fn main() {}
#[cfg(FALSE)]
extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn foo() {}
#[cfg(FALSE)]
extern "some_abi_that_we_are_sure_does_not_exist_semantically" {
fn foo();
}
#[cfg(FALSE)]
type T = extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn();

View file

@ -0,0 +1,14 @@
// run-pass
// Test that failing macro matchers will not cause pre-expansion errors
// even though they use a feature that is pre-expansion gated.
macro_rules! m {
($e:expr) => { 0 }; // This fails on the input below due to `, foo`.
($e:expr,) => { 1 }; // This also fails to match due to `foo`.
(box $e:expr, foo) => { 2 }; // Successful matcher, we should get `2`.
}
fn main() {
assert_eq!(2, m!(box 42, foo));
}

View file

@ -64,7 +64,7 @@ error[E0046]: not all trait items implemented, missing: `fmt`
LL | impl Debug for FooTypeForMethod { LL | impl Debug for FooTypeForMethod {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
| |
= note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>` = help: implement the missing item: `fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { unimplemented!() }`
error: aborting due to 8 previous errors error: aborting due to 8 previous errors

View file

@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item`
LL | impl Iterator for Recurrence { LL | impl Iterator for Recurrence {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
| |
= note: `Item` from trait: `type Item;` = help: implement the missing item: `type Item = Type;`
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
LL | impl<C: Component> FnOnce<(C,)> for Prototype { LL | impl<C: Component> FnOnce<(C,)> for Prototype {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
| |
= note: `Output` from trait: `type Output;` = help: implement the missing item: `type Output = Type;`
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target`
LL | impl Deref for Thing { LL | impl Deref for Thing {
| ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation | ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation
| |
= note: `Target` from trait: `type Target;` = help: implement the missing item: `type Target = Type;`
error: aborting due to previous error error: aborting due to previous error

View file

@ -0,0 +1,20 @@
// run-rustfix
trait T {
unsafe fn foo(a: &usize, b: &usize) -> usize;
fn bar(&self, a: &usize, b: &usize) -> usize;
}
mod foo {
use super::T;
impl T for () { fn bar(&self, _: &usize, _: &usize) -> usize { unimplemented!() }
unsafe fn foo(_: &usize, _: &usize) -> usize { unimplemented!() }
} //~ ERROR not all trait items
impl T for usize { //~ ERROR not all trait items
fn bar(&self, _: &usize, _: &usize) -> usize { unimplemented!() }
unsafe fn foo(_: &usize, _: &usize) -> usize { unimplemented!() }
}
}
fn main() {}

View file

@ -0,0 +1,16 @@
// run-rustfix
trait T {
unsafe fn foo(a: &usize, b: &usize) -> usize;
fn bar(&self, a: &usize, b: &usize) -> usize;
}
mod foo {
use super::T;
impl T for () {} //~ ERROR not all trait items
impl T for usize { //~ ERROR not all trait items
}
}
fn main() {}

View file

@ -0,0 +1,25 @@
error[E0046]: not all trait items implemented, missing: `foo`, `bar`
--> $DIR/missing-trait-item.rs:10:5
|
LL | unsafe fn foo(a: &usize, b: &usize) -> usize;
| --------------------------------------------- `foo` from trait
LL | fn bar(&self, a: &usize, b: &usize) -> usize;
| --------------------------------------------- `bar` from trait
...
LL | impl T for () {}
| ^^^^^^^^^^^^^ missing `foo`, `bar` in implementation
error[E0046]: not all trait items implemented, missing: `foo`, `bar`
--> $DIR/missing-trait-item.rs:12:5
|
LL | unsafe fn foo(a: &usize, b: &usize) -> usize;
| --------------------------------------------- `foo` from trait
LL | fn bar(&self, a: &usize, b: &usize) -> usize;
| --------------------------------------------- `bar` from trait
...
LL | impl T for usize {
| ^^^^^^^^^^^^^^^^ missing `foo`, `bar` in implementation
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0046`.