Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 4 pull requests #67866

Merged
merged 11 commits into from
Jan 4, 2020
7 changes: 5 additions & 2 deletions src/librustc_error_codes/error_codes/E0136.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
A binary can only have one entry point, and by default that entry point is the
function `main()`. If there are multiple such functions, please rename one.
More than one `main` function was found.

Erroneous code example:

Expand All @@ -14,3 +13,7 @@ fn main() { // error!
// ...
}
```

A binary can only have one entry point, and by default that entry point is the
`main()` function. If there are multiple instances of this function, please
rename one of them.
3 changes: 1 addition & 2 deletions src/librustc_error_codes/error_codes/E0161.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
A value was moved. However, its size was not known at compile time, and only
values of a known size can be moved.
A value was moved whose size was not known at compile time.

Erroneous code example:

Expand Down
38 changes: 29 additions & 9 deletions src/librustc_error_codes/error_codes/E0164.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
This error means that an attempt was made to match a struct type enum
variant as a non-struct type:
Something which is neither a tuple struct nor a tuple variant was used as a
pattern.

Erroneous code example:

```compile_fail,E0164
enum Foo { B { i: u32 } }
enum A {
B,
C,
}

impl A {
fn new() {}
}

fn bar(foo: Foo) -> u32 {
fn bar(foo: A) {
match foo {
Foo::B(i) => i, // error E0164
A::new() => (), // error!
_ => {}
}
}
```

Try using `{}` instead:
This error means that an attempt was made to match something which is neither a
tuple struct nor a tuple variant. Only these two elements are allowed as a
pattern:

```
enum Foo { B { i: u32 } }
enum A {
B,
C,
}

impl A {
fn new() {}
}

fn bar(foo: Foo) -> u32 {
fn bar(foo: A) {
match foo {
Foo::B{i} => i,
A::B => (), // ok!
_ => {}
}
}
```
70 changes: 7 additions & 63 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ use rustc::mir::visit::{
MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor,
};
use rustc::mir::{
read_only, AggregateKind, BasicBlock, BinOp, Body, BodyAndCache, CastKind, ClearCrossCrate,
Constant, Local, LocalDecl, LocalKind, Location, Operand, Place, PlaceBase,
ReadOnlyBodyAndCache, Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement,
StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE,
read_only, AggregateKind, BasicBlock, BinOp, Body, BodyAndCache, ClearCrossCrate, Constant,
Local, LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, ReadOnlyBodyAndCache, Rvalue,
SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind,
UnOp, RETURN_PLACE,
};
use rustc::ty::layout::{
HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout,
Expand All @@ -29,9 +29,9 @@ use syntax::ast::Mutability;

use crate::const_eval::error_to_const_error;
use crate::interpret::{
self, intern_const_alloc_recursive, truncate, AllocId, Allocation, Frame, ImmTy, Immediate,
InterpCx, LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy,
Pointer, ScalarMaybeUndef, StackPopCleanup,
self, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy, Immediate, InterpCx,
LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer,
ScalarMaybeUndef, StackPopCleanup,
};
use crate::rustc::ty::subst::Subst;
use crate::transform::{MirPass, MirSource};
Expand Down Expand Up @@ -539,57 +539,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
Some(())
}

fn check_cast(
&mut self,
op: &Operand<'tcx>,
ty: Ty<'tcx>,
source_info: SourceInfo,
place_layout: TyLayout<'tcx>,
) -> Option<()> {
if !ty.is_integral() || !op.ty(&self.local_decls, self.tcx).is_integral() {
return Some(());
}

let value = self.use_ecx(source_info, |this| {
this.ecx.read_immediate(this.ecx.eval_operand(op, None)?)
})?;

// Do not try to read bits for ZSTs. This can occur when casting an enum with one variant
// to an integer. Such enums are represented as ZSTs but still have a discriminant value
// which can be casted.
if value.layout.is_zst() {
return Some(());
}

let value_size = value.layout.size;
let value_bits = value.to_scalar().and_then(|r| r.to_bits(value_size));
if let Ok(value_bits) = value_bits {
let truncated = truncate(value_bits, place_layout.size);
if truncated != value_bits {
let scope = source_info.scope;
let lint_root = match &self.source_scopes[scope].local_data {
ClearCrossCrate::Set(data) => data.lint_root,
ClearCrossCrate::Clear => return None,
};
self.tcx.lint_hir(
::rustc::lint::builtin::CONST_ERR,
lint_root,
source_info.span,
&format!(
"truncating cast: the value {} requires {} bits but the target type is \
only {} bits",
value_bits,
value_size.bits(),
place_layout.size.bits()
),
);
return None;
}
}

Some(())
}

fn const_prop(
&mut self,
rvalue: &Rvalue<'tcx>,
Expand Down Expand Up @@ -651,11 +600,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}
}

Rvalue::Cast(CastKind::Misc, op, ty) => {
trace!("checking Cast(Misc, {:?}, {:?})", op, ty);
self.check_cast(op, ty, source_info, place_layout)?;
}

_ => {}
}

Expand Down
34 changes: 18 additions & 16 deletions src/librustc_typeck/check/dropck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro

ensure_drop_predicates_are_implied_by_item_defn(
tcx,
drop_impl_did,
dtor_predicates,
adt_def.did,
self_to_impl_substs,
Expand Down Expand Up @@ -95,16 +94,23 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
}
Err(_) => {
let item_span = tcx.def_span(self_type_did);
let self_descr = tcx
.def_kind(self_type_did)
.map(|kind| kind.descr(self_type_did))
.unwrap_or("type");
struct_span_err!(
tcx.sess,
drop_impl_span,
E0366,
"Implementations of Drop cannot be specialized"
"`Drop` impls cannot be specialized"
)
.span_note(
item_span,
"Use same sequence of generic type and region \
parameters that is on the struct/enum definition",
&format!(
"use the same sequence of generic type, lifetime and const parameters \
as the {} definition",
self_descr,
),
)
.emit();
return Err(ErrorReported);
Expand Down Expand Up @@ -143,7 +149,6 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
/// implied by assuming the predicates attached to self_type_did.
fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
tcx: TyCtxt<'tcx>,
drop_impl_did: DefId,
dtor_predicates: ty::GenericPredicates<'tcx>,
self_type_did: DefId,
self_to_impl_substs: SubstsRef<'tcx>,
Expand Down Expand Up @@ -187,8 +192,6 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(

let self_type_hir_id = tcx.hir().as_local_hir_id(self_type_did).unwrap();

let drop_impl_span = tcx.def_span(drop_impl_did);

// We can assume the predicates attached to struct/enum definition
// hold.
let generic_assumptions = tcx.predicates_of(self_type_did);
Expand All @@ -205,7 +208,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
// just to look for all the predicates directly.

assert_eq!(dtor_predicates.parent, None);
for (predicate, _) in dtor_predicates.predicates {
for (predicate, predicate_sp) in dtor_predicates.predicates {
// (We do not need to worry about deep analysis of type
// expressions etc because the Drop impls are already forced
// to take on a structure that is roughly an alpha-renaming of
Expand Down Expand Up @@ -241,18 +244,17 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(

if !assumptions_in_impl_context.iter().any(predicate_matches_closure) {
let item_span = tcx.hir().span(self_type_hir_id);
let self_descr =
tcx.def_kind(self_type_did).map(|kind| kind.descr(self_type_did)).unwrap_or("type");
struct_span_err!(
tcx.sess,
drop_impl_span,
*predicate_sp,
E0367,
"The requirement `{}` is added only by the Drop impl.",
predicate
)
.span_note(
item_span,
"The same requirement must be part of \
the struct/enum definition",
"`Drop` impl requires `{}` but the {} it is implemented for does not",
predicate,
self_descr,
)
.span_note(item_span, "the implementor must specify the same requirement")
.emit();
result = Err(ErrorReported);
}
Expand Down
47 changes: 18 additions & 29 deletions src/librustc_typeck/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use rustc::ty::util::CopyImplementationError;
use rustc::ty::TypeFoldable;
use rustc::ty::{self, Ty, TyCtxt};

use hir::Node;
use rustc::hir::def_id::DefId;
use rustc::hir::{self, ItemKind};

Expand Down Expand Up @@ -51,35 +50,25 @@ impl<'tcx> Checker<'tcx> {
}

fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) {
if let ty::Adt(..) = tcx.type_of(impl_did).kind {
/* do nothing */
} else {
// Destructors only work on nominal types.
if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_did) {
if let Some(Node::Item(item)) = tcx.hir().find(impl_hir_id) {
let span = match item.kind {
ItemKind::Impl(.., ref ty, _) => ty.span,
_ => item.span,
};
struct_span_err!(
tcx.sess,
span,
E0120,
"the Drop trait may only be implemented on \
structures"
)
.span_label(span, "implementing Drop requires a struct")
.emit();
} else {
bug!("didn't find impl in ast map");
}
} else {
bug!(
"found external impl of Drop trait on \
something other than a struct"
);
}
// Destructors only work on nominal types.
if let ty::Adt(..) | ty::Error = tcx.type_of(impl_did).kind {
return;
}

let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT");
let sp = match tcx.hir().expect_item(impl_hir_id).kind {
ItemKind::Impl(.., ty, _) => ty.span,
_ => bug!("expected Drop impl item"),
};

struct_span_err!(
tcx.sess,
sp,
E0120,
"the `Drop` trait may only be implemented for structs, enums, and unions",
)
.span_label(sp, "must be a struct, enum, or union")
.emit();
}

fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) {
Expand Down
1 change: 0 additions & 1 deletion src/libstd/sys/unix/cmath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use libc::{c_double, c_float};

#[link_name = "m"]
extern "C" {
pub fn acos(n: c_double) -> c_double;
pub fn acosf(n: c_float) -> c_float;
Expand Down
1 change: 0 additions & 1 deletion src/libstd/sys/vxworks/cmath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use libc::{c_double, c_float};

#[link_name = "m"]
extern "C" {
pub fn acos(n: c_double) -> c_double;
pub fn acosf(n: c_float) -> c_float;
Expand Down
1 change: 0 additions & 1 deletion src/libstd/sys/windows/cmath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use libc::{c_double, c_float};

#[link_name = "m"]
extern "C" {
pub fn acos(n: c_double) -> c_double;
pub fn asin(n: c_double) -> c_double;
Expand Down
16 changes: 11 additions & 5 deletions src/test/ui/consts/const-prop-overflowing-casts.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// build-fail
// ignore-tidy-linelength
// check-pass

enum Foo {
Bar = -42,
Baz = 42,
}

fn main() {
let _ = 0u8 as u32;
let _ = (1u32 << 31) as u16; //~ ERROR truncating cast: the value 2147483648 requires 32 bits but the target type is only 16 bits
let _ = (1u16 << 15) as u8; //~ ERROR truncating cast: the value 32768 requires 16 bits but the target type is only 8 bits
let _ = (!0u16) as u8; //~ ERROR truncating cast: the value 65535 requires 16 bits but the target type is only 8 bits
let _ = (1u32 << 31) as u16;
let _ = (1u16 << 15) as u8;
let _ = (!0u16) as u8;
let _ = (-1i16) as i8;
let _ = (Foo::Bar) as i8;
}
22 changes: 0 additions & 22 deletions src/test/ui/consts/const-prop-overflowing-casts.stderr

This file was deleted.

Loading