From 4e76c3820fea97e06f08555d4eeee3de3be4eb5a Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Tue, 27 Jul 2021 23:40:32 +0200 Subject: [PATCH 01/15] Fix ICE in `improper_ctypes_definitions` lint with all-ZST transparent types --- compiler/rustc_lint/src/types.rs | 10 ++++++++-- src/test/ui/repr/repr-transparent-issue-87496.rs | 12 ++++++++++++ .../ui/repr/repr-transparent-issue-87496.stderr | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/repr/repr-transparent-issue-87496.rs create mode 100644 src/test/ui/repr/repr-transparent-issue-87496.stderr diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a3a87a48768dc..639fe5ca2a46a 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -851,12 +851,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { use FfiResult::*; if def.repr.transparent() { - // Can assume that only one field is not a ZST, so only check + // Can assume that at most one field is not a ZST, so only check // that field's type for FFI-safety. if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) { self.check_field_type_for_ffi(cache, field, substs) } else { - bug!("malformed transparent type"); + // All fields are ZSTs; this means that the type should behave + // like (), which is FFI-unsafe + FfiUnsafe { + ty, + reason: "this struct contains only zero-sized fields".into(), + help: None, + } } } else { // We can't completely trust repr(C) markings; make sure the fields are diff --git a/src/test/ui/repr/repr-transparent-issue-87496.rs b/src/test/ui/repr/repr-transparent-issue-87496.rs new file mode 100644 index 0000000000000..a4dd45c63f564 --- /dev/null +++ b/src/test/ui/repr/repr-transparent-issue-87496.rs @@ -0,0 +1,12 @@ +// Regression test for the ICE described in #87496. + +// check-pass + +#[repr(transparent)] +struct TransparentCustomZst(()); +extern "C" { + fn good17(p: TransparentCustomZst); + //~^ WARNING: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe +} + +fn main() {} diff --git a/src/test/ui/repr/repr-transparent-issue-87496.stderr b/src/test/ui/repr/repr-transparent-issue-87496.stderr new file mode 100644 index 0000000000000..c488755cc242c --- /dev/null +++ b/src/test/ui/repr/repr-transparent-issue-87496.stderr @@ -0,0 +1,16 @@ +warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe + --> $DIR/repr-transparent-issue-87496.rs:8:18 + | +LL | fn good17(p: TransparentCustomZst); + | ^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: `#[warn(improper_ctypes)]` on by default + = note: this struct contains only zero-sized fields +note: the type is defined here + --> $DIR/repr-transparent-issue-87496.rs:6:1 + | +LL | struct TransparentCustomZst(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + From ced597edb7e154092efde9df975ee76f9642a200 Mon Sep 17 00:00:00 2001 From: piegames Date: Wed, 25 Aug 2021 20:22:19 +0200 Subject: [PATCH 02/15] Add TcpListener::into_incoming and IntoIncoming The `incoming` method is really useful, however for some use cases the borrow this introduces is needlessly restricting. Thus, an owned variant is added. --- library/std/src/net/tcp.rs | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index 336891ec1eb94..45f5f3dac85a5 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -96,6 +96,18 @@ pub struct Incoming<'a> { listener: &'a TcpListener, } +/// An iterator that infinitely [`accept`]s connections on a [`TcpListener`]. +/// +/// This `struct` is created by the [`TcpListener::into_incoming`] method. +/// See its documentation for more. +/// +/// [`accept`]: TcpListener::accept +#[derive(Debug)] +#[unstable(feature = "tcplistener_into_incoming", issue = "88339")] +pub struct IntoIncoming { + listener: TcpListener, +} + impl TcpStream { /// Opens a TCP connection to a remote host. /// @@ -798,6 +810,37 @@ impl TcpListener { Incoming { listener: self } } + /// Turn this into an iterator over the connections being received on this + /// listener. + /// + /// The returned iterator will never return [`None`] and will also not yield + /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to + /// calling [`TcpListener::accept`] in a loop. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(tcplistener_into_incoming)] + /// use std::net::{TcpListener, TcpStream}; + /// + /// fn listen_on(port: u16) -> impl Iterator { + /// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); + /// listener.into_incoming() + /// .filter_map(Result::ok) /* Ignore failed connections */ + /// } + /// + /// fn main() -> std::io::Result<()> { + /// for stream in listen_on(80) { + /// /* handle the connection here */ + /// } + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "tcplistener_into_incoming", issue = "88339")] + pub fn into_incoming(self) -> IntoIncoming { + IntoIncoming { listener: self } + } + /// Sets the value for the `IP_TTL` option on this socket. /// /// This value sets the time-to-live field that is used in every packet sent @@ -935,6 +978,14 @@ impl<'a> Iterator for Incoming<'a> { } } +#[unstable(feature = "tcplistener_into_incoming", issue = "88339")] +impl Iterator for IntoIncoming { + type Item = io::Result; + fn next(&mut self) -> Option> { + Some(self.listener.accept().map(|p| p.0)) + } +} + impl AsInner for TcpListener { fn as_inner(&self) -> &net_imp::TcpListener { &self.0 From 3feddf71e685f202e6f4f76ae9167daece33e460 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 6 Sep 2021 16:59:24 -0500 Subject: [PATCH 03/15] Add `ConstraintCategory::Usage` for handling aggregate construction In some cases, we emit borrowcheck diagnostics pointing at a particular field expression in a struct expression (e.g. `MyStruct { field: my_expr }`). However, this behavior currently relies on us choosing the `ConstraintCategory::Boring` with the 'correct' span. When adding additional variants to `ConstraintCategory`, (or changing existing usages away from `ConstraintCategory::Boring`), the current behavior can easily get broken, since a non-boring constraint will get chosen over a boring one. To make the diagnostic output less fragile, this commit adds a `ConstraintCategory::Usage` variant. We use this variant for the temporary assignments created for each field of an aggregate we are constructing. Using this new variant, we can emit a message mentioning "this usage", emphasizing the fact that the error message is related to the specific use site (in the struct expression). This is preparation for additional work on improving NLL error messages (see #57374) --- .../src/diagnostics/region_errors.rs | 1 + compiler/rustc_borrowck/src/type_check/mod.rs | 13 ++++++++++ compiler/rustc_middle/src/mir/mod.rs | 3 +++ compiler/rustc_middle/src/mir/query.rs | 8 +++---- .../src/build/expr/as_operand.rs | 17 +++++++++---- .../src/build/expr/as_rvalue.rs | 24 +++++++++++-------- .../rustc_mir_build/src/build/expr/into.rs | 11 +++++++-- src/test/ui/issues/issue-61882-2.stderr | 2 +- src/test/ui/nll/issue-46036.stderr | 2 +- .../user-annotations/adt-brace-enums.stderr | 6 ++--- .../user-annotations/adt-brace-structs.stderr | 6 ++--- .../user-annotations/adt-tuple-enums.stderr | 6 ++--- .../user-annotations/adt-tuple-struct.stderr | 6 ++--- .../ui/nll/where_clauses_in_structs.stderr | 2 +- 14 files changed, 71 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 57d2a3c5ce91b..0761d63c66540 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -40,6 +40,7 @@ impl ConstraintDescription for ConstraintCategory { ConstraintCategory::CopyBound => "copying this value ", ConstraintCategory::OpaqueType => "opaque type ", ConstraintCategory::ClosureUpvar(_) => "closure capture ", + ConstraintCategory::Usage => "this usage ", ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => "", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 2c8ff45b00da4..9e8d418a369cc 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1386,11 +1386,24 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Return(ReturnConstraint::Normal) } } + Some(l) + if matches!( + body.local_decls[l].local_info, + Some(box LocalInfo::AggregateTemp) + ) => + { + ConstraintCategory::Usage + } Some(l) if !body.local_decls[l].is_user_variable() => { ConstraintCategory::Boring } _ => ConstraintCategory::Assignment, }; + debug!( + "assignment category: {:?} {:?}", + category, + place.as_local().map(|l| &body.local_decls[l]) + ); let place_ty = place.ty(body, tcx).ty; let place_ty = self.normalize(place_ty, location); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 38d4c5b4bd10e..8a72b84bda80f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -993,6 +993,9 @@ pub enum LocalInfo<'tcx> { StaticRef { def_id: DefId, is_thread_local: bool }, /// A temporary created that references the const with the given `DefId` ConstRef { def_id: DefId }, + /// A temporary created during the creation of an aggregate + /// (e.g. a temporary for `foo` in `MyStruct { my_field: foo }`) + AggregateTemp, } impl<'tcx> LocalDecl<'tcx> { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 1bdb6ca012b4a..04beaa1379be5 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -332,17 +332,15 @@ pub enum ConstraintCategory { CopyBound, SizedBound, Assignment, + /// A constraint that came from a usage of a variable (e.g. in an ADT expression + /// like `Foo { field: my_val }`) + Usage, OpaqueType, ClosureUpvar(hir::HirId), /// A "boring" constraint (caused by the given location) is one that /// the user probably doesn't want to see described in diagnostics, /// because it is kind of an artifact of the type system setup. - /// Example: `x = Foo { field: y }` technically creates - /// intermediate regions representing the "type of `Foo { field: y - /// }`", and data flows from `y` into those variables, but they - /// are not very interesting. The assignment into `x` on the other - /// hand might be. Boring, // Boring and applicable everywhere. BoringNoLocation, diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index bbb2f89fda939..b627b0763a286 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -20,7 +20,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { let local_scope = self.local_scope(); - self.as_operand(block, Some(local_scope), expr) + self.as_operand(block, Some(local_scope), expr, None) } /// Returns an operand suitable for use until the end of the current scope expression and @@ -85,6 +85,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// temporary `tmp = x`, so that we capture the value of `x` at /// this time. /// + /// If we end up needing to create a temporary, then we will use + /// `local_info` as its `LocalInfo`, unless `as_temporary` + /// has already assigned it a non-`None` `LocalInfo`. + /// Normally, you should use `None` for `local_info` + /// /// The operand is known to be live until the end of `scope`. /// /// Like `as_local_call_operand`, except that the argument will @@ -94,15 +99,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mut block: BasicBlock, scope: Option, expr: &Expr<'tcx>, + local_info: Option>>, ) -> BlockAnd> { - debug!("as_operand(block={:?}, expr={:?})", block, expr); + debug!("as_operand(block={:?}, expr={:?} local_info={:?})", block, expr, local_info); let this = self; if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind { let source_info = this.source_info(expr.span); let region_scope = (region_scope, source_info); return this.in_scope(region_scope, lint_level, |this| { - this.as_operand(block, scope, &this.thir[value]) + this.as_operand(block, scope, &this.thir[value], local_info) }); } @@ -115,6 +121,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } Category::Place | Category::Rvalue(..) => { let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut)); + if this.local_decls[operand].local_info.is_none() { + this.local_decls[operand].local_info = local_info; + } block.and(Operand::Move(Place::from(operand))) } } @@ -167,6 +176,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - this.as_operand(block, scope, expr) + this.as_operand(block, scope, expr, None) } } diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 68de1af613d9f..de532baab2fb2 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -52,16 +52,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Repeat { value, count } => { let value_operand = - unpack!(block = this.as_operand(block, scope, &this.thir[value])); + unpack!(block = this.as_operand(block, scope, &this.thir[value], None)); block.and(Rvalue::Repeat(value_operand, count)) } ExprKind::Binary { op, lhs, rhs } => { - let lhs = unpack!(block = this.as_operand(block, scope, &this.thir[lhs])); - let rhs = unpack!(block = this.as_operand(block, scope, &this.thir[rhs])); + let lhs = unpack!(block = this.as_operand(block, scope, &this.thir[lhs], None)); + let rhs = unpack!(block = this.as_operand(block, scope, &this.thir[rhs], None)); this.build_binary_op(block, op, expr_span, expr.ty, lhs, rhs) } ExprKind::Unary { op, arg } => { - let arg = unpack!(block = this.as_operand(block, scope, &this.thir[arg])); + let arg = unpack!(block = this.as_operand(block, scope, &this.thir[arg], None)); // Check for -MIN on signed integers if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() { let bool_ty = this.tcx.types.bool; @@ -116,11 +116,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(Rvalue::Use(Operand::Move(Place::from(result)))) } ExprKind::Cast { source } => { - let source = unpack!(block = this.as_operand(block, scope, &this.thir[source])); + let source = + unpack!(block = this.as_operand(block, scope, &this.thir[source], None)); block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty)) } ExprKind::Pointer { cast, source } => { - let source = unpack!(block = this.as_operand(block, scope, &this.thir[source])); + let source = + unpack!(block = this.as_operand(block, scope, &this.thir[source], None)); block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty)) } ExprKind::Array { ref fields } => { @@ -155,7 +157,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fields: Vec<_> = fields .into_iter() .copied() - .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f]))) + .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f], None))) .collect(); block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(el_ty)), fields)) @@ -166,7 +168,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fields: Vec<_> = fields .into_iter() .copied() - .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f]))) + .map(|f| unpack!(block = this.as_operand(block, scope, &this.thir[f], None))) .collect(); block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields)) @@ -242,7 +244,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &this.thir[arg], ) ), - _ => unpack!(block = this.as_operand(block, scope, upvar)), + _ => { + unpack!(block = this.as_operand(block, scope, upvar, None)) + } } } } @@ -304,7 +308,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Category::of(&expr.kind), Some(Category::Rvalue(RvalueFunc::AsRvalue)) )); - let operand = unpack!(block = this.as_operand(block, scope, expr)); + let operand = unpack!(block = this.as_operand(block, scope, expr, None)); block.and(Rvalue::Use(operand)) } } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index e30e758e63779..1803a18441ce2 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -326,10 +326,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let fields_map: FxHashMap<_, _> = fields .into_iter() .map(|f| { + let local_info = Box::new(LocalInfo::AggregateTemp); ( f.name, unpack!( - block = this.as_operand(block, Some(scope), &this.thir[f.expr]) + block = this.as_operand( + block, + Some(scope), + &this.thir[f.expr], + Some(local_info) + ) ), ) }) @@ -508,7 +514,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::Yield { value } => { let scope = this.local_scope(); - let value = unpack!(block = this.as_operand(block, Some(scope), &this.thir[value])); + let value = + unpack!(block = this.as_operand(block, Some(scope), &this.thir[value], None)); let resume = this.cfg.start_new_block(); this.cfg.terminate( block, diff --git a/src/test/ui/issues/issue-61882-2.stderr b/src/test/ui/issues/issue-61882-2.stderr index 03a65540ced04..0b8e134c9662e 100644 --- a/src/test/ui/issues/issue-61882-2.stderr +++ b/src/test/ui/issues/issue-61882-2.stderr @@ -5,7 +5,7 @@ LL | Self(&x); | ^^ | | | borrowed value does not live long enough - | requires that `x` is borrowed for `'static` + | this usage requires that `x` is borrowed for `'static` LL | LL | } | - `x` dropped here while still borrowed diff --git a/src/test/ui/nll/issue-46036.stderr b/src/test/ui/nll/issue-46036.stderr index 49dd0e267b8ea..e6e95ee613647 100644 --- a/src/test/ui/nll/issue-46036.stderr +++ b/src/test/ui/nll/issue-46036.stderr @@ -5,7 +5,7 @@ LL | let foo = Foo { x: &a }; | ^^ | | | borrowed value does not live long enough - | requires that `a` is borrowed for `'static` + | this usage requires that `a` is borrowed for `'static` LL | loop { } LL | } | - `a` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr index e38b77fdcea01..253e382511045 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-enums.stderr @@ -5,7 +5,7 @@ LL | SomeEnum::SomeVariant::<&'static u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-brace-structs.stderr b/src/test/ui/nll/user-annotations/adt-brace-structs.stderr index 3c3003477c2d6..8b9d1705df6ad 100644 --- a/src/test/ui/nll/user-annotations/adt-brace-structs.stderr +++ b/src/test/ui/nll/user-annotations/adt-brace-structs.stderr @@ -5,7 +5,7 @@ LL | SomeStruct::<&'static u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeStruct::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeStruct::<&'a u32> { t: &c }; | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr b/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr index 810912bf88618..2fa7042631d21 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-tuple-enums.stderr @@ -5,7 +5,7 @@ LL | SomeEnum::SomeVariant::<&'static u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeEnum::SomeVariant::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeEnum::SomeVariant::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr b/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr index 4d2140eca1b02..76b5252258c7b 100644 --- a/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr +++ b/src/test/ui/nll/user-annotations/adt-tuple-struct.stderr @@ -5,7 +5,7 @@ LL | SomeStruct::<&'static u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'static` + | this usage requires that `c` is borrowed for `'static` LL | } | - `c` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | SomeStruct::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | } | - `c` dropped here while still borrowed @@ -33,7 +33,7 @@ LL | SomeStruct::<&'a u32>(&c); | ^^ | | | borrowed value does not live long enough - | requires that `c` is borrowed for `'a` + | this usage requires that `c` is borrowed for `'a` LL | }; | - `c` dropped here while still borrowed diff --git a/src/test/ui/nll/where_clauses_in_structs.stderr b/src/test/ui/nll/where_clauses_in_structs.stderr index 2e990131e61de..8499b00f6f556 100644 --- a/src/test/ui/nll/where_clauses_in_structs.stderr +++ b/src/test/ui/nll/where_clauses_in_structs.stderr @@ -6,7 +6,7 @@ LL | fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) { | | | lifetime `'a` defined here LL | Foo { x, y }; - | ^ requires that `'a` must outlive `'b` + | ^ this usage requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` From e1873ba007149e69bb996f7becadc796ed87fc0c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 11 Sep 2021 16:41:14 -0700 Subject: [PATCH 04/15] cleanup(rustc_trait_selection): remove vestigial code from rustc_on_unimplemented This isn't allowed by the validator, and seems to be unused. When it was added in ed10a3faae1fd1176b2edf4a61438e0542c103b9, it was used on `Sized`, and that usage is gone. --- compiler/rustc_span/src/symbol.rs | 1 - .../src/traits/error_reporting/on_unimplemented.rs | 3 --- 2 files changed, 4 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c816d06045681..41ef0795f2553 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -934,7 +934,6 @@ symbols! { panic_unwind, panicking, param_attrs, - parent_trait, partial_cmp, partial_ord, passes, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 3a32f1cb903e5..6128c119b6b76 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -154,9 +154,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { flags.push((sym::from_method, Some(method.to_string()))); } } - if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) { - flags.push((sym::parent_trait, Some(t))); - } if let Some(k) = obligation.cause.span.desugaring_kind() { flags.push((sym::from_desugaring, None)); From cbd79836a5b7ef07e33213cb979294ad1b9faccc Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Mon, 13 Sep 2021 19:39:30 +0200 Subject: [PATCH 05/15] Improve error message for type mismatch in generator arguments --- .../src/traits/error_reporting/mod.rs | 5 ++- .../src/traits/error_reporting/suggestions.rs | 33 +++++++++++-------- src/test/ui/generator/issue-88653.rs | 19 +++++++++++ src/test/ui/generator/issue-88653.stderr | 12 +++++++ 4 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/generator/issue-88653.rs create mode 100644 src/test/ui/generator/issue-88653.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 761b217c78f4e..6eb6164846ccc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -730,7 +730,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; let found_did = match *found_trait_ty.kind() { - ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did), + ty::Closure(did, _) + | ty::Foreign(did) + | ty::FnDef(did, _) + | ty::Generator(did, ..) => Some(did), ty::Adt(def, _) => Some(def.did), _ => None, }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 9371ff3405eb0..362a5f47ffe30 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1250,33 +1250,40 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, ) -> String { let inputs = trait_ref.skip_binder().substs.type_at(1); - let sig = if let ty::Tuple(inputs) = inputs.kind() { - tcx.mk_fn_sig( - inputs.iter().map(|k| k.expect_ty()), - tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))), - false, - hir::Unsafety::Normal, - abi::Abi::Rust, - ) - } else { - tcx.mk_fn_sig( + let sig = match inputs.kind() { + ty::Tuple(inputs) + if tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() => + { + tcx.mk_fn_sig( + inputs.iter().map(|k| k.expect_ty()), + tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))), + false, + hir::Unsafety::Normal, + abi::Abi::Rust, + ) + } + _ => tcx.mk_fn_sig( std::iter::once(inputs), tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))), false, hir::Unsafety::Normal, abi::Abi::Rust, - ) + ), }; trait_ref.rebind(sig).to_string() } - let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure(); + let argument_kind = match expected_ref.skip_binder().substs.type_at(0) { + t if t.is_closure() => "closure", + t if t.is_generator() => "generator", + _ => "function", + }; let mut err = struct_span_err!( self.tcx.sess, span, E0631, "type mismatch in {} arguments", - if argument_is_closure { "closure" } else { "function" } + argument_kind ); let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found)); diff --git a/src/test/ui/generator/issue-88653.rs b/src/test/ui/generator/issue-88653.rs new file mode 100644 index 0000000000000..ce9159b53e0f0 --- /dev/null +++ b/src/test/ui/generator/issue-88653.rs @@ -0,0 +1,19 @@ +// Regression test for #88653, where a confusing warning about a +// type mismatch in generator arguments was issued. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn foo(bar: bool) -> impl Generator<(bool,)> { +//~^ ERROR: type mismatch in generator arguments [E0631] +//~| NOTE: expected signature of `fn((bool,)) -> _` + |bar| { + //~^ NOTE: found signature of `fn(bool) -> _` + if bar { + yield bar; + } + } +} + +fn main() {} diff --git a/src/test/ui/generator/issue-88653.stderr b/src/test/ui/generator/issue-88653.stderr new file mode 100644 index 0000000000000..5bd8ad129fef9 --- /dev/null +++ b/src/test/ui/generator/issue-88653.stderr @@ -0,0 +1,12 @@ +error[E0631]: type mismatch in generator arguments + --> $DIR/issue-88653.rs:8:22 + | +LL | fn foo(bar: bool) -> impl Generator<(bool,)> { + | ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _` +... +LL | |bar| { + | ----- found signature of `fn(bool) -> _` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0631`. From 6b7f916008f48b9a8635d461dc33f7c5621611a2 Mon Sep 17 00:00:00 2001 From: Dan Zwell Date: Tue, 14 Sep 2021 14:22:49 +0800 Subject: [PATCH 06/15] Document the closure arguments for `reduce`. Fixes issue #88927. --- library/core/src/iter/traits/iterator.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 330d3714247c5..b0a9d9f5ef5c9 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2172,8 +2172,9 @@ pub trait Iterator { /// If the iterator is empty, returns [`None`]; otherwise, returns the /// result of the reduction. /// + /// The reducing function is a closure with two arguments: an 'accumulator', and an element. /// For iterators with at least one element, this is the same as [`fold()`] - /// with the first element of the iterator as the initial value, folding + /// with the first element of the iterator as the initial accumulator value, folding /// every subsequent element into it. /// /// [`fold()`]: Iterator::fold @@ -2187,8 +2188,8 @@ pub trait Iterator { /// where I: Iterator, /// I::Item: Ord, /// { - /// iter.reduce(|a, b| { - /// if a >= b { a } else { b } + /// iter.reduce(|accum, item| { + /// if accum >= item { accum } else { item } /// }) /// } /// let a = [10, 20, 5, -23, 0]; From 349ac4f6c8839c89a39d1dd9fac1fbe9a30f2626 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 12 Sep 2021 15:26:30 +0000 Subject: [PATCH 07/15] Const Deref --- library/alloc/src/borrow.rs | 6 +++++- library/core/src/mem/manually_drop.rs | 6 ++++-- library/core/src/ops/deref.rs | 6 ++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 482a497201de6..9ecbf0582319e 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -330,7 +330,11 @@ impl Cow<'_, B> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for Cow<'_, B> { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for Cow<'_, B> +where + B::Owned: ~const Borrow, +{ type Target = B; fn deref(&self) -> &B { diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index d86939454be5b..20b6453990d75 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -145,7 +145,8 @@ impl ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -impl Deref for ManuallyDrop { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for ManuallyDrop { type Target = T; #[inline(always)] fn deref(&self) -> &T { @@ -154,7 +155,8 @@ impl Deref for ManuallyDrop { } #[stable(feature = "manually_drop", since = "1.20.0")] -impl DerefMut for ManuallyDrop { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const DerefMut for ManuallyDrop { #[inline(always)] fn deref_mut(&mut self) -> &mut T { &mut self.value diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index dcf3ce070ec65..fb4ec83bc287e 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -76,7 +76,8 @@ pub trait Deref { } #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for &T { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for &T { type Target = T; #[rustc_diagnostic_item = "noop_method_deref"] @@ -89,7 +90,8 @@ impl Deref for &T { impl !DerefMut for &T {} #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for &mut T { +#[rustc_const_unstable(feature = "const_deref", issue = "88955")] +impl const Deref for &mut T { type Target = T; fn deref(&self) -> &T { From 97621162996c0746a528edaddb43c984e15a3d51 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Sun, 12 Sep 2021 18:49:56 +0000 Subject: [PATCH 08/15] Move object safety suggestions to the end of the error --- .../rustc_infer/src/traits/error_reporting/mod.rs | 12 ++++++++---- compiler/rustc_middle/src/traits/mod.rs | 4 ++-- .../associated-const-in-trait.stderr | 2 +- src/test/ui/associated-item/issue-48027.stderr | 2 +- ...coherence-impl-trait-for-trait-object-safe.stderr | 2 +- .../generic_const_exprs/object-safety-err-ret.stderr | 2 +- src/test/ui/error-codes/E0038.stderr | 2 +- .../feature-gate-object_safe_for_dispatch.stderr | 4 ++-- .../gat-in-trait-path.stderr | 2 +- .../generic-associated-types/issue-67510-pass.stderr | 2 +- .../ui/generic-associated-types/issue-76535.stderr | 4 ++-- .../ui/generic-associated-types/issue-78671.stderr | 2 +- .../ui/generic-associated-types/issue-79422.stderr | 4 ++-- .../ui/generic-associated-types/trait-objects.stderr | 2 +- src/test/ui/issues/issue-18959.stderr | 2 +- src/test/ui/issues/issue-19538.stderr | 4 ++-- .../object-safety-associated-consts.curr.stderr | 2 +- ...associated-consts.object_safe_for_dispatch.stderr | 2 +- .../object-safety/object-safety-generics.curr.stderr | 4 ++-- ...t-safety-generics.object_safe_for_dispatch.stderr | 4 ++-- .../object-safety-mentions-Self.curr.stderr | 4 ++-- ...ety-mentions-Self.object_safe_for_dispatch.stderr | 4 ++-- .../object-unsafe-trait-references-self.stderr | 4 ++-- src/test/ui/traits/item-privacy.stderr | 6 +++--- src/test/ui/traits/test-2.stderr | 8 ++++---- ...-parameter-defaults-referencing-Self-ppaux.stderr | 2 +- src/test/ui/wf/issue-87495.stderr | 2 +- src/test/ui/wf/wf-object-safe.stderr | 2 +- 28 files changed, 50 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index d0bd508bc257f..9dbfa3a850ba8 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -83,10 +83,6 @@ pub fn report_object_safety_error( messages.push(msg.clone()); } } - if trait_span.is_some() { - // Only provide the help if its a local trait, otherwise it's not actionable. - violation.solution(&mut err); - } } } let has_multi_span = !multi_span.is_empty(); @@ -104,5 +100,13 @@ pub fn report_object_safety_error( to be resolvable dynamically; for more information visit \ ", ); + if trait_span.is_some() { + let mut reported_violations: Vec<_> = reported_violations.into_iter().collect(); + reported_violations.sort(); + for violation in reported_violations { + // Only provide the help if its a local trait, otherwise it's not actionable. + violation.solution(&mut err); + } + } err } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 07c2ffac8c78c..fc88b95bc67cd 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -730,7 +730,7 @@ pub struct ImplSourceTraitAliasData<'tcx, N> { pub nested: Vec, } -#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] pub enum ObjectSafetyViolation { /// `Self: Sized` declared on the trait. SizedSelf(SmallVec<[Span; 1]>), @@ -879,7 +879,7 @@ impl ObjectSafetyViolation { } /// Reasons a method might not be object-safe. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] pub enum MethodViolationCode { /// e.g., `fn foo()` StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */), diff --git a/src/test/ui/associated-consts/associated-const-in-trait.stderr b/src/test/ui/associated-consts/associated-const-in-trait.stderr index 7b4594108246b..fc949f2494857 100644 --- a/src/test/ui/associated-consts/associated-const-in-trait.stderr +++ b/src/test/ui/associated-consts/associated-const-in-trait.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | impl dyn Trait { | ^^^^^^^^^ `Trait` cannot be made into an object | - = help: consider moving `N` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/associated-const-in-trait.rs:6:11 | @@ -12,6 +11,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | const N: usize; | ^ ...because it contains this associated `const` + = help: consider moving `N` to another trait error: aborting due to previous error diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr index 77915a80a79b0..7b158f1d75474 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -21,7 +21,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | impl dyn Bar {} | ^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `X` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-48027.rs:2:11 | @@ -29,6 +28,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr index a2b779e29540b..e9090c1b6bcfb 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object LL | impl NotObjectSafe for dyn NotObjectSafe { } | ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object | - = help: consider moving `eq` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:6:43 | @@ -12,6 +11,7 @@ LL | trait NotObjectSafe { fn eq(&self, other: Self); } | ------------- ^^^^ ...because method `eq` references the `Self` type in this parameter | | | this trait cannot be made into an object... + = help: consider moving `eq` to another trait error: aborting due to previous error diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr index 319e6c2c032a0..4e1d71f154558 100644 --- a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | fn use_dyn(v: &dyn Foo) { | ^^^^^^^ `Foo` cannot be made into an object | - = help: consider moving `test` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-err-ret.rs:8:23 | @@ -12,6 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn test(&self) -> [u8; bar::()]; | ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type + = help: consider moving `test` to another trait error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index cead9776e4abb..3773d6f5234b0 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | fn call_foo(x: Box) { | ^^^^^^^^^ `Trait` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/E0038.rs:2:22 | @@ -12,6 +11,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn foo(&self) -> Self; | ^^^^ ...because method `foo` references the `Self` type in its return type + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index a3bd65e518e4c..72cb4cc843cc4 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -40,7 +40,6 @@ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object LL | fn takes_non_object_safe_box(obj: Box) { | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/feature-gate-object_safe_for_dispatch.rs:11:8 | @@ -48,6 +47,7 @@ LL | trait NonObjectSafe3 { | -------------- this trait cannot be made into an object... LL | fn foo(&self); | ^^^ ...because method `foo` has generic type parameters + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe4` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35 @@ -55,7 +55,6 @@ error[E0038]: the trait `NonObjectSafe4` cannot be made into an object LL | fn return_non_object_safe_rc() -> std::rc::Rc { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/feature-gate-object_safe_for_dispatch.rs:15:22 | @@ -63,6 +62,7 @@ LL | trait NonObjectSafe4 { | -------------- this trait cannot be made into an object... LL | fn foo(&self, s: &Self); | ^^^^^ ...because method `foo` references the `Self` type in this parameter + = help: consider moving `foo` to another trait error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16 diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr index 8651789688eaa..a55642490f975 100644 --- a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Foo` cannot be made into an object LL | fn f(_arg : Box Foo = &'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object | - = help: consider moving `A` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/gat-in-trait-path.rs:5:10 | @@ -12,6 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | type A<'a> where Self: 'a; | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.stderr index b4b89ab047363..7dd1bdf891eb5 100644 --- a/src/test/ui/generic-associated-types/issue-67510-pass.stderr +++ b/src/test/ui/generic-associated-types/issue-67510-pass.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `X` cannot be made into an object LL | fn _func1<'a>(_x: Box=&'a ()>>) {} | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object | - = help: consider moving `Y` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-67510-pass.rs:4:10 | @@ -12,6 +11,7 @@ LL | trait X { | - this trait cannot be made into an object... LL | type Y<'a>; | ^ ...because it contains the generic associated type `Y` + = help: consider moving `Y` to another trait error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/src/test/ui/generic-associated-types/issue-76535.stderr index 246454f0612db..0a7eb5dde6009 100644 --- a/src/test/ui/generic-associated-types/issue-76535.stderr +++ b/src/test/ui/generic-associated-types/issue-76535.stderr @@ -20,7 +20,6 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object LL | let sub: Box> = Box::new(SuperStruct::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object | - = help: consider moving `SubType` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-76535.rs:6:10 | @@ -28,6 +27,7 @@ LL | pub trait SuperTrait { | ---------- this trait cannot be made into an object... LL | type SubType<'a>: SubTrait; | ^^^^^^^ ...because it contains the generic associated type `SubType` + = help: consider moving `SubType` to another trait error[E0038]: the trait `SuperTrait` cannot be made into an object --> $DIR/issue-76535.rs:36:57 @@ -35,7 +35,6 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object LL | let sub: Box> = Box::new(SuperStruct::new(0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object | - = help: consider moving `SubType` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-76535.rs:6:10 | @@ -43,6 +42,7 @@ LL | pub trait SuperTrait { | ---------- this trait cannot be made into an object... LL | type SubType<'a>: SubTrait; | ^^^^^^^ ...because it contains the generic associated type `SubType` + = help: consider moving `SubType` to another trait = note: required because of the requirements on the impl of `CoerceUnsized>>>` for `Box` = note: required by cast to type `Box>>` diff --git a/src/test/ui/generic-associated-types/issue-78671.stderr b/src/test/ui/generic-associated-types/issue-78671.stderr index b92730839568d..17dd0ff4a0c94 100644 --- a/src/test/ui/generic-associated-types/issue-78671.stderr +++ b/src/test/ui/generic-associated-types/issue-78671.stderr @@ -20,7 +20,6 @@ error[E0038]: the trait `CollectionFamily` cannot be made into an object LL | Box::new(Family) as &dyn CollectionFamily | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object | - = help: consider moving `Member` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-78671.rs:4:10 | @@ -28,6 +27,7 @@ LL | trait CollectionFamily { | ---------------- this trait cannot be made into an object... LL | type Member; | ^^^^^^ ...because it contains the generic associated type `Member` + = help: consider moving `Member` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/issue-79422.stderr b/src/test/ui/generic-associated-types/issue-79422.stderr index 8d8ef6bf83685..b6f856a97e725 100644 --- a/src/test/ui/generic-associated-types/issue-79422.stderr +++ b/src/test/ui/generic-associated-types/issue-79422.stderr @@ -20,7 +20,6 @@ error[E0038]: the trait `MapLike` cannot be made into an object LL | as Box>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object | - = help: consider moving `VRefCont` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-79422.rs:20:10 | @@ -28,6 +27,7 @@ LL | trait MapLike { | ------- this trait cannot be made into an object... LL | type VRefCont<'a>: RefCont<'a, V>; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` + = help: consider moving `VRefCont` to another trait error[E0038]: the trait `MapLike` cannot be made into an object --> $DIR/issue-79422.rs:41:13 @@ -35,7 +35,6 @@ error[E0038]: the trait `MapLike` cannot be made into an object LL | let m = Box::new(std::collections::BTreeMap::::new()) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object | - = help: consider moving `VRefCont` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-79422.rs:20:10 | @@ -43,6 +42,7 @@ LL | trait MapLike { | ------- this trait cannot be made into an object... LL | type VRefCont<'a>: RefCont<'a, V>; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` + = help: consider moving `VRefCont` to another trait = note: required because of the requirements on the impl of `CoerceUnsized + 'static)>>>` for `Box>` = note: required by cast to type `Box + 'static)>>` diff --git a/src/test/ui/generic-associated-types/trait-objects.stderr b/src/test/ui/generic-associated-types/trait-objects.stderr index 6429bb8159e1f..5ab37910207ca 100644 --- a/src/test/ui/generic-associated-types/trait-objects.stderr +++ b/src/test/ui/generic-associated-types/trait-objects.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `StreamingIterator` cannot be made into an object LL | fn min_size(x: &mut dyn for<'a> StreamingIterator = &'a i32>) -> usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object | - = help: consider moving `Item` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/trait-objects.rs:4:10 | @@ -12,6 +11,7 @@ LL | trait StreamingIterator { | ----------------- this trait cannot be made into an object... LL | type Item<'a> where Self: 'a; | ^^^^ ...because it contains the generic associated type `Item` + = help: consider moving `Item` to another trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index 2a5416ce85ba6..b9e27873636c3 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn foo(b: &dyn Bar) { | ^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-18959.rs:1:20 | @@ -12,6 +11,7 @@ LL | pub trait Foo { fn foo(&self, ext_thing: &T); } | ^^^ ...because method `foo` has generic type parameters LL | pub trait Bar: Foo { } | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr index 555d0ff0dc787..7b37e1f95dcc6 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/issues/issue-19538.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-19538.rs:2:8 | @@ -13,6 +12,7 @@ LL | fn foo(&self, val: T); ... LL | trait Bar: Foo { } | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:30 @@ -20,7 +20,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | let test: &mut dyn Bar = &mut thing; | ^^^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-19538.rs:2:8 | @@ -29,6 +28,7 @@ LL | fn foo(&self, val: T); ... LL | trait Bar: Foo { } | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing` = note: required by cast to type `&mut dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr index 35ec586892c05..9dd144fee24a6 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `X` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-associated-consts.rs:9:11 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index d51734ed2316b..9ba3b251e6603 100644 --- a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t | ^ `Bar` cannot be made into an object | - = help: consider moving `X` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-associated-consts.rs:9:11 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | const X: usize; | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr index 8d6094c514429..345950f1ae670 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:24:39 @@ -19,7 +19,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar_explicit(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -27,6 +26,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index 3d2b2bb228cb5..86355627c796f 100644 --- a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t | ^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` @@ -21,7 +21,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t as &dyn Bar | ^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-generics.rs:10:8 | @@ -29,6 +28,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr index 336929702e6cd..f91c9b9856055 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | fn make_bar(t: &T) -> &dyn Bar { | ^^^^^^^^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:11:22 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:28:30 @@ -19,7 +19,6 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | fn make_baz(t: &T) -> &dyn Baz { | ^^^^^^^^ `Baz` cannot be made into an object | - = help: consider moving `baz` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:15:22 | @@ -27,6 +26,7 @@ LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 6e7896e309cc6..f48628c9d1111 100644 --- a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object LL | t | ^ `Bar` cannot be made into an object | - = help: consider moving `bar` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:11:22 | @@ -12,6 +11,7 @@ LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, x: &Self); | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` @@ -21,7 +21,6 @@ error[E0038]: the trait `Baz` cannot be made into an object LL | t | ^ `Baz` cannot be made into an object | - = help: consider moving `baz` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-safety-mentions-Self.rs:15:22 | @@ -29,6 +28,7 @@ LL | trait Baz { | --- this trait cannot be made into an object... LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T` = note: required by cast to type `&dyn Baz` diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr index f332b7213d8bc..54f19fe9da445 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -4,8 +4,6 @@ error[E0038]: the trait `Trait` cannot be made into an object LL | fn bar(x: &dyn Trait) {} | ^^^^^^^^^ `Trait` cannot be made into an object | - = help: consider moving `baz` to another trait - = help: consider moving `bat` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-unsafe-trait-references-self.rs:2:22 | @@ -15,6 +13,8 @@ LL | fn baz(&self, _: Self) {} | ^^^^ ...because method `baz` references the `Self` type in this parameter LL | fn bat(&self) -> Self {} | ^^^^ ...because method `bat` references the `Self` type in its return type + = help: consider moving `baz` to another trait + = help: consider moving `bat` to another trait error[E0038]: the trait `Other` cannot be made into an object --> $DIR/object-unsafe-trait-references-self.rs:10:12 diff --git a/src/test/ui/traits/item-privacy.stderr b/src/test/ui/traits/item-privacy.stderr index 2260dcfc70ea3..ef5d5cdff8f4b 100644 --- a/src/test/ui/traits/item-privacy.stderr +++ b/src/test/ui/traits/item-privacy.stderr @@ -127,9 +127,6 @@ error[E0038]: the trait `assoc_const::C` cannot be made into an object LL | ::A; | ^^^^^ `assoc_const::C` cannot be made into an object | - = help: consider moving `C` to another trait - = help: consider moving `B` to another trait - = help: consider moving `A` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/item-privacy.rs:25:15 | @@ -143,6 +140,9 @@ LL | pub trait C: A + B { | - this trait cannot be made into an object... LL | const C: u8 = 0; | ^ ...because it contains this associated `const` + = help: consider moving `C` to another trait + = help: consider moving `A` to another trait + = help: consider moving `B` to another trait error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:115:12 diff --git a/src/test/ui/traits/test-2.stderr b/src/test/ui/traits/test-2.stderr index 0289424510f97..d943b48fd0082 100644 --- a/src/test/ui/traits/test-2.stderr +++ b/src/test/ui/traits/test-2.stderr @@ -32,8 +32,6 @@ error[E0038]: the trait `bar` cannot be made into an object LL | (box 10 as Box).dup(); | ^^^^^^^^^^^^ `bar` cannot be made into an object | - = help: consider moving `dup` to another trait - = help: consider moving `blah` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/test-2.rs:4:30 | @@ -42,6 +40,8 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | | | | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait error[E0038]: the trait `bar` cannot be made into an object --> $DIR/test-2.rs:13:6 @@ -49,8 +49,6 @@ error[E0038]: the trait `bar` cannot be made into an object LL | (box 10 as Box).dup(); | ^^^^^^ `bar` cannot be made into an object | - = help: consider moving `dup` to another trait - = help: consider moving `blah` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/test-2.rs:4:30 | @@ -59,6 +57,8 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | | | | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... + = help: consider moving `dup` to another trait + = help: consider moving `blah` to another trait = note: required because of the requirements on the impl of `CoerceUnsized>` for `Box<{integer}>` = note: required by cast to type `Box` diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index 2de5f6eb0f03a..8a296dc7ee6e1 100644 --- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -16,7 +16,6 @@ error[E0038]: the trait `MyAdd` cannot be made into an object LL | let y = x as dyn MyAdd; | ^^^^^^^^^^^^^^ `MyAdd` cannot be made into an object | - = help: consider moving `add` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:6:55 | @@ -24,6 +23,7 @@ LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } | ----- ^^^^ ...because method `add` references the `Self` type in its return type | | | this trait cannot be made into an object... + = help: consider moving `add` to another trait error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/issue-87495.stderr b/src/test/ui/wf/issue-87495.stderr index 010200b5ded1f..c924cd87997e1 100644 --- a/src/test/ui/wf/issue-87495.stderr +++ b/src/test/ui/wf/issue-87495.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `T` cannot be made into an object LL | const CONST: (bool, dyn T); | ^^^^^ `T` cannot be made into an object | - = help: consider moving `CONST` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/issue-87495.rs:4:11 | @@ -12,6 +11,7 @@ LL | trait T { | - this trait cannot be made into an object... LL | const CONST: (bool, dyn T); | ^^^^^ ...because it contains this associated `const` + = help: consider moving `CONST` to another trait error: aborting due to previous error diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 9b749f88fb810..64969fbe3203e 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -4,7 +4,6 @@ error[E0038]: the trait `A` cannot be made into an object LL | let _x: &dyn A; | ^^^^^^ `A` cannot be made into an object | - = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/wf-object-safe.rs:5:23 | @@ -12,6 +11,7 @@ LL | trait A { | - this trait cannot be made into an object... LL | fn foo(&self, _x: &Self); | ^^^^^ ...because method `foo` references the `Self` type in this parameter + = help: consider moving `foo` to another trait error: aborting due to previous error From ef44452a83a21742d67187c0f23d96ce5a05aaff Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 15 Sep 2021 09:13:18 -0700 Subject: [PATCH 09/15] chore(rustc_expand): fix typo in comment --- compiler/rustc_expand/src/mbe/quoted.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index fb7479eafc86f..363cc72b52c3e 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -72,7 +72,7 @@ pub(super) fn parse( // this with just `span.edition()`. A // `SyntaxContext::root()` from the current crate will // have the edition of the current crate, and a - // `SyntaxxContext::root()` from a foreign crate will + // `SyntaxContext::root()` from a foreign crate will // have the edition of that crate (which we manually // retrieve via the `edition` parameter). if span.ctxt() == SyntaxContext::root() { From cc7929b1bd2c50c5b07442195fc6b0a13fa61d35 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 15 Sep 2021 09:14:20 -0700 Subject: [PATCH 10/15] docs(std): add docs for cof_from_cstr impls CC #51430 --- library/std/src/ffi/c_str.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index de05c37785295..3b9175503080c 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -915,6 +915,7 @@ impl From for Box { #[stable(feature = "cow_from_cstr", since = "1.28.0")] impl<'a> From for Cow<'a, CStr> { + /// Converts a [`CString`] into an owned [`Cow`] without copying or allocating. #[inline] fn from(s: CString) -> Cow<'a, CStr> { Cow::Owned(s) @@ -923,6 +924,7 @@ impl<'a> From for Cow<'a, CStr> { #[stable(feature = "cow_from_cstr", since = "1.28.0")] impl<'a> From<&'a CStr> for Cow<'a, CStr> { + /// Converts a [`CStr`] into a borrowed [`Cow`] without copying or allocating. #[inline] fn from(s: &'a CStr) -> Cow<'a, CStr> { Cow::Borrowed(s) @@ -931,6 +933,7 @@ impl<'a> From<&'a CStr> for Cow<'a, CStr> { #[stable(feature = "cow_from_cstr", since = "1.28.0")] impl<'a> From<&'a CString> for Cow<'a, CStr> { + /// Converts a `&`[`CString`] into a borrowed [`Cow`] without copying or allocating. #[inline] fn from(s: &'a CString) -> Cow<'a, CStr> { Cow::Borrowed(s.as_c_str()) From 09745a63fe03ab58178ca579f39304a869c142ed Mon Sep 17 00:00:00 2001 From: Commeownist Date: Wed, 15 Sep 2021 21:31:59 +0300 Subject: [PATCH 11/15] Update clobber_abi list to include k[1-7] regs --- src/doc/unstable-book/src/library-features/asm.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 444b1cbf3cc45..ccaf6e8733e0c 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -804,9 +804,9 @@ The following ABIs can be used with `clobber_abi`: | Architecture | ABI name | Clobbered registers | | ------------ | -------- | ------------------- | -| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `st([0-7])` | -| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `st([0-7])` | +| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | +| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | +| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` | | AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x30`, `v[0-31]`, `p[0-15]`, `ffr` | | ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` | | RISC-V | `"C"`, `"system"`, `"efiapi"` | `x1`, `x[5-7]`, `x[10-17]`, `x[28-31]`, `f[0-7]`, `f[10-17]`, `f[28-31]`, `v[0-31]` | From 4e61d11a160bd43da0451e493d9e076848b8413a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20B=C3=B6ving?= Date: Wed, 15 Sep 2021 20:32:35 +0200 Subject: [PATCH 12/15] Update the backtrace crate https://github.com/rust-lang/backtrace-rs/pull/437 fixed backtraces in OpenBSD -> update it here as well so OpenBSD Rust code can produce proper backtraces. --- library/backtrace | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/backtrace b/library/backtrace index 4f925f8d81dfa..cc89bb66f91b2 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit 4f925f8d81dfa57067537217e501e1dff7433491 +Subproject commit cc89bb66f91b2b4a640b0b525ca5d753e3346d7e From 4fd39dd8a6f20bb919b30a56022c16e235cf7d5a Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Wed, 15 Sep 2021 11:41:37 -0700 Subject: [PATCH 13/15] Make rustc_mir_dataflow::framework::graphviz and rustc_mir_transform::MirPass public --- compiler/rustc_mir_dataflow/src/lib.rs | 4 ++-- compiler/rustc_mir_transform/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index bfae09b7760a0..72c4e27cbeabf 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -28,8 +28,8 @@ pub use self::drop_flag_effects::{ on_lookup_result_bits, }; pub use self::framework::{ - fmt, lattice, visit_results, Analysis, AnalysisDomain, Backward, Direction, Engine, Forward, - GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor, ResultsRefCursor, + fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, Direction, Engine, + Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor, ResultsRefCursor, ResultsVisitable, ResultsVisitor, }; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 90d7cbee976d0..bfd0de85438d1 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -76,7 +76,7 @@ mod unreachable_prop; use rustc_const_eval::transform::check_consts; use rustc_const_eval::transform::promote_consts; use rustc_const_eval::transform::validate; -use rustc_const_eval::transform::MirPass; +pub use rustc_const_eval::transform::MirPass; use rustc_mir_dataflow::rustc_peek; pub fn provide(providers: &mut Providers) { From 47104a34a67444a086fd38c82e005f316f7f567a Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Wed, 15 Sep 2021 11:45:31 -0700 Subject: [PATCH 14/15] Allow call to get_body_with_borrowck_facts without -Z polonius --- compiler/rustc_borrowck/src/consumers.rs | 6 +++--- compiler/rustc_borrowck/src/lib.rs | 8 +++----- compiler/rustc_borrowck/src/nll.rs | 6 ++++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index f6e4e3888418f..4333038a6f936 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -14,7 +14,9 @@ pub use super::{ }; /// This function computes Polonius facts for the given body. It makes a copy of -/// the body because it needs to regenerate the region identifiers. +/// the body because it needs to regenerate the region identifiers. This function +/// should never be invoked during a typical compilation session due to performance +/// issues with Polonius. /// /// Note: /// * This function will panic if the required body was already stolen. This @@ -22,8 +24,6 @@ pub use super::{ /// because they are evaluated during typechecking. The panic can be avoided /// by overriding the `mir_borrowck` query. You can find a complete example /// that shows how to do this at `src/test/run-make/obtain-borrowck/`. -/// * This function will also panic if computation of Polonius facts -/// (`-Zpolonius` flag) is not enabled. /// /// * Polonius is highly unstable, so expect regular changes in its signature or other details. pub fn get_body_with_borrowck_facts<'tcx>( diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4e4b8a953cd12..b3b7d7e02ccef 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -154,11 +154,6 @@ fn do_mir_borrowck<'a, 'tcx>( debug!("do_mir_borrowck(def = {:?})", def); - assert!( - !return_body_with_facts || infcx.tcx.sess.opts.debugging_opts.polonius, - "borrowck facts can be requested only when Polonius is enabled" - ); - let tcx = infcx.tcx; let param_env = tcx.param_env(def.did); let id = tcx.hir().local_def_id_to_hir_id(def.did); @@ -235,6 +230,8 @@ fn do_mir_borrowck<'a, 'tcx>( let borrow_set = Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); + let use_polonius = return_body_with_facts || infcx.tcx.sess.opts.debugging_opts.polonius; + // Compute non-lexical lifetimes. let nll::NllOutput { regioncx, @@ -254,6 +251,7 @@ fn do_mir_borrowck<'a, 'tcx>( &mdpe.move_data, &borrow_set, &upvars, + use_polonius, ); // Dump MIR results into a file, if that is enabled. This let us diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 8b2c0362261ca..477b049b07596 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -164,8 +164,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>( move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, upvars: &[Upvar<'tcx>], + use_polonius: bool, ) -> NllOutput<'tcx> { - let mut all_facts = AllFacts::enabled(infcx.tcx).then_some(AllFacts::default()); + let mut all_facts = + (use_polonius || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default()); let universal_regions = Rc::new(universal_regions); @@ -281,7 +283,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( all_facts.write_to_dir(dir_path, location_table).unwrap(); } - if infcx.tcx.sess.opts.debugging_opts.polonius { + if use_polonius { let algorithm = env::var("POLONIUS_ALGORITHM").unwrap_or_else(|_| String::from("Hybrid")); let algorithm = Algorithm::from_str(&algorithm).unwrap(); From 26eb5bb2d78be1bf86a5b032039c8cff1d5cf94e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Sep 2021 13:37:29 +0200 Subject: [PATCH 15/15] Add rustdoc version into the help popup --- src/librustdoc/html/render/write_shared.rs | 16 ++++++++++++---- src/librustdoc/html/static/css/rustdoc.css | 15 ++++++++++++--- src/librustdoc/html/static/css/themes/ayu.css | 4 ++-- src/librustdoc/html/static/css/themes/dark.css | 4 ++-- src/librustdoc/html/static/css/themes/light.css | 4 ++-- src/librustdoc/html/static/js/main.js | 9 +++++++++ 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 99cd98f7eaeb8..41d04bd5374f4 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -264,10 +264,18 @@ pub(super) fn write_shared( // Maybe we can change the representation to move this out of main.js? write_minify( "main.js", - &static_files::MAIN_JS.replace( - "/* INSERT THEMES HERE */", - &format!(" = {}", serde_json::to_string(&themes).unwrap()), - ), + &static_files::MAIN_JS + .replace( + "/* INSERT THEMES HERE */", + &format!(" = {}", serde_json::to_string(&themes).unwrap()), + ) + .replace( + "/* INSERT RUSTDOC_VERSION HERE */", + &format!( + "rustdoc {}", + rustc_interface::util::version_str().unwrap_or("unknown version") + ), + ), )?; write_minify("search.js", static_files::SEARCH_JS)?; write_minify("settings.js", static_files::SETTINGS_JS)?; diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 2d4bfc62af68e..eb7cc9309f416 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -928,15 +928,24 @@ body.blur > :not(#help) { display: block; margin-right: 0.5rem; } -#help > div > span { +#help span.top, #help span.bottom { text-align: center; display: block; - margin: 10px 0; font-size: 18px; - border-bottom: 1px solid #ccc; + +} +#help span.top { + text-align: center; + display: block; + margin: 10px 0; + border-bottom: 1px solid; padding-bottom: 4px; margin-bottom: 6px; } +#help span.bottom { + clear: both; + border-top: 1px solid; +} #help dd { margin: 5px 35px; } #help .infos { padding-left: 0; } #help h1, #help h2 { margin-top: 0; } diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index f9ddef4120bbe..b05caa5fd87ad 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -286,8 +286,8 @@ details.undocumented > summary::before { border-radius: 4px; } -#help > div > span { - border-bottom-color: #5c6773; +#help span.bottom, #help span.top { + border-color: #5c6773; } .since { diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index d9348be6994e2..d2e54070acd68 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -242,8 +242,8 @@ details.undocumented > summary::before { border-color: #bfbfbf; } -#help > div > span { - border-bottom-color: #bfbfbf; +#help span.bottom, #help span.top { + border-color: #bfbfbf; } #help dt { diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 0ffe5929ea593..25d810560c146 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -232,8 +232,8 @@ details.undocumented > summary::before { border-color: #bfbfbf; } -#help > div > span { - border-bottom-color: #bfbfbf; +#help span.bottom, #help span.top { + border-color: #bfbfbf; } .since { diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 1eebd39256459..e396fd9d288db 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -911,6 +911,7 @@ function hideThemeButtonState() { }); var book_info = document.createElement("span"); + book_info.className = "top"; book_info.innerHTML = "You can find more information in \ the rustdoc book."; @@ -961,6 +962,14 @@ function hideThemeButtonState() { container.appendChild(div_shortcuts); container.appendChild(div_infos); + var rustdoc_version = document.createElement("span"); + rustdoc_version.className = "bottom"; + var rustdoc_version_code = document.createElement("code"); + rustdoc_version_code.innerText = "/* INSERT RUSTDOC_VERSION HERE */"; + rustdoc_version.appendChild(rustdoc_version_code); + + container.appendChild(rustdoc_version); + popup.appendChild(container); insertAfter(popup, searchState.outputElement()); // So that it's only built once and then it'll do nothing when called!