From 9f34b82de203a01b7bb1afd57714886a65dbea8f Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 11 Apr 2020 21:02:49 +0200 Subject: [PATCH 1/6] forbid `dyn Trait` in const generics --- .../hair/pattern/const_to_pat.rs | 3 +++ .../traits/structural_match.rs | 5 +++++ .../issues/issue-63322-forbid-dyn.rs | 15 +++++++++++++++ .../issues/issue-63322-forbid-dyn.stderr | 17 +++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs create mode 100644 src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr diff --git a/src/librustc_mir_build/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/hair/pattern/const_to_pat.rs index ad87afc3e0301..5a3eea3877570 100644 --- a/src/librustc_mir_build/hair/pattern/const_to_pat.rs +++ b/src/librustc_mir_build/hair/pattern/const_to_pat.rs @@ -116,6 +116,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { traits::NonStructuralMatchTy::Param => { bug!("use of constant whose type is a parameter inside a pattern") } + traits::NonStructuralMatchTy::Dynamic => { + bug!("use of a trait object inside a pattern") + } }; let path = self.tcx().def_path_str(adt_def.did); diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs index fbe1fcb08f2ef..8007290f35d85 100644 --- a/src/librustc_trait_selection/traits/structural_match.rs +++ b/src/librustc_trait_selection/traits/structural_match.rs @@ -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`. diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs new file mode 100644 index 0000000000000..2bacd6c9a9c5a --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs @@ -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() { + //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used + unimplemented!() +} + +fn main() { + test::<{ &B }>(); +} diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr new file mode 100644 index 0000000000000..73315af4483e2 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr @@ -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() { + | ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0741`. From 2f5c0f59a96612667ca6aeb40b6e40259f861e7e Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 12 Apr 2020 15:34:42 +0200 Subject: [PATCH 2/6] emit err when using trait objects in pat --- .../hair/pattern/const_to_pat.rs | 30 +++++++++---------- .../issues/issue-63322-forbid-dyn.stderr | 2 +- src/test/ui/match/issue-70972-dyn-trait.rs | 10 +++++++ .../ui/match/issue-70972-dyn-trait.stderr | 8 +++++ 4 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 src/test/ui/match/issue-70972-dyn-trait.rs create mode 100644 src/test/ui/match/issue-70972-dyn-trait.stderr diff --git a/src/librustc_mir_build/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/hair/pattern/const_to_pat.rs index 5a3eea3877570..4cc6a27a6da93 100644 --- a/src/librustc_mir_build/hair/pattern/const_to_pat.rs +++ b/src/librustc_mir_build/hair/pattern/const_to_pat.rs @@ -111,23 +111,21 @@ 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, - traits::NonStructuralMatchTy::Param => { - bug!("use of constant whose type is a parameter inside a pattern") + 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 => { - bug!("use of a trait object inside a pattern") + 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. @@ -158,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!( diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr index 73315af4483e2..c3db6c65a8f4c 100644 --- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr @@ -12,6 +12,6 @@ error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(Part LL | fn test() { | ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq` -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0741`. diff --git a/src/test/ui/match/issue-70972-dyn-trait.rs b/src/test/ui/match/issue-70972-dyn-trait.rs new file mode 100644 index 0000000000000..a9b2699cafdc4 --- /dev/null +++ b/src/test/ui/match/issue-70972-dyn-trait.rs @@ -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 + _ => {} + } +} diff --git a/src/test/ui/match/issue-70972-dyn-trait.stderr b/src/test/ui/match/issue-70972-dyn-trait.stderr new file mode 100644 index 0000000000000..a4e827357de6b --- /dev/null +++ b/src/test/ui/match/issue-70972-dyn-trait.stderr @@ -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 + From 5314f0126c82124a31e897c0b64497cf6f45cfa8 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 1 May 2020 22:32:33 +0200 Subject: [PATCH 3/6] doc: misc rustdoc things --- src/librustc_builtin_macros/test_harness.rs | 6 ++++-- src/librustc_lint/lib.rs | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index 160a5204eaf70..aca1c69dfd591 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -233,6 +233,7 @@ fn generate_test_harness( /// /// By default this expands to /// +/// ``` /// #[main] /// pub fn main() { /// extern crate test; @@ -242,6 +243,7 @@ fn generate_test_harness( /// &test_const3, /// ]); /// } +/// ``` /// /// Most of the Ident have the usual def-site hygiene for the AST pass. The /// exception is the `test_const`s. These have a syntax context that has two @@ -253,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 { let sp = cx.def_site; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 4033c2b28494c..521a0d67b59da 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -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 //! From d0dea9f5887c8371279b0b07ce0380f060ca1e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Fischer?= Date: Wed, 29 Apr 2020 18:59:13 -0400 Subject: [PATCH 4/6] Added MIR constant propagation of Scalars into function call arguments - Documented rationale of current solution - Polished documentation --- src/librustc_mir/transform/const_prop.rs | 56 +++++++++++++++++-- .../rustc.main.ConstProp.diff | 13 ++++- .../rustc.main.SimplifyLocals.diff | 22 +++++++- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 09d8f89676a66..a34b9dac42808 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -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); } diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/scalar_literal_propagation/rustc.main.ConstProp.diff index 0183ff7716cbb..596ddcb43533b 100644 --- a/src/test/mir-opt/const_prop/scalar_literal_propagation/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/scalar_literal_propagation/rustc.main.ConstProp.diff @@ -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()) // mir::Constant // + span: $DIR/scalar_literal_propagation.rs:4:5: 4:12 // + literal: Const { ty: fn(u32) {consume}, val: Value(Scalar()) } ++ // 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: { diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff index 0742f655730c5..0bd4ba97b3ca0 100644 --- a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff @@ -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()) } +- _5 = const ((), ()); // scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:14:13: 14:21 +- // ty::Const +- // + ty: ((), ()) +- // + val: Value(Scalar()) +- // mir::Constant +- // + span: $DIR/simplify-locals-removes-unused-consts.rs:14:13: 14:21 +- // + literal: Const { ty: ((), ()), val: Value(Scalar()) } - 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()) // 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()) } } 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 From 16a0349571248c70fce0f279b350f9fd617a52ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 2 May 2020 12:50:57 -0700 Subject: [PATCH 5/6] Do not try to find binop method on RHS `TyErr` Fix #71798. --- src/librustc_typeck/check/op.rs | 2 +- src/test/ui/issues-71798.rs | 7 +++++++ src/test/ui/issues-71798.stderr | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues-71798.rs create mode 100644 src/test/ui/issues-71798.stderr diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index cac9113fd5d30..23004cf364725 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -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 => { diff --git a/src/test/ui/issues-71798.rs b/src/test/ui/issues-71798.rs new file mode 100644 index 0000000000000..08b10463d3927 --- /dev/null +++ b/src/test/ui/issues-71798.rs @@ -0,0 +1,7 @@ +fn test_ref(x: &u32) -> impl std::future::Future + '_ { + *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 +} diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr new file mode 100644 index 0000000000000..85da87914e768 --- /dev/null +++ b/src/test/ui/issues-71798.stderr @@ -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 + '_ { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`. From a028292de58fefb507e20cdeb36f313526ee3bfb Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 4 May 2020 08:28:53 -0500 Subject: [PATCH 6/6] Use f64 in f64 examples I believe that this is a copy/paste error; this example was using f32, but it's the docs for f64. --- src/libcore/num/f64.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index b38fd804ee80f..73e760a2ee8b3 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -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::() }; /// assert_eq!(rounded, 4); /// - /// let value = -128.9_f32; + /// let value = -128.9_f64; /// let rounded = unsafe { value.to_int_unchecked::() }; /// assert_eq!(rounded, i8::MIN); /// ```