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 5 pull requests #71879

Merged
merged 11 commits into from
May 4, 2020
4 changes: 2 additions & 2 deletions src/libcore/num/f64.rs
Original file line number Diff line number Diff line change
@@ -474,11 +474,11 @@ impl f64 {
/// assuming that the value is finite and fits in that type.
///
/// ```
/// let value = 4.6_f32;
/// let value = 4.6_f64;
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
/// assert_eq!(rounded, 4);
///
/// let value = -128.9_f32;
/// let value = -128.9_f64;
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
/// assert_eq!(rounded, i8::MIN);
/// ```
4 changes: 2 additions & 2 deletions src/librustc_builtin_macros/test_harness.rs
Original file line number Diff line number Diff line change
@@ -255,8 +255,8 @@ fn generate_test_harness(
///
/// The expansion here can be controlled by two attributes:
///
/// `reexport_test_harness_main` provides a different name for the `main`
/// function and `test_runner` provides a path that replaces
/// [`TestCtxt::reexport_test_harness_main`] provides a different name for the `main`
/// function and [`TestCtxt::test_runner`] provides a path that replaces
/// `test::test_main_static`.
fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
let sp = cx.def_site;
6 changes: 3 additions & 3 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
@@ -6,9 +6,9 @@
//! other phases of the compiler, which are generally required to hold in order
//! to compile the program at all.
//!
//! Most lints can be written as `LintPass` instances. These run after
//! Most lints can be written as [LintPass] instances. These run after
//! all other analyses. The `LintPass`es built into rustc are defined
//! within `rustc_session::lint::builtin`,
//! within [rustc_session::lint::builtin],
//! which has further comments on how to add such a lint.
//! rustc can also load user-defined lint plugins via the plugin mechanism.
//!
@@ -19,7 +19,7 @@
//! example) requires more effort. See `emit_lint` and `GatherNodeLevels`
//! in `context.rs`.
//!
//! Some code also exists in `rustc_session::lint`, `rustc_middle::lint`.
//! Some code also exists in [rustc_session::lint], [rustc_middle::lint].
//!
//! ## Note
//!
56 changes: 51 additions & 5 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
@@ -787,6 +787,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
| NonMutatingUse(NonMutatingUseContext::Inspect)
| NonMutatingUse(NonMutatingUseContext::Projection)
| NonUse(_) => {}
// FIXME(felix91gr): explain the reasoning behind this
MutatingUse(MutatingUseContext::Projection) => {
if self.local_kinds[local] != LocalKind::Temp {
self.can_const_prop[local] = ConstPropMode::NoPropagation;
@@ -969,13 +970,58 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
| TerminatorKind::GeneratorDrop
| TerminatorKind::FalseEdges { .. }
| TerminatorKind::FalseUnwind { .. } => {}
//FIXME(wesleywiser) Call does have Operands that could be const-propagated
TerminatorKind::Call { .. } => {}
// Every argument in our function calls can be const propagated.
TerminatorKind::Call { ref mut args, .. } => {
let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level;
// Constant Propagation into function call arguments is gated
// under mir-opt-level 2, because LLVM codegen gives performance
// regressions with it.
if mir_opt_level >= 2 {
for opr in args {
/*
The following code would appear to be incomplete, because
the function `Operand::place()` returns `None` if the
`Operand` is of the variant `Operand::Constant`. In this
context however, that variant will never appear. This is why:

When constructing the MIR, all function call arguments are
copied into `Locals` of `LocalKind::Temp`. At least, all arguments
that are not unsized (Less than 0.1% are unsized. See #71170
to learn more about those).

This means that, conversely, all `Operands` found as function call
arguments are of the variant `Operand::Copy`. This allows us to
simplify our handling of `Operands` in this case.
*/
if let Some(l) = opr.place().and_then(|p| p.as_local()) {
if let Some(value) = self.get_const(l) {
if self.should_const_prop(value) {
// FIXME(felix91gr): this code only handles `Scalar` cases.
// For now, we're not handling `ScalarPair` cases because
// doing so here would require a lot of code duplication.
// We should hopefully generalize `Operand` handling into a fn,
// and use it to do const-prop here and everywhere else
// where it makes sense.
if let interpret::Operand::Immediate(
interpret::Immediate::Scalar(
interpret::ScalarMaybeUndef::Scalar(scalar),
),
) = *value
{
*opr = self.operand_from_scalar(
scalar,
value.layout.ty,
source_info.span,
);
}
}
}
}
}
}
}
}
// We remove all Locals which are restricted in propagation to their containing blocks.
// We wouldn't need to clone, but the borrow checker can't see that we're not aliasing
// the locals_of_current_block field, so we need to clone it first.
// let ecx = &mut self.ecx;
for local in self.locals_of_current_block.iter() {
Self::remove_const(&mut self.ecx, local);
}
27 changes: 14 additions & 13 deletions src/librustc_mir_build/hair/pattern/const_to_pat.rs
Original file line number Diff line number Diff line change
@@ -111,21 +111,22 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
}

if let Some(non_sm_ty) = structural {
let adt_def = match non_sm_ty {
traits::NonStructuralMatchTy::Adt(adt_def) => adt_def,
let msg = match non_sm_ty {
traits::NonStructuralMatchTy::Adt(adt_def) => {
let path = self.tcx().def_path_str(adt_def.did);
format!(
"to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
path, path,
)
}
traits::NonStructuralMatchTy::Dynamic => {
format!("trait objects cannot be used in patterns")
}
traits::NonStructuralMatchTy::Param => {
bug!("use of constant whose type is a parameter inside a pattern")
}
};
let path = self.tcx().def_path_str(adt_def.did);

let make_msg = || -> String {
format!(
"to use a constant of type `{}` in a pattern, \
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
path, path,
)
};

// double-check there even *is* a semantic `PartialEq` to dispatch to.
//
@@ -155,13 +156,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {

if !ty_is_partial_eq {
// span_fatal avoids ICE from resolution of non-existent method (rare case).
self.tcx().sess.span_fatal(self.span, &make_msg());
self.tcx().sess.span_fatal(self.span, &msg);
} else if mir_structural_match_violation {
self.tcx().struct_span_lint_hir(
lint::builtin::INDIRECT_STRUCTURAL_MATCH,
self.id,
self.span,
|lint| lint.build(&make_msg()).emit(),
|lint| lint.build(&msg).emit(),
);
} else {
debug!(
5 changes: 5 additions & 0 deletions src/librustc_trait_selection/traits/structural_match.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ use rustc_span::Span;
pub enum NonStructuralMatchTy<'tcx> {
Adt(&'tcx AdtDef),
Param,
Dynamic,
}

/// This method traverses the structure of `ty`, trying to find an
@@ -137,6 +138,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
self.found = Some(NonStructuralMatchTy::Param);
return true; // Stop visiting.
}
ty::Dynamic(..) => {
self.found = Some(NonStructuralMatchTy::Dynamic);
return true; // Stop visiting.
}
ty::RawPtr(..) => {
// structural-match ignores substructure of
// `*const _`/`*mut _`, so skip `super_visit_with`.
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/op.rs
Original file line number Diff line number Diff line change
@@ -251,7 +251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
Err(()) => {
// error types are considered "builtin"
if !lhs_ty.references_error() {
if !lhs_ty.references_error() && !rhs_ty.references_error() {
let source_map = self.tcx.sess.source_map();
match is_assign {
IsAssign::Yes => {
Original file line number Diff line number Diff line change
@@ -22,20 +22,27 @@
StorageLive(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:4:5: 4:15
StorageLive(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:4:13: 4:14
- _3 = _1; // scope 1 at $DIR/scalar_literal_propagation.rs:4:13: 4:14
- _2 = const consume(move _3) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:4:5: 4:15
+ _3 = const 1u32; // scope 1 at $DIR/scalar_literal_propagation.rs:4:13: 4:14
+ // ty::Const
// ty::Const
+ // + ty: u32
+ // + val: Value(Scalar(0x00000001))
+ // mir::Constant
+ // + span: $DIR/scalar_literal_propagation.rs:4:13: 4:14
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
_2 = const consume(move _3) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:4:5: 4:15
// ty::Const
+ _2 = const consume(const 1u32) -> bb1; // scope 1 at $DIR/scalar_literal_propagation.rs:4:5: 4:15
+ // ty::Const
// + ty: fn(u32) {consume}
// + val: Value(Scalar(<ZST>))
// mir::Constant
// + span: $DIR/scalar_literal_propagation.rs:4:5: 4:12
// + literal: Const { ty: fn(u32) {consume}, val: Value(Scalar(<ZST>)) }
+ // ty::Const
+ // + ty: u32
+ // + val: Value(Scalar(0x00000001))
+ // mir::Constant
+ // + span: $DIR/scalar_literal_propagation.rs:4:5: 4:15
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000001)) }
}

bb1: {
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@
- StorageDead(_2); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:13:27: 13:28
- StorageDead(_1); // scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:13:28: 13:29
- StorageLive(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
- StorageLive(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:13: 14:21
- StorageLive(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:14: 14:16
- _6 = const (); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:14: 14:16
- // ty::Const
@@ -66,6 +67,13 @@
- // mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:18: 14:20
- // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
- _5 = const ((), ()); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:13: 14:21
- // ty::Const
- // + ty: ((), ())
- // + val: Value(Scalar(<ZST>))
- // mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:13: 14:21
- // + literal: Const { ty: ((), ()), val: Value(Scalar(<ZST>)) }
- StorageDead(_7); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:20: 14:21
- StorageDead(_6); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:20: 14:21
- _4 = const use_zst(const ((), ())) -> bb1; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
@@ -79,13 +87,15 @@
// + ty: ((), ())
// + val: Value(Scalar(<ZST>))
// mir::Constant
// + span: $DIR/simplify-locals-removes-unused-consts.rs:14:13: 14:21
// + span: $DIR/simplify-locals-removes-unused-consts.rs:14:5: 14:22
// + literal: Const { ty: ((), ()), val: Value(Scalar(<ZST>)) }
}

bb1: {
- StorageDead(_5); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:21: 14:22
- StorageDead(_4); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:22: 14:23
- StorageLive(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
- StorageLive(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:34
- StorageLive(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:30
- StorageLive(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:28
- _11 = const Temp { x: 40u8 }; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:28
@@ -105,6 +115,13 @@
- // mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:30
- // + literal: Const { ty: u8, val: Value(Scalar(0x28)) }
- _9 = const 42u8; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:34
- // ty::Const
- // + ty: u8
- // + val: Value(Scalar(0x2a))
- // mir::Constant
- // + span: $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:34
- // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
- StorageDead(_10); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:33: 16:34
- _8 = const use_u8(const 42u8) -> bb2; // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
- // ty::Const
@@ -117,11 +134,12 @@
// + ty: u8
// + val: Value(Scalar(0x2a))
// mir::Constant
// + span: $DIR/simplify-locals-removes-unused-consts.rs:16:12: 16:34
// + span: $DIR/simplify-locals-removes-unused-consts.rs:16:5: 16:35
// + literal: Const { ty: u8, val: Value(Scalar(0x2a)) }
}

bb2: {
- StorageDead(_9); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:34: 16:35
- StorageDead(_11); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36
- StorageDead(_8); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36
+ StorageDead(_2); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36
15 changes: 15 additions & 0 deletions src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

trait A {}
struct B;
impl A for B {}

fn test<const T: &'static dyn A>() {
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used
unimplemented!()
}

fn main() {
test::<{ &B }>();
}
17 changes: 17 additions & 0 deletions src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/issue-63322-forbid-dyn.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
--> $DIR/issue-63322-forbid-dyn.rs:8:18
|
LL | fn test<const T: &'static dyn A>() {
| ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0741`.
7 changes: 7 additions & 0 deletions src/test/ui/issues-71798.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
*x //~^ ERROR the trait bound `u32: std::future::Future` is not satisfied
}

fn main() {
let _ = test_ref & u; //~ ERROR cannot find value `u` in this scope
}
20 changes: 20 additions & 0 deletions src/test/ui/issues-71798.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0425]: cannot find value `u` in this scope
--> $DIR/issues-71798.rs:6:24
|
LL | let _ = test_ref & u;
| ^ not found in this scope

error[E0277]: the trait bound `u32: std::future::Future` is not satisfied
--> $DIR/issues-71798.rs:1:25
|
LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `u32`
LL | *x
| -- this returned value is of type `u32`
|
= note: the return type of a function must have a statically known size

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0425.
For more information about an error, try `rustc --explain E0277`.
10 changes: 10 additions & 0 deletions src/test/ui/match/issue-70972-dyn-trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const F: &'static dyn Send = &7u32;

fn main() {
let a: &dyn Send = &7u32;
match a {
F => panic!(),
//~^ ERROR trait objects cannot be used in patterns
_ => {}
}
}
8 changes: 8 additions & 0 deletions src/test/ui/match/issue-70972-dyn-trait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: trait objects cannot be used in patterns
--> $DIR/issue-70972-dyn-trait.rs:6:9
|
LL | F => panic!(),
| ^

error: aborting due to previous error