1
Fork 0

Auto merge of #59590 - Centril:rollup, r=Centril

Rollup of 7 pull requests

Successful merges:

 - #58805 (Lint for redundant imports)
 - #59506 (Use platform dependent mcount function)
 - #59519 (rustc_target: factor out common fields of non-Single Variants.)
 - #59580 (Allow closure to unsafe fn coercion)
 - #59581 (Stabilize refcell_replace_swap feature)
 - #59583 (match match match match match)
 - #59587 (Remove #[doc(hidden)] from Error::type_id)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-03-31 17:21:14 +00:00
commit 4fac5c98b2
110 changed files with 599 additions and 251 deletions

View file

@ -135,7 +135,7 @@ impl<T> ToOwned for T
/// Another example showing how to keep `Cow` in a struct:
///
/// ```
/// use std::borrow::{Cow, ToOwned};
/// use std::borrow::Cow;
///
/// struct Items<'a, X: 'a> where [X]: ToOwned<Owned = Vec<X>> {
/// values: Cow<'a, [X]>,

View file

@ -702,8 +702,6 @@ impl<T> RefCell<T> {
/// Replaces the wrapped value with a new one computed from `f`, returning
/// the old value, without deinitializing either one.
///
/// This function corresponds to [`std::mem::replace`](../mem/fn.replace.html).
///
/// # Panics
///
/// Panics if the value is currently borrowed.
@ -711,7 +709,6 @@ impl<T> RefCell<T> {
/// # Examples
///
/// ```
/// #![feature(refcell_replace_swap)]
/// use std::cell::RefCell;
/// let cell = RefCell::new(5);
/// let old_value = cell.replace_with(|&mut old| old + 1);
@ -719,7 +716,7 @@ impl<T> RefCell<T> {
/// assert_eq!(cell, RefCell::new(6));
/// ```
#[inline]
#[unstable(feature = "refcell_replace_swap", issue="43570")]
#[stable(feature = "refcell_replace_swap", since="1.35.0")]
pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
let mut_borrow = &mut *self.borrow_mut();
let replacement = f(mut_borrow);
@ -1421,7 +1418,6 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
///
/// ```
/// use std::cell::UnsafeCell;
/// use std::marker::Sync;
///
/// # #[allow(dead_code)]
/// struct NotThreadSafe<T> {

View file

@ -16,7 +16,6 @@
#![feature(pattern)]
#![feature(range_is_empty)]
#![feature(raw)]
#![feature(refcell_replace_swap)]
#![feature(slice_patterns)]
#![feature(sort_internals)]
#![feature(specialization)]

View file

@ -45,7 +45,6 @@
#![feature(proc_macro_internals)]
#![feature(optin_builtin_traits)]
#![feature(range_is_empty)]
#![feature(refcell_replace_swap)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_attrs)]
#![feature(slice_patterns)]

View file

@ -483,6 +483,7 @@ pub enum BuiltinLintDiagnostics {
UnknownCrateTypes(Span, String, String),
UnusedImports(String, Vec<(Span, String)>),
NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
RedundantImport(Vec<(Span, bool)>, ast::Ident),
}
impl BuiltinLintDiagnostics {
@ -579,6 +580,15 @@ impl BuiltinLintDiagnostics {
db.span_label(outer_impl_trait_span, "outer `impl Trait`");
db.span_label(inner_impl_trait_span, "nested `impl Trait` here");
}
BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
for (span, is_imported) in spans {
let introduced = if is_imported { "imported" } else { "defined" };
db.span_label(
span,
format!("the item `{}` is already {} here", ident, introduced)
);
}
}
}
}
}

View file

@ -707,7 +707,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
adjustment::Adjust::NeverToAny |
adjustment::Adjust::ReifyFnPointer |
adjustment::Adjust::UnsafeFnPointer |
adjustment::Adjust::ClosureFnPointer |
adjustment::Adjust::ClosureFnPointer(_) |
adjustment::Adjust::MutToConstPointer |
adjustment::Adjust::Unsize => {
// Creating a closure/fn-pointer or unsizing consumes

View file

@ -621,7 +621,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
adjustment::Adjust::NeverToAny |
adjustment::Adjust::ReifyFnPointer |
adjustment::Adjust::UnsafeFnPointer |
adjustment::Adjust::ClosureFnPointer |
adjustment::Adjust::ClosureFnPointer(_) |
adjustment::Adjust::MutToConstPointer |
adjustment::Adjust::Borrow(_) |
adjustment::Adjust::Unsize => {

View file

@ -2247,8 +2247,9 @@ pub enum CastKind {
/// Converts unique, zero-sized type for a fn to fn()
ReifyFnPointer,
/// Converts non capturing closure to fn()
ClosureFnPointer,
/// Converts non capturing closure to fn() or unsafe fn().
/// It cannot convert a closure that requires unsafe.
ClosureFnPointer(hir::Unsafety),
/// Converts safe fn() to unsafe fn()
UnsafeFnPointer,

View file

@ -62,8 +62,9 @@ pub enum Adjust<'tcx> {
/// Go from a safe fn pointer to an unsafe fn pointer.
UnsafeFnPointer,
/// Go from a non-capturing closure to an fn pointer.
ClosureFnPointer,
/// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
/// It cannot convert a closure that requires unsafe.
ClosureFnPointer(hir::Unsafety),
/// Go from a mut raw pointer to a const raw pointer.
MutToConstPointer,

View file

@ -2441,7 +2441,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// type with the same signature. Detuples and so forth -- so
/// e.g., if we have a sig with `Fn<(u32, i32)>` then you would get
/// a `fn(u32, i32)`.
pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
/// `unsafety` determines the unsafety of the `fn` type. If you pass
/// `hir::Unsafety::Unsafe` in the previous example, then you would get
/// an `unsafe fn (u32, i32)`.
/// It cannot convert a closure that requires unsafe.
pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>, unsafety: hir::Unsafety) -> Ty<'tcx> {
let converted_sig = sig.map_bound(|s| {
let params_iter = match s.inputs()[0].sty {
ty::Tuple(params) => {
@ -2453,7 +2457,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
params_iter,
s.output(),
s.c_variadic,
hir::Unsafety::Normal,
unsafety,
abi::Abi::Rust,
)
});

View file

@ -913,11 +913,13 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
}
return Ok(tcx.intern_layout(LayoutDetails {
variants: Variants::NicheFilling {
dataful_variant: i,
niche_variants,
niche: niche_scalar,
niche_start,
variants: Variants::Multiple {
discr: niche_scalar,
discr_kind: DiscriminantKind::Niche {
dataful_variant: i,
niche_variants,
niche_start,
},
variants: st,
},
fields: FieldPlacement::Arbitrary {
@ -1137,8 +1139,9 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
}
tcx.intern_layout(LayoutDetails {
variants: Variants::Tagged {
tag,
variants: Variants::Multiple {
discr: tag,
discr_kind: DiscriminantKind::Tag,
variants: layout_variants,
},
fields: FieldPlacement::Arbitrary {
@ -1293,8 +1296,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
}
}
Variants::NicheFilling { .. } |
Variants::Tagged { .. } => {
Variants::Multiple { ref discr, ref discr_kind, .. } => {
debug!("print-type-size `{:#?}` adt general variants def {}",
layout.ty, adt_def.variants.len());
let variant_infos: Vec<_> =
@ -1306,8 +1308,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
layout.for_variant(self, i))
})
.collect();
record(adt_kind.into(), adt_packed, match layout.variants {
Variants::Tagged { ref tag, .. } => Some(tag.value.size(self)),
record(adt_kind.into(), adt_packed, match discr_kind {
DiscriminantKind::Tag => Some(discr.value.size(self)),
_ => None
}, variant_infos);
}
@ -1627,8 +1629,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
})
}
Variants::NicheFilling { ref variants, .. } |
Variants::Tagged { ref variants, .. } => {
Variants::Multiple { ref variants, .. } => {
&variants[variant_index]
}
};
@ -1735,8 +1736,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
}
// Discriminant field for enums (where applicable).
Variants::Tagged { tag: ref discr, .. } |
Variants::NicheFilling { niche: ref discr, .. } => {
Variants::Multiple { ref discr, .. } => {
assert_eq!(i, 0);
let layout = LayoutDetails::scalar(cx, discr.clone());
return MaybeResult::from_ok(TyLayout {
@ -1881,26 +1881,37 @@ impl<'a> HashStable<StableHashingContext<'a>> for Variants {
Single { index } => {
index.hash_stable(hcx, hasher);
}
Tagged {
ref tag,
Multiple {
ref discr,
ref discr_kind,
ref variants,
} => {
tag.hash_stable(hcx, hasher);
discr.hash_stable(hcx, hasher);
discr_kind.hash_stable(hcx, hasher);
variants.hash_stable(hcx, hasher);
}
NicheFilling {
}
}
}
impl<'a> HashStable<StableHashingContext<'a>> for DiscriminantKind {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
use crate::ty::layout::DiscriminantKind::*;
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
Tag => {}
Niche {
dataful_variant,
ref niche_variants,
ref niche,
niche_start,
ref variants,
} => {
dataful_variant.hash_stable(hcx, hasher);
niche_variants.start().hash_stable(hcx, hasher);
niche_variants.end().hash_stable(hcx, hasher);
niche.hash_stable(hcx, hasher);
niche_start.hash_stable(hcx, hasher);
variants.hash_stable(hcx, hasher);
}
}
}

View file

@ -777,7 +777,6 @@ impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E>
value: &V)
-> Result<(), E::Error>
{
use crate::ty::codec::TyEncoder;
let start_pos = self.position();
tag.encode(self)?;

View file

@ -630,8 +630,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
Some(ty::adjustment::Adjust::ReifyFnPointer),
ty::adjustment::Adjust::UnsafeFnPointer =>
Some(ty::adjustment::Adjust::UnsafeFnPointer),
ty::adjustment::Adjust::ClosureFnPointer =>
Some(ty::adjustment::Adjust::ClosureFnPointer),
ty::adjustment::Adjust::ClosureFnPointer(unsafety) =>
Some(ty::adjustment::Adjust::ClosureFnPointer(unsafety)),
ty::adjustment::Adjust::MutToConstPointer =>
Some(ty::adjustment::Adjust::MutToConstPointer),
ty::adjustment::Adjust::Unsize =>
@ -1187,7 +1187,7 @@ EnumTypeFoldableImpl! {
(ty::adjustment::Adjust::NeverToAny),
(ty::adjustment::Adjust::ReifyFnPointer),
(ty::adjustment::Adjust::UnsafeFnPointer),
(ty::adjustment::Adjust::ClosureFnPointer),
(ty::adjustment::Adjust::ClosureFnPointer)(a),
(ty::adjustment::Adjust::MutToConstPointer),
(ty::adjustment::Adjust::Unsize),
(ty::adjustment::Adjust::Deref)(a),

View file

@ -77,9 +77,15 @@ pub fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
if cx.sess().instrument_mcount() {
// Similar to `clang -pg` behavior. Handled by the
// `post-inline-ee-instrument` LLVM pass.
// The function name varies on platforms.
// See test/CodeGen/mcount.c in clang.
let mcount_name = CString::new(
cx.sess().target.target.options.target_mcount.as_str().as_bytes()).unwrap();
llvm::AddFunctionAttrStringValue(
llfn, llvm::AttributePlace::Function,
const_cstr!("instrument-function-entry-inlined"), const_cstr!("mcount"));
const_cstr!("instrument-function-entry-inlined"), &mcount_name);
}
}

View file

@ -372,7 +372,6 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// Returns a Value of the "eh_unwind_resume" lang item if one is defined,
// otherwise declares it as an external function.
fn eh_unwind_resume(&self) -> &'ll Value {
use crate::attributes;
let unwresume = &self.eh_unwind_resume;
if let Some(llfn) = unwresume.get() {
return llfn;

View file

@ -1246,7 +1246,11 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
}
]
}
layout::Variants::Tagged { ref variants, .. } => {
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
ref variants,
..
} => {
let discriminant_info = if fallback {
RegularDiscriminant(self.discriminant_type_metadata
.expect(""))
@ -1288,12 +1292,14 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
}
}).collect()
}
layout::Variants::NicheFilling {
ref niche_variants,
niche_start,
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Niche {
ref niche_variants,
niche_start,
dataful_variant,
},
ref discr,
ref variants,
dataful_variant,
ref niche,
} => {
if fallback {
let variant = self.layout.for_variant(cx, dataful_variant);
@ -1380,7 +1386,11 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
let value = (i.as_u32() as u128)
.wrapping_sub(niche_variants.start().as_u32() as u128)
.wrapping_add(niche_start);
let value = truncate(value, niche.value.size(cx));
let value = truncate(value, discr.value.size(cx));
// NOTE(eddyb) do *NOT* remove this assert, until
// we pass the full 128-bit value to LLVM, otherwise
// truncation will be silent and remain undetected.
assert_eq!(value as u64 as u128, value);
Some(value as u64)
};
@ -1597,8 +1607,11 @@ fn prepare_enum_metadata(
let layout = cx.layout_of(enum_type);
match (&layout.abi, &layout.variants) {
(&layout::Abi::Scalar(_), &layout::Variants::Tagged {ref tag, .. }) =>
return FinalMetadata(discriminant_type_metadata(tag.value)),
(&layout::Abi::Scalar(_), &layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
ref discr,
..
}) => return FinalMetadata(discriminant_type_metadata(discr.value)),
_ => {}
}
@ -1610,9 +1623,16 @@ fn prepare_enum_metadata(
if use_enum_fallback(cx) {
let discriminant_type_metadata = match layout.variants {
layout::Variants::Single { .. } |
layout::Variants::NicheFilling { .. } => None,
layout::Variants::Tagged { ref tag, .. } => {
Some(discriminant_type_metadata(tag.value))
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Niche { .. },
..
} => None,
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
ref discr,
..
} => {
Some(discriminant_type_metadata(discr.value))
}
};
@ -1647,16 +1667,20 @@ fn prepare_enum_metadata(
);
}
let discriminator_metadata = match &layout.variants {
let discriminator_metadata = match layout.variants {
// A single-variant enum has no discriminant.
&layout::Variants::Single { .. } => None,
layout::Variants::Single { .. } => None,
&layout::Variants::NicheFilling { ref niche, .. } => {
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Niche { .. },
ref discr,
..
} => {
// Find the integer type of the correct size.
let size = niche.value.size(cx);
let align = niche.value.align(cx);
let size = discr.value.size(cx);
let align = discr.value.align(cx);
let discr_type = match niche.value {
let discr_type = match discr.value {
layout::Int(t, _) => t,
layout::Float(layout::FloatTy::F32) => Integer::I32,
layout::Float(layout::FloatTy::F64) => Integer::I64,
@ -1679,8 +1703,12 @@ fn prepare_enum_metadata(
}
},
&layout::Variants::Tagged { ref tag, .. } => {
let discr_type = tag.value.to_ty(cx.tcx);
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
ref discr,
..
} => {
let discr_type = discr.value.to_ty(cx.tcx);
let (size, align) = cx.size_and_align_of(discr_type);
let discr_metadata = basic_type_metadata(cx, discr_type);

View file

@ -452,7 +452,13 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
_ => {
let mut data_variant = match self.variants {
layout::Variants::NicheFilling { dataful_variant, .. } => {
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Niche {
dataful_variant,
..
},
..
} => {
// Only the niche itself is always initialized,
// so only check for a pointer at its offset.
//

View file

@ -216,37 +216,36 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
if self.layout.abi.is_uninhabited() {
return bx.cx().const_undef(cast_to);
}
match self.layout.variants {
let (discr_scalar, discr_kind) = match self.layout.variants {
layout::Variants::Single { index } => {
let discr_val = self.layout.ty.ty_adt_def().map_or(
index.as_u32() as u128,
|def| def.discriminant_for_variant(bx.cx().tcx(), index).val);
return bx.cx().const_uint_big(cast_to, discr_val);
}
layout::Variants::Tagged { .. } |
layout::Variants::NicheFilling { .. } => {},
}
layout::Variants::Multiple { ref discr, ref discr_kind, .. } => {
(discr, discr_kind)
}
};
let discr = self.project_field(bx, 0);
let lldiscr = bx.load_operand(discr).immediate();
match self.layout.variants {
layout::Variants::Single { .. } => bug!(),
layout::Variants::Tagged { ref tag, .. } => {
let signed = match tag.value {
match *discr_kind {
layout::DiscriminantKind::Tag => {
let signed = match discr_scalar.value {
// We use `i1` for bytes that are always `0` or `1`,
// e.g., `#[repr(i8)] enum E { A, B }`, but we can't
// let LLVM interpret the `i1` as signed, because
// then `i1 1` (i.e., E::B) is effectively `i8 -1`.
layout::Int(_, signed) => !tag.is_bool() && signed,
layout::Int(_, signed) => !discr_scalar.is_bool() && signed,
_ => false
};
bx.intcast(lldiscr, cast_to, signed)
}
layout::Variants::NicheFilling {
layout::DiscriminantKind::Niche {
dataful_variant,
ref niche_variants,
niche_start,
..
} => {
let niche_llty = bx.cx().immediate_backend_type(discr.layout);
if niche_variants.start() == niche_variants.end() {
@ -291,7 +290,10 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
layout::Variants::Single { index } => {
assert_eq!(index, variant_index);
}
layout::Variants::Tagged { .. } => {
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
..
} => {
let ptr = self.project_field(bx, 0);
let to = self.layout.ty.ty_adt_def().unwrap()
.discriminant_for_variant(bx.tcx(), variant_index)
@ -301,10 +303,12 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
ptr.llval,
ptr.align);
}
layout::Variants::NicheFilling {
dataful_variant,
ref niche_variants,
niche_start,
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Niche {
dataful_variant,
ref niche_variants,
niche_start,
},
..
} => {
if variant_index != dataful_variant {

View file

@ -193,7 +193,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::CastKind::ClosureFnPointer => {
mir::CastKind::ClosureFnPointer(_) => {
match operand.layout.ty.sty {
ty::Closure(def_id, substs) => {
let instance = monomorphize::resolve_closure(
@ -282,8 +282,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
});
}
}
layout::Variants::Tagged { .. } |
layout::Variants::NicheFilling { .. } => {},
layout::Variants::Multiple { .. } => {},
}
let llval = operand.immediate();
@ -732,7 +731,6 @@ fn cast_int_to_float<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
// All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity,
// and for everything else LLVM's uitofp works just fine.
use rustc_apfloat::ieee::Single;
use rustc_apfloat::Float;
const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
<< (Single::MAX_EXP - Single::PRECISION as i16);
let max = bx.cx().const_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);

View file

@ -77,7 +77,6 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
}
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
use syntax_pos::DUMMY_SP;
if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) {
return false;
}

View file

@ -155,7 +155,7 @@ impl CodeSuggestion {
/// Returns the assembled code suggestions and whether they should be shown with an underline.
pub fn splice_lines(&self, cm: &SourceMapperDyn)
-> Vec<(String, Vec<SubstitutionPart>)> {
use syntax_pos::{CharPos, Loc, Pos};
use syntax_pos::{CharPos, Pos};
fn push_trailing(buf: &mut String,
line_opt: Option<&Cow<'_, str>>,

View file

@ -62,7 +62,6 @@ fn total_duration(traces: &[trace::Rec]) -> Duration {
fn profile_queries_thread(r: Receiver<ProfileQueriesMsg>) {
use self::trace::*;
use std::fs::File;
use std::time::{Instant};
let mut profq_msgs: Vec<ProfileQueriesMsg> = vec![];
let mut frame: StackFrame = StackFrame { parse_st: ParseState::Clear, traces: vec![] };

View file

@ -842,51 +842,56 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
let item_def_id = cx.tcx.hir().local_def_id_from_hir_id(it.hir_id);
let t = cx.tcx.type_of(item_def_id);
let ty = cx.tcx.erase_regions(&t);
match cx.layout_of(ty) {
Ok(layout) => {
let variants = &layout.variants;
if let layout::Variants::Tagged { ref variants, ref tag, .. } = variants {
let discr_size = tag.value.size(&cx.tcx).bytes();
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
t, layout.size.bytes(), layout);
let (largest, slargest, largest_index) = enum_definition.variants
.iter()
.zip(variants)
.map(|(variant, variant_layout)| {
// Subtract the size of the enum discriminant.
let bytes = variant_layout.size.bytes().saturating_sub(discr_size);
debug!("- variant `{}` is {} bytes large",
variant.node.ident,
bytes);
bytes
})
.enumerate()
.fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l {
(size, l, idx)
} else if size > s {
(l, size, li)
} else {
(l, s, li)
});
// We only warn if the largest variant is at least thrice as large as
// the second-largest.
if largest > slargest * 3 && slargest > 0 {
cx.span_lint(VARIANT_SIZE_DIFFERENCES,
enum_definition.variants[largest_index].span,
&format!("enum variant is more than three times \
larger ({} bytes) than the next largest",
largest));
}
}
}
let layout = match cx.layout_of(ty) {
Ok(layout) => layout,
Err(ty::layout::LayoutError::Unknown(_)) => return,
Err(err @ ty::layout::LayoutError::SizeOverflow(_)) => {
bug!("failed to get layout for `{}`: {}", t, err);
}
};
let (variants, tag) = match layout.variants {
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
ref discr,
ref variants,
} => (variants, discr),
_ => return,
};
let discr_size = tag.value.size(&cx.tcx).bytes();
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
t, layout.size.bytes(), layout);
let (largest, slargest, largest_index) = enum_definition.variants
.iter()
.zip(variants)
.map(|(variant, variant_layout)| {
// Subtract the size of the enum discriminant.
let bytes = variant_layout.size.bytes().saturating_sub(discr_size);
debug!("- variant `{}` is {} bytes large",
variant.node.ident,
bytes);
bytes
})
.enumerate()
.fold((0, 0, 0), |(l, s, li), (idx, size)| if size > l {
(size, l, idx)
} else if size > s {
(l, size, li)
} else {
(l, s, li)
});
// We only warn if the largest variant is at least thrice as large as
// the second-largest.
if largest > slargest * 3 && slargest > 0 {
cx.span_lint(VARIANT_SIZE_DIFFERENCES,
enum_definition.variants[largest_index].span,
&format!("enum variant is more than three times \
larger ({} bytes) than the next largest",
largest));
}
}
}

View file

@ -1999,14 +1999,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}
CastKind::ClosureFnPointer => {
CastKind::ClosureFnPointer(unsafety) => {
let sig = match op.ty(mir, tcx).sty {
ty::Closure(def_id, substs) => {
substs.closure_sig_ty(def_id, tcx).fn_sig(tcx)
}
_ => bug!(),
};
let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig);
let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety);
if let Err(terr) = self.eq_types(
ty_fn_ptr_from,

View file

@ -162,9 +162,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source = unpack!(block = this.as_operand(block, scope, source));
block.and(Rvalue::Cast(CastKind::UnsafeFnPointer, source, expr.ty))
}
ExprKind::ClosureFnPointer { source } => {
ExprKind::ClosureFnPointer { source, unsafety } => {
let source = unpack!(block = this.as_operand(block, scope, source));
block.and(Rvalue::Cast(CastKind::ClosureFnPointer, source, expr.ty))
block.and(Rvalue::Cast(CastKind::ClosureFnPointer(unsafety), source, expr.ty))
}
ExprKind::MutToConstPointer { source } => {
let source = unpack!(block = this.as_operand(block, scope, source));

View file

@ -81,8 +81,8 @@ fn apply_adjustment<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
Adjust::UnsafeFnPointer => {
ExprKind::UnsafeFnPointer { source: expr.to_ref() }
}
Adjust::ClosureFnPointer => {
ExprKind::ClosureFnPointer { source: expr.to_ref() }
Adjust::ClosureFnPointer(unsafety) => {
ExprKind::ClosureFnPointer { source: expr.to_ref(), unsafety }
}
Adjust::NeverToAny => {
ExprKind::NeverToAny { source: expr.to_ref() }

View file

@ -185,6 +185,7 @@ pub enum ExprKind<'tcx> {
},
ClosureFnPointer {
source: ExprRef<'tcx>,
unsafety: hir::Unsafety,
},
UnsafeFnPointer {
source: ExprRef<'tcx>,

View file

@ -427,7 +427,6 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
let mut kind = match (lo, hi) {
(PatternKind::Constant { value: lo }, PatternKind::Constant { value: hi }) => {
use std::cmp::Ordering;
let cmp = compare_const_vals(
self.tcx,
lo,

View file

@ -64,8 +64,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
dest);
}
}
layout::Variants::Tagged { .. } |
layout::Variants::NicheFilling { .. } => {},
layout::Variants::Multiple { .. } => {},
}
let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?;
@ -105,7 +104,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
}
}
ClosureFnPointer => {
ClosureFnPointer(_) => {
// The src operand does not matter, just its type
match src.layout.ty.sty {
ty::Closure(def_id, substs) => {

View file

@ -610,25 +610,24 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
) -> EvalResult<'tcx, (u128, VariantIdx)> {
trace!("read_discriminant_value {:#?}", rval.layout);
match rval.layout.variants {
let discr_kind = match rval.layout.variants {
layout::Variants::Single { index } => {
let discr_val = rval.layout.ty.ty_adt_def().map_or(
index.as_u32() as u128,
|def| def.discriminant_for_variant(*self.tcx, index).val);
return Ok((discr_val, index));
}
layout::Variants::Tagged { .. } |
layout::Variants::NicheFilling { .. } => {},
}
layout::Variants::Multiple { ref discr_kind, .. } => discr_kind,
};
// read raw discriminant value
let discr_op = self.operand_field(rval, 0)?;
let discr_val = self.read_immediate(discr_op)?;
let raw_discr = discr_val.to_scalar_or_undef();
trace!("discr value: {:?}", raw_discr);
// post-process
Ok(match rval.layout.variants {
layout::Variants::Single { .. } => bug!(),
layout::Variants::Tagged { .. } => {
Ok(match *discr_kind {
layout::DiscriminantKind::Tag => {
let bits_discr = match raw_discr.to_bits(discr_val.layout.size) {
Ok(raw_discr) => raw_discr,
Err(_) => return err!(InvalidDiscriminant(raw_discr.erase_tag())),
@ -657,11 +656,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
.ok_or_else(|| EvalErrorKind::InvalidDiscriminant(raw_discr.erase_tag()))?;
(real_discr, index.0)
},
layout::Variants::NicheFilling {
layout::DiscriminantKind::Niche {
dataful_variant,
ref niche_variants,
niche_start,
..
} => {
let variants_start = niche_variants.start().as_u32() as u128;
let variants_end = niche_variants.end().as_u32() as u128;

View file

@ -331,8 +331,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
val: ImmTy<'tcx, M::PointerTag>,
) -> EvalResult<'tcx, Scalar<M::PointerTag>> {
use rustc::mir::UnOp::*;
use rustc_apfloat::ieee::{Single, Double};
use rustc_apfloat::Float;
let layout = val.layout;
let val = val.to_scalar()?;

View file

@ -958,7 +958,11 @@ where
layout::Variants::Single { index } => {
assert_eq!(index, variant_index);
}
layout::Variants::Tagged { ref tag, .. } => {
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Tag,
ref discr,
..
} => {
let adt_def = dest.layout.ty.ty_adt_def().unwrap();
assert!(variant_index.as_usize() < adt_def.variants.len());
let discr_val = adt_def
@ -968,16 +972,18 @@ where
// raw discriminants for enums are isize or bigger during
// their computation, but the in-memory tag is the smallest possible
// representation
let size = tag.value.size(self);
let size = discr.value.size(self);
let discr_val = truncate(discr_val, size);
let discr_dest = self.place_field(dest, 0)?;
self.write_scalar(Scalar::from_uint(discr_val, size), discr_dest)?;
}
layout::Variants::NicheFilling {
dataful_variant,
ref niche_variants,
niche_start,
layout::Variants::Multiple {
discr_kind: layout::DiscriminantKind::Niche {
dataful_variant,
ref niche_variants,
niche_start,
},
..
} => {
assert!(

View file

@ -241,8 +241,7 @@ macro_rules! make_value_visitor {
// If this is a multi-variant layout, we have find the right one and proceed with
// that.
match v.layout().variants {
layout::Variants::NicheFilling { .. } |
layout::Variants::Tagged { .. } => {
layout::Variants::Multiple { .. } => {
let op = v.to_op(self.ecx())?;
let idx = self.ecx().read_discriminant(op)?.1;
let inner = v.project_downcast(self.ecx(), idx)?;

View file

@ -563,7 +563,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
);
visit_fn_use(self.tcx, fn_ty, false, &mut self.output);
}
mir::Rvalue::Cast(mir::CastKind::ClosureFnPointer, ref operand, _) => {
mir::Rvalue::Cast(mir::CastKind::ClosureFnPointer(_), ref operand, _) => {
let source_ty = operand.ty(self.mir, self.tcx);
let source_ty = self.tcx.subst_and_normalize_erasing_regions(
self.param_substs,

View file

@ -1105,7 +1105,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
Rvalue::CheckedBinaryOp(..) |
Rvalue::Cast(CastKind::ReifyFnPointer, ..) |
Rvalue::Cast(CastKind::UnsafeFnPointer, ..) |
Rvalue::Cast(CastKind::ClosureFnPointer, ..) |
Rvalue::Cast(CastKind::ClosureFnPointer(_), ..) |
Rvalue::Cast(CastKind::Unsize, ..) |
Rvalue::Cast(CastKind::MutToConstPointer, ..) |
Rvalue::Discriminant(..) |

View file

@ -156,7 +156,7 @@ fn check_rvalue(
check_operand(tcx, mir, operand, span)
}
Rvalue::Cast(CastKind::UnsafeFnPointer, _, _) |
Rvalue::Cast(CastKind::ClosureFnPointer, _, _) |
Rvalue::Cast(CastKind::ClosureFnPointer(_), _, _) |
Rvalue::Cast(CastKind::ReifyFnPointer, _, _) => Err((
span,
"function pointer casts are not allowed in const fn".into(),

View file

@ -586,7 +586,7 @@ fn check_adjustments<'a, 'tcx>(
Adjust::NeverToAny |
Adjust::ReifyFnPointer |
Adjust::UnsafeFnPointer |
Adjust::ClosureFnPointer |
Adjust::ClosureFnPointer(_) |
Adjust::MutToConstPointer |
Adjust::Borrow(_) |
Adjust::Unsize => {}

View file

@ -1738,7 +1738,6 @@ impl<'a> Resolver<'a> {
/// just that an error occurred.
pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool)
-> Result<hir::Path, ()> {
use std::iter;
let mut errored = false;
let path = if path_str.starts_with("::") {

View file

@ -7,6 +7,7 @@ use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyErro
use crate::{Resolver, Segment};
use crate::{names_to_string, module_to_string};
use crate::{resolve_error, ResolutionError, Suggestion};
use crate::ModuleKind;
use crate::macros::ParentScope;
use errors::Applicability;
@ -14,7 +15,11 @@ use errors::Applicability;
use rustc_data_structures::ptr_key::PtrKey;
use rustc::ty;
use rustc::lint::builtin::BuiltinLintDiagnostics;
use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE};
use rustc::lint::builtin::{
DUPLICATE_MACRO_EXPORTS,
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
UNUSED_IMPORTS,
};
use rustc::hir::def_id::{CrateNum, DefId};
use rustc::hir::def::*;
use rustc::session::DiagnosticMessageId;
@ -1227,10 +1232,97 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
import[ns] = Some(PathResolution::new(def));
});
self.check_for_redundant_imports(
ident,
directive,
source_bindings,
target_bindings,
target,
);
debug!("(resolving single import) successfully resolved import");
None
}
fn check_for_redundant_imports(
&mut self,
ident: Ident,
directive: &'b ImportDirective<'b>,
source_bindings: &PerNS<Cell<Result<&'b NameBinding<'b>, Determinacy>>>,
target_bindings: &PerNS<Cell<Option<&'b NameBinding<'b>>>>,
target: Ident,
) {
// Skip if the import was produced by a macro.
if directive.parent_scope.expansion != Mark::root() {
return;
}
// Skip if we are inside a named module (in contrast to an anonymous
// module defined by a block).
if let ModuleKind::Def(_, _) = directive.parent_scope.module.kind {
return;
}
let mut is_redundant = PerNS {
value_ns: None,
type_ns: None,
macro_ns: None,
};
let mut redundant_span = PerNS {
value_ns: None,
type_ns: None,
macro_ns: None,
};
self.per_ns(|this, ns| if let Some(binding) = source_bindings[ns].get().ok() {
if binding.def() == Def::Err {
return;
}
let orig_blacklisted_binding = mem::replace(
&mut this.blacklisted_binding,
target_bindings[ns].get()
);
match this.early_resolve_ident_in_lexical_scope(
target,
ScopeSet::Import(ns),
&directive.parent_scope,
false,
false,
directive.span,
) {
Ok(other_binding) => {
is_redundant[ns] = Some(
binding.def() == other_binding.def()
&& !other_binding.is_ambiguity()
);
redundant_span[ns] =
Some((other_binding.span, other_binding.is_import()));
}
Err(_) => is_redundant[ns] = Some(false)
}
this.blacklisted_binding = orig_blacklisted_binding;
});
if !is_redundant.is_empty() &&
is_redundant.present_items().all(|is_redundant| is_redundant)
{
self.session.buffer_lint_with_diagnostic(
UNUSED_IMPORTS,
directive.id,
directive.span,
&format!("the item `{}` is imported redundantly", ident),
BuiltinLintDiagnostics::RedundantImport(
redundant_span.present_items().collect(),
ident,
),
);
}
}
fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
let module = match directive.imported_module.get().unwrap() {
ModuleOrUniformRoot::Module(module) => module,

View file

@ -61,8 +61,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &ArgType<'a, Ty>)
}
return Ok(());
}
abi::Variants::Tagged { .. } |
abi::Variants::NicheFilling { .. } => return Err(Memory),
abi::Variants::Multiple { .. } => return Err(Memory),
}
}

View file

@ -828,15 +828,22 @@ pub enum Variants {
index: VariantIdx,
},
/// General-case enums: for each case there is a struct, and they all have
/// all space reserved for the tag, and their first field starts
/// at a non-0 offset, after where the tag would go.
Tagged {
tag: Scalar,
/// Enums with more than one inhabited variant: for each case there is
/// a struct, and they all have space reserved for the discriminant,
/// which is the sole field of the enum layout.
Multiple {
discr: Scalar,
discr_kind: DiscriminantKind,
variants: IndexVec<VariantIdx, LayoutDetails>,
},
}
/// Multiple cases distinguished by a niche (values invalid for a type):
#[derive(PartialEq, Eq, Hash, Debug)]
pub enum DiscriminantKind {
/// Integer tag holding the discriminant value itself.
Tag,
/// Niche (values invalid for a type) encoding the discriminant:
/// the variant `dataful_variant` contains a niche at an arbitrary
/// offset (field 0 of the enum), which for a variant with discriminant
/// `d` is set to `(d - niche_variants.start).wrapping_add(niche_start)`.
@ -844,13 +851,11 @@ pub enum Variants {
/// For example, `Option<(usize, &T)>` is represented such that
/// `None` has a null pointer for the second tuple field, and
/// `Some` is the identity function (with a non-null reference).
NicheFilling {
Niche {
dataful_variant: VariantIdx,
niche_variants: RangeInclusive<VariantIdx>,
niche: Scalar,
niche_start: u128,
variants: IndexVec<VariantIdx, LayoutDetails>,
}
},
}
#[derive(PartialEq, Eq, Hash, Debug)]

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
linker_flavor: LinkerFlavor::Gcc,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}_mcount".to_string(),
.. base
},
})

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
linker_flavor: LinkerFlavor::Gcc,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}_mcount".to_string(),
.. base
},
})

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
@ -16,6 +16,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "__mcount".to_string(),
.. base
},
})
}

View file

@ -18,6 +18,7 @@ pub fn target() -> TargetResult {
options: TargetOptions {
features: "+strict-align,+v6".to_string(),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
.. base
},
})

View file

@ -18,6 +18,7 @@ pub fn target() -> TargetResult {
options: TargetOptions {
features: "+strict-align,+v6,+vfp2".to_string(),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
.. base
}
})

View file

@ -23,6 +23,7 @@ pub fn target() -> TargetResult {
linker_flavor: LinkerFlavor::Gcc,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}mcount".to_string(),
.. base
},
})

View file

@ -23,6 +23,7 @@ pub fn target() -> TargetResult {
linker_flavor: LinkerFlavor::Gcc,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}mcount".to_string(),
.. base
},
})

View file

@ -19,6 +19,7 @@ pub fn target() -> TargetResult {
// Atomic operations provided by compiler-builtins
max_atomic_width: Some(32),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
.. base
}
})

View file

@ -19,6 +19,7 @@ pub fn target() -> TargetResult {
// Atomic operations provided by compiler-builtins
max_atomic_width: Some(32),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
.. base
}
})

View file

@ -22,6 +22,7 @@ pub fn target() -> TargetResult {
// Atomic operations provided by compiler-builtins
max_atomic_width: Some(32),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}mcount".to_string(),
.. base
}
})

View file

@ -18,6 +18,7 @@ pub fn target() -> TargetResult {
features: "+v6,+vfp2".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
.. base
}
})

View file

@ -18,6 +18,7 @@ pub fn target() -> TargetResult {
options: TargetOptions {
features: "+v6,+vfp2".to_string(),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "__mcount".to_string(),
.. base
}
})

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
@ -19,6 +19,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "\u{1}mcount".to_string(),
.. base
},
})
}

View file

@ -18,6 +18,7 @@ pub fn target() -> TargetResult {
features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
.. base
}
})

View file

@ -23,6 +23,7 @@ pub fn target() -> TargetResult {
cpu: "generic".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
.. base
}
})

View file

@ -26,6 +26,7 @@ pub fn target() -> TargetResult {
cpu: "generic".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "\u{1}mcount".to_string(),
.. base
}
})

View file

@ -19,6 +19,7 @@ pub fn target() -> TargetResult {
cpu: "generic".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
target_mcount: "__mcount".to_string(),
.. base
}
})

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::apple_base::opts();
@ -19,6 +19,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "apple".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "\u{1}mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
@ -18,6 +18,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "__mcount".to_string(),
.. base
},
})
}

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
cpu: "mips64r2".to_string(),
features: "+mips64r2".to_string(),
max_atomic_width: Some(64),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
cpu: "mips64r2".to_string(),
features: "+mips64r2".to_string(),
max_atomic_width: Some(64),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -16,6 +16,7 @@ pub fn target() -> TargetResult {
cpu: "mips32r2".to_string(),
features: "+mips32r2,+fpxx,+nooddspreg".to_string(),
max_atomic_width: Some(32),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -16,6 +16,7 @@ pub fn target() -> TargetResult {
cpu: "mips32r2".to_string(),
features: "+mips32r2,+soft-float".to_string(),
max_atomic_width: Some(32),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
cpu: "mips32r2".to_string(),
features: "+mips32r2,+fpxx,+nooddspreg".to_string(),
max_atomic_width: Some(32),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
cpu: "mips32r2".to_string(),
features: "+mips32r2,+soft-float".to_string(),
max_atomic_width: Some(32),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -16,6 +16,7 @@ pub fn target() -> TargetResult {
cpu: "mips32r6".to_string(),
features: "+mips32r6".to_string(),
max_atomic_width: Some(32),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
cpu: "mips32r6".to_string(),
features: "+mips32r6".to_string(),
max_atomic_width: Some(32),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
cpu: "mips64r6".to_string(),
features: "+mips64r6".to_string(),
max_atomic_width: Some(64),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -17,6 +17,7 @@ pub fn target() -> TargetResult {
cpu: "mips64r6".to_string(),
features: "+mips64r6".to_string(),
max_atomic_width: Some(64),
target_mcount: "_mcount".to_string(),
..super::linux_base::opts()
},

View file

@ -761,7 +761,10 @@ pub struct TargetOptions {
/// to opt out. The default is "aliases".
///
/// Workaround for: https://github.com/rust-lang/rust/issues/57356
pub merge_functions: MergeFunctions
pub merge_functions: MergeFunctions,
/// Use platform dependent mcount function
pub target_mcount: String
}
impl Default for TargetOptions {
@ -845,6 +848,7 @@ impl Default for TargetOptions {
simd_types_indirect: true,
override_export_symbols: None,
merge_functions: MergeFunctions::Aliases,
target_mcount: "mcount".to_string(),
}
}
}
@ -1150,6 +1154,7 @@ impl Target {
key!(simd_types_indirect, bool);
key!(override_export_symbols, opt_list);
key!(merge_functions, MergeFunctions)?;
key!(target_mcount);
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
for name in array.iter().filter_map(|abi| abi.as_string()) {
@ -1364,6 +1369,7 @@ impl ToJson for Target {
target_option_val!(simd_types_indirect);
target_option_val!(override_export_symbols);
target_option_val!(merge_functions);
target_option_val!(target_mcount);
if default.abi_blacklist != self.options.abi_blacklist {
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::freebsd_base::opts();
@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult, RelroLevel};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult, RelroLevel};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
@ -21,6 +21,9 @@ pub fn target() -> TargetResult {
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
@ -16,6 +16,9 @@ pub fn target() -> TargetResult {
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
@ -16,6 +16,9 @@ pub fn target() -> TargetResult {
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
@ -16,6 +16,9 @@ pub fn target() -> TargetResult {
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "_mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
@ -16,6 +16,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "__mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
@ -17,6 +17,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "__mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::apple_base::opts();
@ -19,6 +19,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "apple".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "\u{1}mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
@ -24,6 +24,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "rumprun".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "__mcount".to_string(),
.. base
},
})
}

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkerFlavor, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
@ -18,6 +18,9 @@ pub fn target() -> TargetResult {
target_env: String::new(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: base,
options: TargetOptions {
target_mcount: "__mcount".to_string(),
.. base
},
})
}

View file

@ -225,7 +225,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
}
ty::Closure(def_id_a, substs_a) => {
// Non-capturing closures are coercible to
// function pointers
// function pointers or unsafe function pointers.
// It cannot convert closures that require unsafe.
self.coerce_closure_to_fn(a, def_id_a, substs_a, b)
}
_ => {
@ -714,16 +715,19 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
let hir_id_a = self.tcx.hir().as_local_hir_id(def_id_a).unwrap();
match b.sty {
ty::FnPtr(_) if self.tcx.with_freevars(hir_id_a, |v| v.is_empty()) => {
ty::FnPtr(fn_ty) if self.tcx.with_freevars(hir_id_a, |v| v.is_empty()) => {
// We coerce the closure, which has fn type
// `extern "rust-call" fn((arg0,arg1,...)) -> _`
// to
// `fn(arg0,arg1,...) -> _`
// or
// `unsafe fn(arg0,arg1,...) -> _`
let sig = self.closure_sig(def_id_a, substs_a);
let pointer_ty = self.tcx.coerce_closure_fn_ty(sig);
let unsafety = fn_ty.unsafety();
let pointer_ty = self.tcx.coerce_closure_fn_ty(sig, unsafety);
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})",
a, b, pointer_ty);
self.unify_and(pointer_ty, b, simple(Adjust::ClosureFnPointer))
self.unify_and(pointer_ty, b, simple(Adjust::ClosureFnPointer(unsafety)))
}
_ => self.unify_and(a, b, identity),
}

View file

@ -420,9 +420,6 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
def_id: DefId,
return_ty: Option<Ty<'tcx>>,
) {
use ty::subst::Subst;
use rustc::ty::TypeFoldable;
let predicates = fcx.tcx.predicates_of(def_id);
let generics = tcx.generics_of(def_id);
@ -1010,8 +1007,6 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>(
span: Span,
id: hir::HirId)
{
use rustc::ty::TypeFoldable;
let empty_env = ty::ParamEnv::empty();
let def_id = fcx.tcx.hir().local_def_id_from_hir_id(id);

View file

@ -64,7 +64,6 @@ This API is completely unstable and subject to change.
#![feature(crate_visibility_modifier)]
#![feature(exhaustive_patterns)]
#![feature(nll)]
#![feature(refcell_replace_swap)]
#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
#![feature(never_type)]

View file

@ -1069,8 +1069,6 @@ themePicker.onblur = handleThemeButtonsBlur;
}
if cx.shared.include_sources {
use std::path::Component;
let mut hierarchy = Hierarchy::new(OsString::new());
for source in cx.shared.local_sources.iter()
.filter_map(|p| p.0.strip_prefix(&cx.shared.src_root)

View file

@ -371,8 +371,7 @@ pub fn make_test(s: &str,
// Uses libsyntax to parse the doctest and find if there's a main fn and the extern
// crate already is included.
let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| {
use crate::syntax::{ast, parse::{self, ParseSess}, source_map::FilePathMapping};
use crate::syntax_pos::FileName;
use crate::syntax::{parse::{self, ParseSess}, source_map::FilePathMapping};
use errors::emitter::EmitterWriter;
use errors::Handler;

View file

@ -197,7 +197,6 @@ pub trait Error: Debug + Display {
fn source(&self) -> Option<&(dyn Error + 'static)> { None }
/// Gets the `TypeId` of `self`
#[doc(hidden)]
#[stable(feature = "error_type_id", since = "1.34.0")]
fn type_id(&self) -> TypeId where Self: 'static {
TypeId::of::<Self>()

View file

@ -0,0 +1,7 @@
// ignore-tidy-linelength
// compile-flags: -Z instrument-mcount
#![crate_type = "lib"]
// CHECK: attributes #{{.*}} "instrument-function-entry-inlined"="{{.*}}mcount{{.*}}" "no-frame-pointer-elim"="true"
pub fn foo() {}

View file

@ -0,0 +1,5 @@
fn main() {
let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
//~^ ERROR E0133
let _: unsafe fn() = || unsafe { ::std::pin::Pin::new_unchecked(&0_u8); }; // OK
}

View file

@ -45,8 +45,6 @@ pub mod glfw {
}
fn issue_6533() {
use glfw;
fn action_to_str(state: glfw::InputState) -> &'static str {
use glfw::{RELEASE, PRESS, REPEAT};
match state {

View file

@ -238,7 +238,6 @@ pub fn main() {
// Basic test to make sure that we can invoke the `write!` macro with an
// fmt::Write instance.
fn test_write() {
use std::fmt::Write;
let mut buf = String::new();
write!(&mut buf, "{}", 3);
{
@ -267,7 +266,6 @@ fn test_print() {
// Just make sure that the macros are defined, there's not really a lot that we
// can do with them just yet (to test the output)
fn test_format_args() {
use std::fmt::Write;
let mut buf = String::new();
{
let w = &mut buf;

View file

@ -25,7 +25,6 @@ fn foo() {
#[cfg(unix)]
fn check_status(status: std::process::ExitStatus)
{
use libc;
use std::os::unix::process::ExitStatusExt;
assert!(status.signal() == Some(libc::SIGILL)

View file

@ -9,6 +9,5 @@ macro_rules! reexport {
reexport!();
fn main() {
use Bar;
fn f(_: Bar) {}
}

View file

@ -15,7 +15,6 @@ fn arena() -> &'static ArenaSet<Vec<u8>> {
fn require_sync<T: Sync>(_: &T) { }
unsafe fn __stability() -> &'static ArenaSet<Vec<u8>> {
use std::mem::transmute;
use std::boxed::Box;
static mut DATA: *const ArenaSet<Vec<u8>> = 0 as *const ArenaSet<Vec<u8>>;
static mut ONCE: Once = ONCE_INIT;

View file

@ -36,7 +36,6 @@ fn loud_recurse() {
#[cfg(unix)]
fn check_status(status: std::process::ExitStatus)
{
use libc;
use std::os::unix::process::ExitStatusExt;
assert!(!status.success());

Some files were not shown because too many files have changed in this diff Show more