diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 4686b4989ae52..1cd4ddad5783a 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1138,9 +1138,7 @@ impl<'a> State<'a> { fn print_expr_anon_const(&mut self, anon_const: &hir::AnonConst) { self.ibox(INDENT_UNIT); self.s.word_space("const"); - self.s.word("{"); self.print_anon_const(anon_const); - self.s.word("}"); self.end() } diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index f873358ff9fdd..835f75ec8ef06 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -2,12 +2,12 @@ use super::ObjectSafetyViolation; use crate::infer::InferCtxt; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::Symbol; -use rustc_span::Span; +use rustc_span::{MultiSpan, Span}; use std::fmt; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { @@ -54,10 +54,11 @@ pub fn report_object_safety_error( "the trait `{}` cannot be made into an object", trait_str ); - err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); + err.span_label(span, format!("`{}` cannot be made into an object", trait_str)); let mut reported_violations = FxHashSet::default(); - let mut had_span_label = false; + let mut multi_span = vec![]; + let mut messages = vec![]; for violation in violations { if let ObjectSafetyViolation::SizedSelf(sp) = &violation { if !sp.is_empty() { @@ -71,31 +72,37 @@ pub fn report_object_safety_error( let msg = if trait_span.is_none() || spans.is_empty() { format!("the trait cannot be made into an object because {}", violation.error_msg()) } else { - had_span_label = true; format!("...because {}", violation.error_msg()) }; if spans.is_empty() { err.note(&msg); } else { for span in spans { - err.span_label(span, &msg); + multi_span.push(span); + messages.push(msg.clone()); } } - match (trait_span, violation.solution()) { - (Some(_), Some((note, None))) => { - err.help(¬e); - } - (Some(_), Some((note, Some((sugg, span))))) => { - err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable); - } + if trait_span.is_some() { // Only provide the help if its a local trait, otherwise it's not actionable. - _ => {} + violation.solution(&mut err); } } } - if let (Some(trait_span), true) = (trait_span, had_span_label) { - err.span_label(trait_span, "this trait cannot be made into an object..."); + let has_multi_span = !multi_span.is_empty(); + let mut note_span = MultiSpan::from_spans(multi_span.clone()); + if let (Some(trait_span), true) = (trait_span, has_multi_span) { + note_span + .push_span_label(trait_span, "this trait cannot be made into an object...".to_string()); } + for (span, msg) in multi_span.into_iter().zip(messages.into_iter()) { + note_span.push_span_label(span, msg); + } + err.span_note( + note_span, + "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 \ + ", + ); if tcx.sess.trait_methods_not_found.borrow().contains(&span) { // Avoid emitting error caused by non-existing method (#58734) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index b38efedbf607e..fa40995407f4f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -821,9 +821,6 @@ pub struct LocalDecl<'tcx> { /// flag drop flags to avoid triggering this check as they are introduced /// after typeck. /// - /// Unsafety checking will also ignore dereferences of these locals, - /// so they can be used for raw pointers only used in a desugaring. - /// /// This should be sound because the drop flags are fully algebraic, and /// therefore don't affect the OIBIT or outlives properties of the /// generator. @@ -1010,13 +1007,13 @@ impl<'tcx> LocalDecl<'tcx> { } /// Returns `Some` if this is a reference to a static item that is used to - /// access that static + /// access that static. pub fn is_ref_to_static(&self) -> bool { matches!(self.local_info, Some(box LocalInfo::StaticRef { .. })) } - /// Returns `Some` if this is a reference to a static item that is used to - /// access that static + /// Returns `Some` if this is a reference to a thread-local static item that is used to + /// access that static. pub fn is_ref_to_thread_local(&self) -> bool { match self.local_info { Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local, diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index b9e4f6fb12eb1..f0bfdae261c64 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -152,10 +152,14 @@ impl<'tcx> Rvalue<'tcx> { tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count)) } Rvalue::ThreadLocalRef(did) => { + let static_ty = tcx.type_of(did); if tcx.is_mutable_static(did) { - tcx.mk_mut_ptr(tcx.type_of(did)) + tcx.mk_mut_ptr(static_ty) + } else if tcx.is_foreign_item(did) { + tcx.mk_imm_ptr(static_ty) } else { - tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did)) + // FIXME: These things don't *really* have 'static lifetime. + tcx.mk_imm_ref(tcx.lifetimes.re_static, static_ty) } } Rvalue::Ref(reg, bk, ref place) => { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 1dd6d590d908f..26962aa108342 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -13,6 +13,7 @@ use crate::mir::interpret::ErrorHandled; use crate::ty::subst::SubstsRef; use crate::ty::{self, AdtKind, Ty, TyCtxt}; +use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_span::symbol::Symbol; @@ -646,13 +647,13 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(), ObjectSafetyViolation::SupertraitSelf(ref spans) => { if spans.iter().any(|sp| *sp != DUMMY_SP) { - "it uses `Self` as a type parameter in this".into() + "it uses `Self` as a type parameter".into() } else { "it cannot use `Self` as a type parameter in a supertrait or `where`-clause" .into() } } - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => { + ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_, _, _), _) => { format!("associated function `{}` has no `self` parameter", name).into() } ObjectSafetyViolation::Method( @@ -686,32 +687,65 @@ impl ObjectSafetyViolation { } } - pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> { - Some(match *self { - ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => { - return None; + pub fn solution(&self, err: &mut DiagnosticBuilder<'_>) { + match *self { + ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {} + ObjectSafetyViolation::Method( + name, + MethodViolationCode::StaticMethod(sugg, self_span, has_args), + _, + ) => { + err.span_suggestion( + self_span, + &format!( + "consider turning `{}` into a method by giving it a `&self` argument", + name + ), + format!("&self{}", if has_args { ", " } else { "" }), + Applicability::MaybeIncorrect, + ); + match sugg { + Some((sugg, span)) => { + err.span_suggestion( + span, + &format!( + "alternatively, consider constraining `{}` so it does not apply to \ + trait objects", + name + ), + sugg.to_string(), + Applicability::MaybeIncorrect, + ); + } + None => { + err.help(&format!( + "consider turning `{}` into a method by giving it a `&self` \ + argument or constraining it so it does not apply to trait objects", + name + )); + } + } } - ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => ( - format!( - "consider turning `{}` into a method by giving it a `&self` argument or \ - constraining it so it does not apply to trait objects", - name - ), - sugg.map(|(sugg, sp)| (sugg.to_string(), sp)), - ), ObjectSafetyViolation::Method( name, MethodViolationCode::UndispatchableReceiver, span, - ) => ( - format!("consider changing method `{}`'s `self` parameter to be `&self`", name), - Some(("&Self".to_string(), span)), - ), + ) => { + err.span_suggestion( + span, + &format!( + "consider changing method `{}`'s `self` parameter to be `&self`", + name + ), + "&Self".to_string(), + Applicability::MachineApplicable, + ); + } ObjectSafetyViolation::AssocConst(name, _) | ObjectSafetyViolation::Method(name, ..) => { - (format!("consider moving `{}` to another trait", name), None) + err.help(&format!("consider moving `{}` to another trait", name)); } - }) + } } pub fn spans(&self) -> SmallVec<[Span; 1]> { @@ -735,7 +769,7 @@ impl ObjectSafetyViolation { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] pub enum MethodViolationCode { /// e.g., `fn foo()` - StaticMethod(Option<(&'static str, Span)>), + StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */), /// e.g., `fn foo(&self, x: Self)` ReferencesSelfInput(usize), diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b0f0f0ba57fad..4a20e1c32f99e 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -529,8 +529,12 @@ impl<'tcx> TyCtxt<'tcx> { // Make sure that any constants in the static's type are evaluated. let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id)); + // Make sure that accesses to unsafe statics end up using raw pointers. + // For thread-locals, this needs to be kept in sync with `Rvalue::ty`. if self.is_mutable_static(def_id) { self.mk_mut_ptr(static_ty) + } else if self.is_foreign_item(def_id) { + self.mk_imm_ptr(static_ty) } else { self.mk_imm_ref(self.lifetimes.re_erased, static_ty) } diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index 7309a4129e468..3d68b862df2d0 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -204,6 +204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if let [] = proj_base { let decl = &self.body.local_decls[place.local]; if decl.internal { + // If the projection root is an artifical local that we introduced when + // desugaring `static`, give a more specific error message + // (avoid the general "raw pointer" clause below, that would only be confusing). if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info { if self.tcx.is_mutable_static(def_id) { self.require_unsafe( diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 1860f1238c4b5..5176db82d3b41 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -548,7 +548,11 @@ impl<'a> Parser<'a> { fn check_inline_const(&mut self) -> bool { self.check_keyword(kw::Const) - && self.look_ahead(1, |t| t == &token::OpenDelim(DelimToken::Brace)) + && self.look_ahead(1, |t| match t.kind { + token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)), + token::OpenDelim(DelimToken::Brace) => true, + _ => false, + }) } /// Checks to see if the next token is either `+` or `+=`. diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 0e43f1655ddb2..d1647e686a84f 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -13,7 +13,7 @@ use super::elaborate_predicates; use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; -use rustc_errors::{Applicability, FatalError}; +use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst}; @@ -21,7 +21,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitor, WithConstnes use rustc_middle::ty::{Predicate, ToPredicate}; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; -use rustc_span::Span; +use rustc_span::{MultiSpan, Span}; use smallvec::SmallVec; use std::array; @@ -100,49 +100,7 @@ fn object_safety_violations_for_trait( span, ) = violation { - // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. - // It's also hard to get a use site span, so we use the method definition span. - tcx.struct_span_lint_hir( - WHERE_CLAUSES_OBJECT_SAFETY, - hir::CRATE_HIR_ID, - *span, - |lint| { - let mut err = lint.build(&format!( - "the trait `{}` cannot be made into an object", - tcx.def_path_str(trait_def_id) - )); - let node = tcx.hir().get_if_local(trait_def_id); - let msg = if let Some(hir::Node::Item(item)) = node { - err.span_label( - item.ident.span, - "this trait cannot be made into an object...", - ); - format!("...because {}", violation.error_msg()) - } else { - format!( - "the trait cannot be made into an object because {}", - violation.error_msg() - ) - }; - err.span_label(*span, &msg); - match (node, violation.solution()) { - (Some(_), Some((note, None))) => { - err.help(¬e); - } - (Some(_), Some((note, Some((sugg, span))))) => { - err.span_suggestion( - span, - ¬e, - sugg, - Applicability::MachineApplicable, - ); - } - // Only provide the help if its a local trait, otherwise it's not actionable. - _ => {} - } - err.emit(); - }, - ); + lint_object_unsafe_trait(tcx, *span, trait_def_id, violation); false } else { true @@ -180,6 +138,51 @@ fn object_safety_violations_for_trait( violations } +/// Lint object-unsafe trait. +fn lint_object_unsafe_trait( + tcx: TyCtxt<'_>, + span: Span, + trait_def_id: DefId, + violation: &ObjectSafetyViolation, +) { + // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. + // It's also hard to get a use site span, so we use the method definition span. + tcx.struct_span_lint_hir(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |lint| { + let mut err = lint.build(&format!( + "the trait `{}` cannot be made into an object", + tcx.def_path_str(trait_def_id) + )); + let node = tcx.hir().get_if_local(trait_def_id); + let mut spans = MultiSpan::from_span(span); + if let Some(hir::Node::Item(item)) = node { + spans.push_span_label( + item.ident.span, + "this trait cannot be made into an object...".into(), + ); + spans.push_span_label(span, format!("...because {}", violation.error_msg())); + } else { + spans.push_span_label( + span, + format!( + "the trait cannot be made into an object because {}", + violation.error_msg() + ), + ); + }; + err.span_note( + spans, + "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 \ + ", + ); + if node.is_some() { + // Only provide the help if its a local trait, otherwise it's not + violation.solution(&mut err); + } + err.emit(); + }); +} + fn sized_trait_bound_spans<'tcx>( tcx: TyCtxt<'tcx>, bounds: hir::GenericBounds<'tcx>, @@ -385,6 +388,8 @@ fn virtual_call_violation_for_method<'tcx>( trait_def_id: DefId, method: &ty::AssocItem, ) -> Option { + let sig = tcx.fn_sig(method.def_id); + // The method's first parameter must be named `self` if !method.fn_has_self_parameter { // We'll attempt to provide a structured suggestion for `Self: Sized`. @@ -395,11 +400,21 @@ fn virtual_call_violation_for_method<'tcx>( [.., pred] => (", Self: Sized", pred.span().shrink_to_hi()), }, ); - return Some(MethodViolationCode::StaticMethod(sugg)); + // Get the span pointing at where the `self` receiver should be. + let sm = tcx.sess.source_map(); + let self_span = method.ident.span.to(tcx + .hir() + .span_if_local(method.def_id) + .unwrap_or_else(|| sm.next_point(method.ident.span)) + .shrink_to_hi()); + let self_span = sm.span_through_char(self_span, '(').shrink_to_hi(); + return Some(MethodViolationCode::StaticMethod( + sugg, + self_span, + !sig.inputs().skip_binder().is_empty(), + )); } - let sig = tcx.fn_sig(method.def_id); - for (i, input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() { if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) { return Some(MethodViolationCode::ReferencesSelfInput(i)); diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 2f3fb49717b9c..02268b11a7a8e 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -302,7 +302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true, ), hir::BinOpKind::Mul => ( - format!("cannot multiply `{}` to `{}`", rhs_ty, lhs_ty), + format!("cannot multiply `{}` by `{}`", lhs_ty, rhs_ty), Some("std::ops::Mul"), true, ), diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 92cbce96054b8..20c6ebd22928b 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -13,8 +13,6 @@ use super::node::{self, marker, ForceResult::*, Handle, NodeRef}; use super::search::{self, SearchResult::*}; use super::unwrap_unchecked; -use UnderflowResult::*; - mod entry; pub use entry::{Entry, OccupiedEntry, VacantEntry}; use Entry::*; @@ -1154,40 +1152,8 @@ impl BTreeMap { let mut right = Self::new(); let right_root = Self::ensure_is_owned(&mut right.root); - for _ in 0..left_root.height() { - right_root.push_internal_level(); - } - - { - let mut left_node = left_root.node_as_mut(); - let mut right_node = right_root.node_as_mut(); - - loop { - let mut split_edge = match search::search_node(left_node, key) { - // key is going to the right tree - Found(handle) => handle.left_edge(), - GoDown(handle) => handle, - }; - split_edge.move_suffix(&mut right_node); - - match (split_edge.force(), right_node.force()) { - (Internal(edge), Internal(node)) => { - left_node = edge.descend(); - right_node = node.first_edge().descend(); - } - (Leaf(_), Leaf(_)) => { - break; - } - _ => { - unreachable!(); - } - } - } - } - - left_root.fix_right_border(); - right_root.fix_left_border(); + left_root.split_off(right_root, key); if left_root.height() < right_root.height() { self.length = left_root.node_as_ref().calc_length(); @@ -2250,193 +2216,6 @@ impl BTreeMap { } } -impl<'a, K: 'a, V: 'a> Handle, K, V, marker::LeafOrInternal>, marker::KV> { - /// Removes a key/value-pair from the map, and returns that pair, as well as - /// the leaf edge corresponding to that former pair. - fn remove_kv_tracking( - self, - handle_emptied_internal_root: F, - ) -> ((K, V), Handle, K, V, marker::Leaf>, marker::Edge>) { - let (old_kv, mut pos, was_internal) = match self.force() { - Leaf(leaf) => { - let (old_kv, pos) = leaf.remove(); - (old_kv, pos, false) - } - Internal(mut internal) => { - // Replace the location freed in the internal node with an - // adjacent KV, and remove that adjacent KV from its leaf. - // Always choose the adjacent KV on the left side because - // it is typically faster to pop an element from the end - // of the KV arrays without needing to shift other elements. - - let key_loc = internal.kv_mut().0 as *mut K; - let val_loc = internal.kv_mut().1 as *mut V; - - let to_remove = internal.left_edge().descend().last_leaf_edge().left_kv().ok(); - let to_remove = unsafe { unwrap_unchecked(to_remove) }; - - let (kv, pos) = to_remove.remove(); - - let old_key = unsafe { mem::replace(&mut *key_loc, kv.0) }; - let old_val = unsafe { mem::replace(&mut *val_loc, kv.1) }; - - ((old_key, old_val), pos, true) - } - }; - - // Handle underflow - let mut cur_node = unsafe { ptr::read(&pos).into_node().forget_type() }; - let mut at_leaf = true; - while cur_node.len() < node::MIN_LEN { - match handle_underfull_node(cur_node) { - AtRoot => break, - Merged(edge, merged_with_left, offset) => { - // If we merged with our right sibling then our tracked - // position has not changed. However if we merged with our - // left sibling then our tracked position is now dangling. - if at_leaf && merged_with_left { - let idx = pos.idx() + offset; - let node = match unsafe { ptr::read(&edge).descend().force() } { - Leaf(leaf) => leaf, - Internal(_) => unreachable!(), - }; - pos = unsafe { Handle::new_edge(node, idx) }; - } - - let parent = edge.into_node(); - if parent.len() == 0 { - // The parent that was just emptied must be the root, - // because nodes on a lower level would not have been - // left with a single child. - handle_emptied_internal_root(); - break; - } else { - cur_node = parent.forget_type(); - at_leaf = false; - } - } - Stole(stole_from_left) => { - // Adjust the tracked position if we stole from a left sibling - if stole_from_left && at_leaf { - // SAFETY: This is safe since we just added an element to our node. - unsafe { - pos.move_next_unchecked(); - } - } - break; - } - } - } - - // If we deleted from an internal node then we need to compensate for - // the earlier swap and adjust the tracked position to point to the - // next element. - if was_internal { - pos = unsafe { unwrap_unchecked(pos.next_kv().ok()).next_leaf_edge() }; - } - - (old_kv, pos) - } -} - -impl node::Root { - /// Removes empty levels on the top, but keep an empty leaf if the entire tree is empty. - fn fix_top(&mut self) { - while self.height() > 0 && self.node_as_ref().len() == 0 { - self.pop_internal_level(); - } - } - - fn fix_right_border(&mut self) { - self.fix_top(); - - { - let mut cur_node = self.node_as_mut(); - - while let Internal(node) = cur_node.force() { - let mut last_kv = node.last_kv(); - - if last_kv.can_merge() { - cur_node = last_kv.merge().descend(); - } else { - let right_len = last_kv.reborrow().right_edge().descend().len(); - // `MINLEN + 1` to avoid readjust if merge happens on the next level. - if right_len < node::MIN_LEN + 1 { - last_kv.bulk_steal_left(node::MIN_LEN + 1 - right_len); - } - cur_node = last_kv.right_edge().descend(); - } - } - } - - self.fix_top(); - } - - /// The symmetric clone of `fix_right_border`. - fn fix_left_border(&mut self) { - self.fix_top(); - - { - let mut cur_node = self.node_as_mut(); - - while let Internal(node) = cur_node.force() { - let mut first_kv = node.first_kv(); - - if first_kv.can_merge() { - cur_node = first_kv.merge().descend(); - } else { - let left_len = first_kv.reborrow().left_edge().descend().len(); - if left_len < node::MIN_LEN + 1 { - first_kv.bulk_steal_right(node::MIN_LEN + 1 - left_len); - } - cur_node = first_kv.left_edge().descend(); - } - } - } - - self.fix_top(); - } -} - -enum UnderflowResult<'a, K, V> { - AtRoot, - Merged(Handle, K, V, marker::Internal>, marker::Edge>, bool, usize), - Stole(bool), -} - -fn handle_underfull_node<'a, K: 'a, V: 'a>( - node: NodeRef, K, V, marker::LeafOrInternal>, -) -> UnderflowResult<'_, K, V> { - let parent = match node.ascend() { - Ok(parent) => parent, - Err(_) => return AtRoot, - }; - - // Prefer the left KV if it exists. Merging with the left side is faster, - // since merging happens towards the left and `node` has fewer elements. - // Stealing from the left side is faster, since we can pop from the end of - // the KV arrays. - let (is_left, mut handle) = match parent.left_kv() { - Ok(left) => (true, left), - Err(parent) => { - let right = unsafe { unwrap_unchecked(parent.right_kv().ok()) }; - (false, right) - } - }; - - if handle.can_merge() { - let offset = if is_left { handle.reborrow().left_edge().descend().len() + 1 } else { 0 }; - Merged(handle.merge(), is_left, offset) - } else { - if is_left { - handle.steal_left(); - } else { - handle.steal_right(); - } - Stole(is_left) - } -} - impl> Iterator for MergeIter { type Item = (K, V); diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs index ecbdacda4b618..bcc50ed561587 100644 --- a/library/alloc/src/collections/btree/mod.rs +++ b/library/alloc/src/collections/btree/mod.rs @@ -2,8 +2,10 @@ mod borrow; pub mod map; mod navigate; mod node; +mod remove; mod search; pub mod set; +mod split; #[doc(hidden)] trait Recover { diff --git a/library/alloc/src/collections/btree/remove.rs b/library/alloc/src/collections/btree/remove.rs new file mode 100644 index 0000000000000..9733b7d608425 --- /dev/null +++ b/library/alloc/src/collections/btree/remove.rs @@ -0,0 +1,132 @@ +use super::node::{self, marker, ForceResult, Handle, NodeRef}; +use super::unwrap_unchecked; +use core::mem; +use core::ptr; + +impl<'a, K: 'a, V: 'a> Handle, K, V, marker::LeafOrInternal>, marker::KV> { + /// Removes a key/value-pair from the map, and returns that pair, as well as + /// the leaf edge corresponding to that former pair. + pub fn remove_kv_tracking( + self, + handle_emptied_internal_root: F, + ) -> ((K, V), Handle, K, V, marker::Leaf>, marker::Edge>) { + let (old_kv, mut pos, was_internal) = match self.force() { + ForceResult::Leaf(leaf) => { + let (old_kv, pos) = leaf.remove(); + (old_kv, pos, false) + } + ForceResult::Internal(mut internal) => { + // Replace the location freed in the internal node with an + // adjacent KV, and remove that adjacent KV from its leaf. + // Always choose the adjacent KV on the left side because + // it is typically faster to pop an element from the end + // of the KV arrays without needing to shift other elements. + + let key_loc = internal.kv_mut().0 as *mut K; + let val_loc = internal.kv_mut().1 as *mut V; + + let to_remove = internal.left_edge().descend().last_leaf_edge().left_kv().ok(); + let to_remove = unsafe { unwrap_unchecked(to_remove) }; + + let (kv, pos) = to_remove.remove(); + + let old_key = unsafe { mem::replace(&mut *key_loc, kv.0) }; + let old_val = unsafe { mem::replace(&mut *val_loc, kv.1) }; + + ((old_key, old_val), pos, true) + } + }; + + // Handle underflow + let mut cur_node = unsafe { ptr::read(&pos).into_node().forget_type() }; + let mut at_leaf = true; + while cur_node.len() < node::MIN_LEN { + match handle_underfull_node(cur_node) { + UnderflowResult::AtRoot => break, + UnderflowResult::Merged(edge, merged_with_left, offset) => { + // If we merged with our right sibling then our tracked + // position has not changed. However if we merged with our + // left sibling then our tracked position is now dangling. + if at_leaf && merged_with_left { + let idx = pos.idx() + offset; + let node = match unsafe { ptr::read(&edge).descend().force() } { + ForceResult::Leaf(leaf) => leaf, + ForceResult::Internal(_) => unreachable!(), + }; + pos = unsafe { Handle::new_edge(node, idx) }; + } + + let parent = edge.into_node(); + if parent.len() == 0 { + // The parent that was just emptied must be the root, + // because nodes on a lower level would not have been + // left with a single child. + handle_emptied_internal_root(); + break; + } else { + cur_node = parent.forget_type(); + at_leaf = false; + } + } + UnderflowResult::Stole(stole_from_left) => { + // Adjust the tracked position if we stole from a left sibling + if stole_from_left && at_leaf { + // SAFETY: This is safe since we just added an element to our node. + unsafe { + pos.move_next_unchecked(); + } + } + break; + } + } + } + + // If we deleted from an internal node then we need to compensate for + // the earlier swap and adjust the tracked position to point to the + // next element. + if was_internal { + pos = unsafe { unwrap_unchecked(pos.next_kv().ok()).next_leaf_edge() }; + } + + (old_kv, pos) + } +} + +enum UnderflowResult<'a, K, V> { + AtRoot, + Merged(Handle, K, V, marker::Internal>, marker::Edge>, bool, usize), + Stole(bool), +} + +fn handle_underfull_node<'a, K: 'a, V: 'a>( + node: NodeRef, K, V, marker::LeafOrInternal>, +) -> UnderflowResult<'_, K, V> { + let parent = match node.ascend() { + Ok(parent) => parent, + Err(_) => return UnderflowResult::AtRoot, + }; + + // Prefer the left KV if it exists. Merging with the left side is faster, + // since merging happens towards the left and `node` has fewer elements. + // Stealing from the left side is faster, since we can pop from the end of + // the KV arrays. + let (is_left, mut handle) = match parent.left_kv() { + Ok(left) => (true, left), + Err(parent) => { + let right = unsafe { unwrap_unchecked(parent.right_kv().ok()) }; + (false, right) + } + }; + + if handle.can_merge() { + let offset = if is_left { handle.reborrow().left_edge().descend().len() + 1 } else { 0 }; + UnderflowResult::Merged(handle.merge(), is_left, offset) + } else { + if is_left { + handle.steal_left(); + } else { + handle.steal_right(); + } + UnderflowResult::Stole(is_left) + } +} diff --git a/library/alloc/src/collections/btree/split.rs b/library/alloc/src/collections/btree/split.rs new file mode 100644 index 0000000000000..0e6e213f6e87d --- /dev/null +++ b/library/alloc/src/collections/btree/split.rs @@ -0,0 +1,104 @@ +use super::node::{self, ForceResult::*, Root}; +use super::search::{self, SearchResult::*}; +use core::borrow::Borrow; + +impl Root { + pub fn split_off(&mut self, right_root: &mut Self, key: &Q) + where + K: Borrow, + { + debug_assert!(right_root.height() == 0); + debug_assert!(right_root.node_as_ref().len() == 0); + + let left_root = self; + for _ in 0..left_root.height() { + right_root.push_internal_level(); + } + + { + let mut left_node = left_root.node_as_mut(); + let mut right_node = right_root.node_as_mut(); + + loop { + let mut split_edge = match search::search_node(left_node, key) { + // key is going to the right tree + Found(handle) => handle.left_edge(), + GoDown(handle) => handle, + }; + + split_edge.move_suffix(&mut right_node); + + match (split_edge.force(), right_node.force()) { + (Internal(edge), Internal(node)) => { + left_node = edge.descend(); + right_node = node.first_edge().descend(); + } + (Leaf(_), Leaf(_)) => { + break; + } + _ => unreachable!(), + } + } + } + + left_root.fix_right_border(); + right_root.fix_left_border(); + } + + /// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty. + fn fix_top(&mut self) { + while self.height() > 0 && self.node_as_ref().len() == 0 { + self.pop_internal_level(); + } + } + + fn fix_right_border(&mut self) { + self.fix_top(); + + { + let mut cur_node = self.node_as_mut(); + + while let Internal(node) = cur_node.force() { + let mut last_kv = node.last_kv(); + + if last_kv.can_merge() { + cur_node = last_kv.merge().descend(); + } else { + let right_len = last_kv.reborrow().right_edge().descend().len(); + // `MINLEN + 1` to avoid readjust if merge happens on the next level. + if right_len < node::MIN_LEN + 1 { + last_kv.bulk_steal_left(node::MIN_LEN + 1 - right_len); + } + cur_node = last_kv.right_edge().descend(); + } + } + } + + self.fix_top(); + } + + /// The symmetric clone of `fix_right_border`. + fn fix_left_border(&mut self) { + self.fix_top(); + + { + let mut cur_node = self.node_as_mut(); + + while let Internal(node) = cur_node.force() { + let mut first_kv = node.first_kv(); + + if first_kv.can_merge() { + cur_node = first_kv.merge().descend(); + } else { + let left_len = first_kv.reborrow().left_edge().descend().len(); + if left_len < node::MIN_LEN + 1 { + first_kv.bulk_steal_right(node::MIN_LEN + 1 - left_len); + } + cur_node = first_kv.left_edge().descend(); + } + } + } + + self.fix_top(); + } +} diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index 19f86ced5007c..92090d8e6fca7 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -302,7 +302,7 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } #[lang = "mul"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( - message = "cannot multiply `{Rhs}` to `{Self}`", + message = "cannot multiply `{Self}` by `{Rhs}`", label = "no implementation for `{Self} * {Rhs}`" )] #[doc(alias = "*")] @@ -826,7 +826,7 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } #[lang = "mul_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] #[rustc_on_unimplemented( - message = "cannot multiply-assign `{Rhs}` to `{Self}`", + message = "cannot multiply-assign `{Self}` by `{Rhs}`", label = "no implementation for `{Self} *= {Rhs}`" )] #[doc(alias = "*")] diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 9f0284d5d9542..b73cd046e5a65 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -781,6 +781,34 @@ impl<'a, T: ?Sized> Pin<&'a mut T> { } } +impl Pin<&'static T> { + /// Get a pinned reference from a static reference. + /// + /// This is safe, because `T` is borrowed for the `'static` lifetime, which + /// never ends. + #[unstable(feature = "pin_static_ref", issue = "none")] + #[rustc_const_unstable(feature = "const_pin", issue = "76654")] + pub const fn static_ref(r: &'static T) -> Pin<&'static T> { + // SAFETY: The 'static borrow guarantees the data will not be + // moved/invalidated until it gets dropped (which is never). + unsafe { Pin::new_unchecked(r) } + } +} + +impl Pin<&'static mut T> { + /// Get a pinned mutable reference from a static mutable reference. + /// + /// This is safe, because `T` is borrowed for the `'static` lifetime, which + /// never ends. + #[unstable(feature = "pin_static_ref", issue = "none")] + #[rustc_const_unstable(feature = "const_pin", issue = "76654")] + pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> { + // SAFETY: The 'static borrow guarantees the data will not be + // moved/invalidated until it gets dropped (which is never). + unsafe { Pin::new_unchecked(r) } + } +} + #[stable(feature = "pin", since = "1.33.0")] impl Deref for Pin

{ type Target = P::Target; diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 02a7362bb3b2e..b487b39952174 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -84,7 +84,7 @@ impl<'a> SourceCollector<'a> { }; // Remove the utf-8 BOM if any - if contents.starts_with("\u{feff}") { + if contents.starts_with('\u{feff}') { contents.drain(..3); } @@ -99,16 +99,15 @@ impl<'a> SourceCollector<'a> { href.push('/'); }); self.scx.ensure_dir(&cur)?; - let mut fname = p.file_name().expect("source has no filename").to_os_string(); + + let src_fname = p.file_name().expect("source has no filename").to_os_string(); + let mut fname = src_fname.clone(); fname.push(".html"); cur.push(&fname); href.push_str(&fname.to_string_lossy()); - let title = format!( - "{} -- source", - cur.file_name().expect("failed to get file name").to_string_lossy() - ); - let desc = format!("Source to the Rust file `{}`.", filename); + let title = format!("{} - source", src_fname.to_string_lossy()); + let desc = format!("Source of the Rust file `{}`.", filename); let page = layout::Page { title: &title, css_class: "source", diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir index 0d5760b4cd5c7..88d583b815adb 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir @@ -4,17 +4,17 @@ promoted[0] in FOO: &[&i32; 1] = { let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45 - let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + let mut _3: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 bb0: { - _3 = const {alloc2: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + _3 = const {alloc2: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 // ty::Const - // + ty: &i32 + // + ty: *const i32 // + val: Value(Scalar(alloc2)) // mir::Constant // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) } - _2 = _3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 + // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } + _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 return; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index a392334e0c955..82277b2a21cbe 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -7,7 +7,7 @@ let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45 - let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + let _5: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 scope 1 { } @@ -18,16 +18,16 @@ - StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 - StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45 - StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 -- _5 = const {alloc2: &i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 +- _5 = const {alloc2: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 // ty::Const -- // + ty: &i32 +- // + ty: *const i32 - // + val: Value(Scalar(alloc2)) + // + ty: &[&i32; 1] + // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 -- // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) } +- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } - _4 = &(*_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 - _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 - _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 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 a8a8d01ed78fb..7b4594108246b 100644 --- a/src/test/ui/associated-consts/associated-const-in-trait.stderr +++ b/src/test/ui/associated-consts/associated-const-in-trait.stderr @@ -1,15 +1,17 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/associated-const-in-trait.rs:9:6 | -LL | trait Trait { - | ----- this trait cannot be made into an object... -LL | const N: usize; - | - ...because it contains this associated `const` -... LL | impl dyn Trait { - | ^^^^^^^^^ the trait `Trait` cannot be made into an object + | ^^^^^^^^^ `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 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +LL | const N: usize; + | ^ ...because it contains this associated `const` 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 98b545c6e0e78..92d74e38cfa8d 100644 --- a/src/test/ui/associated-item/issue-48027.stderr +++ b/src/test/ui/associated-item/issue-48027.stderr @@ -1,15 +1,17 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-48027.rs:6:6 | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | const X: usize; - | - ...because it contains this associated `const` -... LL | impl dyn Bar {} - | ^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^ `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 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` error[E0283]: type annotations needed --> $DIR/issue-48027.rs:3:32 diff --git a/src/test/ui/binop/binop-mul-bool.rs b/src/test/ui/binop/binop-mul-bool.rs index 27b2f8bb3ff30..41494c7a017ed 100644 --- a/src/test/ui/binop/binop-mul-bool.rs +++ b/src/test/ui/binop/binop-mul-bool.rs @@ -1,3 +1,3 @@ -// error-pattern:cannot multiply `bool` to `bool` +// error-pattern:cannot multiply `bool` by `bool` fn main() { let x = true * false; } diff --git a/src/test/ui/binop/binop-mul-bool.stderr b/src/test/ui/binop/binop-mul-bool.stderr index 859c44a859e85..8b5cde63c9991 100644 --- a/src/test/ui/binop/binop-mul-bool.stderr +++ b/src/test/ui/binop/binop-mul-bool.stderr @@ -1,4 +1,4 @@ -error[E0369]: cannot multiply `bool` to `bool` +error[E0369]: cannot multiply `bool` by `bool` --> $DIR/binop-mul-bool.rs:3:26 | LL | fn main() { let x = true * false; } diff --git a/src/test/ui/binop/binop-mul-i32-f32.rs b/src/test/ui/binop/binop-mul-i32-f32.rs new file mode 100644 index 0000000000000..d18be51a45f6f --- /dev/null +++ b/src/test/ui/binop/binop-mul-i32-f32.rs @@ -0,0 +1,5 @@ +fn foo(x: i32, y: f32) -> f32 { + x * y //~ ERROR cannot multiply `i32` by `f32` +} + +fn main() {} diff --git a/src/test/ui/binop/binop-mul-i32-f32.stderr b/src/test/ui/binop/binop-mul-i32-f32.stderr new file mode 100644 index 0000000000000..4a67fe2379b8d --- /dev/null +++ b/src/test/ui/binop/binop-mul-i32-f32.stderr @@ -0,0 +1,11 @@ +error[E0277]: cannot multiply `i32` by `f32` + --> $DIR/binop-mul-i32-f32.rs:2:7 + | +LL | x * y + | ^ no implementation for `i32 * f32` + | + = help: the trait `Mul` is not implemented for `i32` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. 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 cd18a013628c2..a2b779e29540b 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 @@ -1,14 +1,17 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:24 | -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... LL | impl NotObjectSafe for dyn NotObjectSafe { } - | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | ^^^^^^^^^^^^^^^^^ `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 + | +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... error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index a8b160bbb2c3d..68734cd4ccd6b 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -14,9 +14,10 @@ error[E0038]: the trait `Copy` cannot be made into an object --> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12 | LL | let _: &Copy + 'static; - | ^^^^^ the trait `Copy` cannot be made into an object + | ^^^^^ `Copy` cannot be made into an object | = note: the trait cannot be made into an object because it requires `Self: Sized` + = 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 error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr index f323a9904557a..513fda3097c14 100644 --- a/src/test/ui/error-codes/E0033-teach.stderr +++ b/src/test/ui/error-codes/E0033-teach.stderr @@ -7,15 +7,21 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033-teach.rs:8:20 | +LL | let trait_obj: &dyn SomeTrait = SomeTrait; + | ^^^^^^^^^^^^^^ `SomeTrait` cannot be made into an object + | +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/E0033-teach.rs:4:8 + | LL | trait SomeTrait { | --------- this trait cannot be made into an object... LL | fn foo(); - | --- ...because associated function `foo` has no `self` parameter -... -LL | let trait_obj: &dyn SomeTrait = SomeTrait; - | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object + | ^^^ ...because associated function `foo` has no `self` parameter +help: consider turning `foo` into a method by giving it a `&self` argument | -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn foo(&self); + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() where Self: Sized; | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr index 84481ff16c07e..fc1248440d043 100644 --- a/src/test/ui/error-codes/E0033.stderr +++ b/src/test/ui/error-codes/E0033.stderr @@ -7,15 +7,21 @@ LL | let trait_obj: &dyn SomeTrait = SomeTrait; error[E0038]: the trait `SomeTrait` cannot be made into an object --> $DIR/E0033.rs:6:20 | +LL | let trait_obj: &dyn SomeTrait = SomeTrait; + | ^^^^^^^^^^^^^^ `SomeTrait` cannot be made into an object + | +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/E0033.rs:2:8 + | LL | trait SomeTrait { | --------- this trait cannot be made into an object... LL | fn foo(); - | --- ...because associated function `foo` has no `self` parameter -... -LL | let trait_obj: &dyn SomeTrait = SomeTrait; - | ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object + | ^^^ ...because associated function `foo` has no `self` parameter +help: consider turning `foo` into a method by giving it a `&self` argument | -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn foo(&self); + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() where Self: Sized; | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index 638e924b0eb43..eb68a6298d1ac 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -1,15 +1,17 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/E0038.rs:5:16 | -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 -... LL | fn call_foo(x: Box) { - | ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object + | ^^^^^^^^^^^^^^ `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 + | +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 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 e3272e8849f9b..b61d560445582 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 @@ -1,26 +1,35 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 | +LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { + | ^^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object + | +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:4:23 + | LL | trait NonObjectSafe1: Sized {} - | -------------- ----- ...because it requires `Self: Sized` + | -------------- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { - | ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object error[E0038]: the trait `NonObjectSafe2` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:36 | +LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe2` cannot be made into an object + | +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:7:8 + | LL | trait NonObjectSafe2 { | -------------- this trait cannot be made into an object... LL | fn static_fn() {} - | --------- ...because associated function `static_fn` has no `self` parameter -... -LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object + | ^^^^^^^^^ ...because associated function `static_fn` has no `self` parameter +help: consider turning `static_fn` into a method by giving it a `&self` argument | -help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn static_fn(&self) {} + | ^^^^^ +help: alternatively, consider constraining `static_fn` so it does not apply to trait objects | LL | fn static_fn() where Self: Sized {} | ^^^^^^^^^^^^^^^^^ @@ -28,39 +37,46 @@ LL | fn static_fn() where Self: Sized {} error[E0038]: the trait `NonObjectSafe3` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 | -LL | trait NonObjectSafe3 { - | -------------- this trait cannot be made into an object... -LL | fn foo(&self); - | --- ...because method `foo` has generic type parameters -... LL | fn takes_non_object_safe_box(obj: Box) { - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^ `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 + | +LL | trait NonObjectSafe3 { + | -------------- this trait cannot be made into an object... +LL | fn foo(&self); + | ^^^ ...because method `foo` has generic type parameters error[E0038]: the trait `NonObjectSafe4` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35 | -LL | trait NonObjectSafe4 { - | -------------- this trait cannot be made into an object... -LL | fn foo(&self, &Self); - | ----- ...because method `foo` references the `Self` type in this parameter -... LL | fn return_non_object_safe_rc() -> std::rc::Rc { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `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:19 + | +LL | trait NonObjectSafe4 { + | -------------- this trait cannot be made into an object... +LL | fn foo(&self, &Self); + | ^^^^^ ...because method `foo` references the `Self` type in this parameter error[E0038]: the trait `NonObjectSafe1` cannot be made into an object --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16 | +LL | impl Trait for dyn NonObjectSafe1 {} + | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object + | +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:4:23 + | LL | trait NonObjectSafe1: Sized {} - | -------------- ----- ...because it requires `Self: Sized` + | -------------- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | impl Trait for dyn NonObjectSafe1 {} - | ^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object error: aborting due to 5 previous errors diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 9df5188bbdd08..2f3726bdb33a8 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -1,15 +1,21 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13 | +LL | fn car() -> dyn NotObjectSafe { + | ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object + | +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-in-return-position-dyn-trait.rs:3:8 + | LL | trait NotObjectSafe { | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; - | --- ...because associated function `foo` has no `self` parameter -... -LL | fn car() -> dyn NotObjectSafe { - | ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | ^^^ ...because associated function `foo` has no `self` parameter +help: consider turning `foo` into a method by giving it a `&self` argument | -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn foo(&self) -> Self; + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() -> Self where Self: Sized; | ^^^^^^^^^^^^^^^^^ @@ -17,15 +23,21 @@ LL | fn foo() -> Self where Self: Sized; error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 | +LL | fn cat() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object + | +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-in-return-position-dyn-trait.rs:3:8 + | LL | trait NotObjectSafe { | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; - | --- ...because associated function `foo` has no `self` parameter -... -LL | fn cat() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + | ^^^ ...because associated function `foo` has no `self` parameter +help: consider turning `foo` into a method by giving it a `&self` argument | -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn foo(&self) -> Self; + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() -> Self where Self: Sized; | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/inline-const/const-expr-macro.rs b/src/test/ui/inline-const/const-expr-macro.rs new file mode 100644 index 0000000000000..66b58571751ce --- /dev/null +++ b/src/test/ui/inline-const/const-expr-macro.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(inline_const)] +macro_rules! do_const_block{ + ($val:block) => { const $val } +} + +fn main() { + let s = do_const_block!({ 22 }); + assert_eq!(s, 22); +} diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index b3ba7aecad0db..86b530e85a80a 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -1,15 +1,17 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-18959.rs:11:11 | -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... -... LL | fn foo(b: &dyn Bar) { - | ^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ `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 + | +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... error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr index 63f0701974b8b..c3a5d3dfeee7d 100644 --- a/src/test/ui/issues/issue-19380.stderr +++ b/src/test/ui/issues/issue-19380.stderr @@ -1,15 +1,21 @@ error[E0038]: the trait `Qiz` cannot be made into an object --> $DIR/issue-19380.rs:11:9 | +LL | foos: &'static [&'static (dyn Qiz + 'static)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Qiz` cannot be made into an object + | +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-19380.rs:2:6 + | LL | trait Qiz { | --- this trait cannot be made into an object... LL | fn qiz(); - | --- ...because associated function `qiz` has no `self` parameter -... -LL | foos: &'static [&'static (dyn Qiz + 'static)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object + | ^^^ ...because associated function `qiz` has no `self` parameter +help: consider turning `qiz` into a method by giving it a `&self` argument | -help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn qiz(&self); + | ^^^^^ +help: alternatively, consider constraining `qiz` so it does not apply to trait objects | LL | fn qiz() where Self: Sized; | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr index 71a013248cf76..555d0ff0dc787 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/issues/issue-19538.stderr @@ -1,30 +1,34 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:15 | +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 + | LL | fn foo(&self, val: T); - | --- ...because method `foo` has generic type parameters + | ^^^ ...because method `foo` has generic type parameters ... LL | trait Bar: Foo { } | --- this trait cannot be made into an object... -... -LL | let test: &mut dyn Bar = &mut thing; - | ^^^^^^^^^^^^ the trait `Bar` 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 | +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 + | LL | fn foo(&self, val: T); - | --- ...because method `foo` has generic type parameters + | ^^^ ...because method `foo` has generic type parameters ... LL | trait Bar: Foo { } | --- this trait cannot be made into an object... -... -LL | let test: &mut dyn Bar = &mut thing; - | ^^^^^^^^^^ the trait `Bar` 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/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr index 0badf66ba7d86..1d7f252e5566d 100644 --- a/src/test/ui/issues/issue-20692.stderr +++ b/src/test/ui/issues/issue-20692.stderr @@ -1,27 +1,32 @@ error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:7:5 | +LL | &dyn Array; + | ^^^^^^^^^^ `Array` cannot be made into an object + | +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-20692.rs:1:14 + | LL | trait Array: Sized + Copy {} - | ----- ----- ---- ...because it requires `Self: Sized` + | ----- ^^^^^ ^^^^ ...because it requires `Self: Sized` | | | | | ...because it requires `Self: Sized` | this trait cannot be made into an object... -... -LL | &dyn Array; - | ^^^^^^^^^^ the trait `Array` cannot be made into an object error[E0038]: the trait `Array` cannot be made into an object --> $DIR/issue-20692.rs:4:13 | +LL | let _ = x + | ^ `Array` cannot be made into an object + | +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-20692.rs:1:14 + | LL | trait Array: Sized + Copy {} - | ----- ----- ---- ...because it requires `Self: Sized` + | ----- ^^^^^ ^^^^ ...because it requires `Self: Sized` | | | | | ...because it requires `Self: Sized` | this trait cannot be made into an object... -... -LL | let _ = x - | ^ the trait `Array` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Array>` for `&T` = note: required by cast to type `&dyn Array` diff --git a/src/test/ui/issues/issue-26056.stderr b/src/test/ui/issues/issue-26056.stderr index be438ef9ac7ba..2c873243fe9e4 100644 --- a/src/test/ui/issues/issue-26056.stderr +++ b/src/test/ui/issues/issue-26056.stderr @@ -1,13 +1,16 @@ error[E0038]: the trait `Map` cannot be made into an object --> $DIR/issue-26056.rs:20:13 | +LL | as &dyn Map; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Map` cannot be made into an object + | +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-26056.rs:9:12 + | LL | trait Map: MapLookup<::Key> { - | --- ----------------------------- ...because it uses `Self` as a type parameter in this + | --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... -... -LL | as &dyn Map; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Map` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28576.stderr b/src/test/ui/issues/issue-28576.stderr index 658199003c18d..203cd0630ebd0 100644 --- a/src/test/ui/issues/issue-28576.stderr +++ b/src/test/ui/issues/issue-28576.stderr @@ -1,16 +1,19 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-28576.rs:7:12 | -LL | pub trait Bar: Foo { - | --- ------------- - | | | | - | | | ...because it uses `Self` as a type parameter in this - | | ...because it uses `Self` as a type parameter in this - | this trait cannot be made into an object... -LL | fn new(&self, b: & LL | / dyn Bar LL | | - | |________________________^ the trait `Bar` cannot be made into an object + | |________________________^ `Bar` cannot be made into an object + | +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-28576.rs:5:16 + | +LL | pub trait Bar: Foo { + | --- ^^^^^^^^^^^^^ + | | | | + | | | ...because it uses `Self` as a type parameter + | | ...because it uses `Self` as a type parameter + | this trait cannot be made into an object... error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28837.rs b/src/test/ui/issues/issue-28837.rs index f874b00db0b49..9719c3afa68c1 100644 --- a/src/test/ui/issues/issue-28837.rs +++ b/src/test/ui/issues/issue-28837.rs @@ -7,7 +7,7 @@ fn main() { a - a; //~ ERROR cannot subtract `A` from `A` - a * a; //~ ERROR cannot multiply `A` to `A` + a * a; //~ ERROR cannot multiply `A` by `A` a / a; //~ ERROR cannot divide `A` by `A` diff --git a/src/test/ui/issues/issue-28837.stderr b/src/test/ui/issues/issue-28837.stderr index b63e168caf196..07f67bc3de79d 100644 --- a/src/test/ui/issues/issue-28837.stderr +++ b/src/test/ui/issues/issue-28837.stderr @@ -18,7 +18,7 @@ LL | a - a; | = note: an implementation of `std::ops::Sub` might be missing for `A` -error[E0369]: cannot multiply `A` to `A` +error[E0369]: cannot multiply `A` by `A` --> $DIR/issue-28837.rs:10:7 | LL | a * a; diff --git a/src/test/ui/issues/issue-35668.rs b/src/test/ui/issues/issue-35668.rs index 6f6dfb00f86b7..c970163fcab2c 100644 --- a/src/test/ui/issues/issue-35668.rs +++ b/src/test/ui/issues/issue-35668.rs @@ -1,6 +1,6 @@ fn func<'a, T>(a: &'a [T]) -> impl Iterator { a.iter().map(|a| a*a) - //~^ ERROR cannot multiply `&T` to `&T` + //~^ ERROR cannot multiply `&T` by `&T` } fn main() { diff --git a/src/test/ui/issues/issue-35668.stderr b/src/test/ui/issues/issue-35668.stderr index 600cacc23aef5..81a2bb88c89a3 100644 --- a/src/test/ui/issues/issue-35668.stderr +++ b/src/test/ui/issues/issue-35668.stderr @@ -1,4 +1,4 @@ -error[E0369]: cannot multiply `&T` to `&T` +error[E0369]: cannot multiply `&T` by `&T` --> $DIR/issue-35668.rs:2:23 | LL | a.iter().map(|a| a*a) diff --git a/src/test/ui/issues/issue-3820.rs b/src/test/ui/issues/issue-3820.rs index c090654623206..b987a90b28baa 100644 --- a/src/test/ui/issues/issue-3820.rs +++ b/src/test/ui/issues/issue-3820.rs @@ -11,5 +11,5 @@ impl Thing { fn main() { let u = Thing {x: 2}; let _v = u.mul(&3); // This is ok - let w = u * 3; //~ ERROR cannot multiply `{integer}` to `Thing` + let w = u * 3; //~ ERROR cannot multiply `Thing` by `{integer}` } diff --git a/src/test/ui/issues/issue-3820.stderr b/src/test/ui/issues/issue-3820.stderr index 8cc768237a948..84f8f9bd14786 100644 --- a/src/test/ui/issues/issue-3820.stderr +++ b/src/test/ui/issues/issue-3820.stderr @@ -1,4 +1,4 @@ -error[E0369]: cannot multiply `{integer}` to `Thing` +error[E0369]: cannot multiply `Thing` by `{integer}` --> $DIR/issue-3820.rs:14:15 | LL | let w = u * 3; diff --git a/src/test/ui/issues/issue-38404.stderr b/src/test/ui/issues/issue-38404.stderr index 50c5195dc93b0..d7721d7e69cd4 100644 --- a/src/test/ui/issues/issue-38404.stderr +++ b/src/test/ui/issues/issue-38404.stderr @@ -1,12 +1,16 @@ error[E0038]: the trait `B` cannot be made into an object --> $DIR/issue-38404.rs:3:15 | +LL | trait C: A> {} + | ^^^^^^^^^^^^^^^^^^^^^^ `B` cannot be made into an object + | +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-38404.rs:1:13 + | LL | trait A: std::ops::Add + Sized {} - | ------------------- ...because it uses `Self` as a type parameter in this + | ^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter LL | trait B: A {} | - this trait cannot be made into an object... -LL | trait C: A> {} - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `B` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr index 39a62b81c6cc1..d41488c15f737 100644 --- a/src/test/ui/issues/issue-38604.stderr +++ b/src/test/ui/issues/issue-38604.stderr @@ -1,25 +1,30 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:14:13 | +LL | let _f: Box = + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +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-38604.rs:2:22 + | LL | trait Foo where u32: Q { - | --- ------- ...because it uses `Self` as a type parameter in this + | --- ^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... -... -LL | let _f: Box = - | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:15:9 | +LL | Box::new(()); + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +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-38604.rs:2:22 + | LL | trait Foo where u32: Q { - | --- ------- ...because it uses `Self` as a type parameter in this + | --- ^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... -... -LL | Box::new(()); - | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | = 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/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index 03e3a7f227a23..93bd951d3fa1e 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -1,10 +1,8 @@ error: the trait `X` cannot be made into an object --> $DIR/issue-50781.rs:6:8 | -LL | trait X { - | - this trait cannot be made into an object... LL | fn foo(&self) where Self: Trait; - | ^^^ ...because method `foo` references the `Self` type in its `where` clause + | ^^^ | note: the lint level is defined here --> $DIR/issue-50781.rs:1:9 @@ -13,6 +11,13 @@ LL | #![deny(where_clauses_object_safety)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #51443 +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-50781.rs:6:8 + | +LL | trait X { + | - this trait cannot be made into an object... +LL | fn foo(&self) where Self: Trait; + | ^^^ ...because method `foo` references the `Self` type in its `where` clause = help: consider moving `foo` to another trait error: aborting due to previous error diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr index a6fd44d174399..64e56f8c79043 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -12,25 +12,30 @@ LL | take_param(&x); error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:19 | +LL | let z = &x as &dyn Foo; + | ^^^^^^^^ `Foo` cannot be made into an object + | +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/kindck-inherited-copy-bound.rs:10:13 + | LL | trait Foo : Copy { - | --- ---- ...because it requires `Self: Sized` + | --- ^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | let z = &x as &dyn Foo; - | ^^^^^^^^ the trait `Foo` cannot be made into an object error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | +LL | let z = &x as &dyn Foo; + | ^^ `Foo` cannot be made into an object + | +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/kindck-inherited-copy-bound.rs:10:13 + | LL | trait Foo : Copy { - | --- ---- ...because it requires `Self: Sized` + | --- ^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | let z = &x as &dyn Foo; - | ^^ the trait `Foo` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box<{integer}>` = note: required by cast to type `&dyn Foo` diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index bc7448a05e856..57f7551fd4018 100644 --- a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -12,14 +12,16 @@ LL | take_param(&x); error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/kindck-inherited-copy-bound.rs:28:13 | +LL | let z = &x as &dyn Foo; + | ^^ `Foo` cannot be made into an object + | +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/kindck-inherited-copy-bound.rs:10:13 + | LL | trait Foo : Copy { - | --- ---- ...because it requires `Self: Sized` + | --- ^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | let z = &x as &dyn Foo; - | ^^ the trait `Foo` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Foo>` for `&Box` = note: required by cast to type `&dyn Foo` diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs index 12d4826649d83..4be7420e33c17 100644 --- a/src/test/ui/mismatched_types/binops.rs +++ b/src/test/ui/mismatched_types/binops.rs @@ -1,7 +1,7 @@ fn main() { 1 + Some(1); //~ ERROR cannot add `Option<{integer}>` to `{integer}` 2 as usize - Some(1); //~ ERROR cannot subtract `Option<{integer}>` from `usize` - 3 * (); //~ ERROR cannot multiply `()` to `{integer}` + 3 * (); //~ ERROR cannot multiply `{integer}` by `()` 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` 5 < String::new(); //~ ERROR can't compare `{integer}` with `String` 6 == Ok(1); //~ ERROR can't compare `{integer}` with `std::result::Result<{integer}, _>` diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 227c7887fb01b..f2bfb12ee9c80 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -14,7 +14,7 @@ LL | 2 as usize - Some(1); | = help: the trait `Sub>` is not implemented for `usize` -error[E0277]: cannot multiply `()` to `{integer}` +error[E0277]: cannot multiply `{integer}` by `()` --> $DIR/binops.rs:4:7 | LL | 3 * (); 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 890acde35c4f8..35ec586892c05 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 @@ -1,15 +1,17 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-associated-consts.rs:12:30 | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | const X: usize; - | - ...because it contains this associated `const` -... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ `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 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` 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 c32038b5a27cc..d51734ed2316b 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 @@ -1,15 +1,17 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-associated-consts.rs:14:5 | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | const X: usize; - | - ...because it contains this associated `const` -... LL | t - | ^ the trait `Bar` cannot be made into an object + | ^ `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 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` = 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-bounds.stderr b/src/test/ui/object-safety/object-safety-bounds.stderr index af4548308631e..89c4f8ced79f6 100644 --- a/src/test/ui/object-safety/object-safety-bounds.stderr +++ b/src/test/ui/object-safety/object-safety-bounds.stderr @@ -1,13 +1,16 @@ error[E0038]: the trait `X` cannot be made into an object --> $DIR/object-safety-bounds.rs:7:11 | +LL | fn f() -> Box> { + | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object + | +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-bounds.rs:4:13 + | LL | trait X { | - this trait cannot be made into an object... LL | type U: PartialEq; - | --------------- ...because it uses `Self` as a type parameter in this -... -LL | fn f() -> Box> { - | ^^^^^^^^^^^^^^^^^^^ the trait `X` cannot be made into an object + | ^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter error: aborting due to previous error 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 9e70abbd32fc6..8d6094c514429 100644 --- a/src/test/ui/object-safety/object-safety-generics.curr.stderr +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -1,28 +1,32 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:18:30 | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | fn bar(&self, t: T); - | --- ...because method `bar` has generic type parameters -... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ `Bar` cannot be made into an object | = 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 +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 | LL | trait Bar { | --- this trait cannot be made into an object... LL | fn bar(&self, t: T); - | --- ...because method `bar` has generic type parameters -... + | ^^^ ...because method `bar` has generic type parameters + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:24:39 + | LL | fn make_bar_explicit(t: &T) -> &dyn Bar { - | ^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ `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 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters 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 7c104fa158dbb..3d2b2bb228cb5 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 @@ -1,30 +1,34 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:20:5 | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | fn bar(&self, t: T); - | --- ...because method `bar` has generic type parameters -... LL | t - | ^ the trait `Bar` cannot be made into an object + | ^ `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 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:26:5 | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | fn bar(&self, t: T); - | --- ...because method `bar` has generic type parameters -... LL | t as &dyn Bar - | ^ the trait `Bar` cannot be made into an object + | ^ `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 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters = 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-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr index fe9ca5b6fa4b7..0262d536246dc 100644 --- a/src/test/ui/object-safety/object-safety-issue-22040.stderr +++ b/src/test/ui/object-safety/object-safety-issue-22040.stderr @@ -1,13 +1,16 @@ error[E0038]: the trait `Expr` cannot be made into an object --> $DIR/object-safety-issue-22040.rs:12:23 | +LL | elements: Vec>, + | ^^^^^^^^^^^^^ `Expr` cannot be made into an object + | +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-issue-22040.rs:5:21 + | LL | trait Expr: Debug + PartialEq { - | ---- --------- ...because it uses `Self` as a type parameter in this + | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... -... -LL | elements: Vec>, - | ^^^^^^^^^^^^^ the trait `Expr` cannot be made into an object error: aborting due to previous error 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 4dbb27b425b32..336929702e6cd 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 @@ -1,28 +1,32 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:22:30 | -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 -... LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^^^^ `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 + | +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 error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:28:30 | -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 -... LL | fn make_baz(t: &T) -> &dyn Baz { - | ^^^^^^^^ the trait `Baz` cannot be made into an object + | ^^^^^^^^ `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 + | +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 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 ced26889ba082..6e7896e309cc6 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 @@ -1,30 +1,34 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:24:5 | -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 -... LL | t - | ^ the trait `Bar` cannot be made into an object + | ^ `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 + | +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 = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` = note: required by cast to type `&dyn Bar` error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:30:5 | -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 -... LL | t - | ^ the trait `Baz` cannot be made into an object + | ^ `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 + | +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 = 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/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr index f878cf8b46241..e00d6bb2f4a36 100644 --- a/src/test/ui/object-safety/object-safety-no-static.curr.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -1,15 +1,21 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety-no-static.rs:12:18 | +LL | fn diverges() -> Box { + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +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-no-static.rs:9:8 + | LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo() {} - | --- ...because associated function `foo` has no `self` parameter -... -LL | fn diverges() -> Box { - | ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | ^^^ ...because associated function `foo` has no `self` parameter +help: consider turning `foo` into a method by giving it a `&self` argument | -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn foo(&self) {} + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() where Self: Sized {} | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index 8e920697d8ffa..91a071f567813 100644 --- a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -1,17 +1,23 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety-no-static.rs:22:27 | +LL | let b: Box = Box::new(Bar); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +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-no-static.rs:9:8 + | LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo() {} - | --- ...because associated function `foo` has no `self` parameter -... -LL | let b: Box = Box::new(Bar); - | ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object - | + | ^^^ ...because associated function `foo` has no `self` parameter = note: required because of the requirements on the impl of `CoerceUnsized>` for `Box` = note: required by cast to type `Box` -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() where Self: Sized {} | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr index 2f605d8e904c5..71236c8e38438 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -1,13 +1,16 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:14:30 | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +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-sized-2.rs:9:18 + | LL | trait Bar | --- this trait cannot be made into an object... LL | where Self : Sized - | ----- ...because it requires `Self: Sized` -... -LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^^^ ...because it requires `Self: Sized` error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index cc0463f5d8767..b6e4903b0790b 100644 --- a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -1,14 +1,16 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized-2.rs:16:5 | +LL | t + | ^ `Bar` cannot be made into an object + | +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-sized-2.rs:9:18 + | LL | trait Bar | --- this trait cannot be made into an object... LL | where Self : Sized - | ----- ...because it requires `Self: Sized` -... -LL | t - | ^ the trait `Bar` cannot be made into an object - | + | ^^^^^ ...because it requires `Self: Sized` = 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-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr index 54f65c43d9cde..94b06ee934d44 100644 --- a/src/test/ui/object-safety/object-safety-sized.curr.stderr +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -1,13 +1,16 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:12:30 | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +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-sized.rs:8:13 + | LL | trait Bar : Sized { - | --- ----- ...because it requires `Self: Sized` + | --- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^^ the trait `Bar` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index aceacac2db3a2..645852c7e71c2 100644 --- a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -1,14 +1,16 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-sized.rs:14:5 | +LL | t + | ^ `Bar` cannot be made into an object + | +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-sized.rs:8:13 + | LL | trait Bar : Sized { - | --- ----- ...because it requires `Self: Sized` + | --- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | t - | ^ the trait `Bar` cannot be made into an object - | = 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-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr index ef7f6bacd1233..a106ab995b0a5 100644 --- a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -1,13 +1,16 @@ error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-supertrait-mentions-Self.rs:15:31 | +LL | fn make_baz(t: &T) -> &dyn Baz { + | ^^^^^^^ `Baz` cannot be made into an object + | +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-supertrait-mentions-Self.rs:8:13 + | LL | trait Baz : Bar { - | --- --------- ...because it uses `Self` as a type parameter in this + | --- ^^^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... -... -LL | fn make_baz(t: &T) -> &dyn Baz { - | ^^^^^^^ the trait `Baz` cannot be made into an object error: aborting due to previous error diff --git a/src/test/ui/pattern/pattern-tyvar-2.rs b/src/test/ui/pattern/pattern-tyvar-2.rs index 532df4fa0cbe8..7647c766ef914 100644 --- a/src/test/ui/pattern/pattern-tyvar-2.rs +++ b/src/test/ui/pattern/pattern-tyvar-2.rs @@ -1,6 +1,6 @@ enum Bar { T1((), Option>), T2, } fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } } -//~^ ERROR cannot multiply `{integer}` to `Vec` +//~^ ERROR cannot multiply `Vec` by `{integer}` fn main() { } diff --git a/src/test/ui/pattern/pattern-tyvar-2.stderr b/src/test/ui/pattern/pattern-tyvar-2.stderr index e205cd9015e49..121817e705690 100644 --- a/src/test/ui/pattern/pattern-tyvar-2.stderr +++ b/src/test/ui/pattern/pattern-tyvar-2.stderr @@ -1,4 +1,4 @@ -error[E0369]: cannot multiply `{integer}` to `Vec` +error[E0369]: cannot multiply `Vec` by `{integer}` --> $DIR/pattern-tyvar-2.rs:3:71 | LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } } diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index bd6e9d5950272..782cfeec4bcaf 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -2,12 +2,13 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object --> $DIR/issue-3907-2.rs:11:12 | LL | fn bar(_x: Foo) {} - | ^^^ the trait `issue_3907::Foo` cannot be made into an object - | - ::: $DIR/auxiliary/issue-3907.rs:2:8 + | ^^^ `issue_3907::Foo` cannot be made into an object + | +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/auxiliary/issue-3907.rs:2:8 | LL | fn bar(); - | --- the trait cannot be made into an object because associated function `bar` has no `self` parameter + | ^^^ the trait cannot be made into an object because associated function `bar` has no `self` parameter error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index 85da2c6eeb085..35a65facb57e6 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -1,31 +1,36 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:32 | -LL | trait Foo { - | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --------- - | | - | ...because method `foo`'s `self` parameter cannot be dispatched on - | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` + | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; - | ^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | ^^^^^^^^^^^ `Foo` cannot be made into an object + | +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/arbitrary-self-types-not-object-safe.rs:8:18 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo(self: &Rc) -> usize; + | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 | -LL | trait Foo { - | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --------- - | | - | ...because method `foo`'s `self` parameter cannot be dispatched on - | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` + | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; - | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +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/arbitrary-self-types-not-object-safe.rs:8:18 | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo(self: &Rc) -> usize; + | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on = note: required because of the requirements on the impl of `CoerceUnsized>` for `Rc` = note: required by cast to type `Rc` diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index c4cde2c356103..a74752cf840f2 100644 --- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -1,17 +1,19 @@ error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 | -LL | trait Foo { - | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; - | --------- - | | - | ...because method `foo`'s `self` parameter cannot be dispatched on - | help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` + | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` ... LL | let x = Rc::new(5usize) as Rc; - | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object + | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +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/arbitrary-self-types-not-object-safe.rs:8:18 | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo(self: &Rc) -> usize; + | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on = note: required because of the requirements on the impl of `CoerceUnsized>` for `Rc` = note: required by cast to type `Rc` 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 c3cfad70bf430..797406f869fe6 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -1,29 +1,34 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/object-unsafe-trait-references-self.rs:6:11 | -LL | trait Trait { - | ----- this trait cannot be made into an object... -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 -... LL | fn bar(x: &dyn Trait) {} - | ^^^^^^^^^^ the trait `Trait` cannot be made into an object + | ^^^^^^^^^^ `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 + | +LL | trait Trait { + | ----- this trait cannot be made into an object... +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 error[E0038]: the trait `Other` cannot be made into an object --> $DIR/object-unsafe-trait-references-self.rs:10:11 | +LL | fn foo(x: &dyn Other) {} + | ^^^^^^^^^^ `Other` cannot be made into an object + | +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:8:14 + | LL | trait Other: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -LL | -LL | fn foo(x: &dyn Other) {} - | ^^^^^^^^^^ the trait `Other` cannot be made into an object error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr index 58be59602b9c5..67491b0446f90 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-self.stderr @@ -14,12 +14,16 @@ LL | fn f(a: Self) -> Self; error[E0038]: the trait `A` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:3:13 | +LL | fn f(a: A) -> A; + | ^ `A` cannot be made into an object + | +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-should-use-self.rs:2:10 + | LL | trait A: Sized { - | - ----- ...because it requires `Self: Sized` + | - ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -LL | fn f(a: A) -> A; - | ^ the trait `A` cannot be made into an object error: associated item referring to unboxed trait object for its own trait --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 @@ -37,14 +41,21 @@ LL | fn f(a: Self) -> Self; error[E0038]: the trait `B` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-self.rs:8:13 | +LL | fn f(a: B) -> B; + | ^ `B` cannot be made into an object + | +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-should-use-self.rs:8:8 + | LL | trait B { | - this trait cannot be made into an object... LL | fn f(a: B) -> B; - | - ^ the trait `B` cannot be made into an object - | | - | ...because associated function `f` has no `self` parameter + | ^ ...because associated function `f` has no `self` parameter +help: consider turning `f` into a method by giving it a `&self` argument | -help: consider turning `f` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn f(&self, a: B) -> B; + | ^^^^^^ +help: alternatively, consider constraining `f` so it does not apply to trait objects | LL | fn f(a: B) -> B where Self: Sized; | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed index c4b8960b65e4a..73bb6725f5a72 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.fixed @@ -2,7 +2,7 @@ #![allow(unused_variables, dead_code)] trait Trait { - fn foo() where Self: Other, Self: Sized, { } + fn foo(&self) where Self: Other, Self: Sized, { } fn bar(self: &Self) {} //~ ERROR invalid `self` parameter type } diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr index 6466a768ecbe9..a2caf846cc5fe 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr @@ -1,17 +1,23 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11 | +LL | fn bar(x: &dyn Trait) {} + | ^^^^^^^^^^ `Trait` cannot be made into an object + | +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-should-use-where-sized.rs:5:8 + | LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn foo() where Self: Other, { } - | --- ...because associated function `foo` has no `self` parameter + | ^^^ ...because associated function `foo` has no `self` parameter LL | fn bar(self: ()) {} - | -- ...because method `bar`'s `self` parameter cannot be dispatched on -... -LL | fn bar(x: &dyn Trait) {} - | ^^^^^^^^^^ the trait `Trait` cannot be made into an object + | ^^ ...because method `bar`'s `self` parameter cannot be dispatched on +help: consider turning `foo` into a method by giving it a `&self` argument | -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn foo(&self) where Self: Other, { } + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() where Self: Other, Self: Sized, { } | ^^^^^^^^^^^^^ diff --git a/src/test/ui/traits/issue-72410.stderr b/src/test/ui/traits/issue-72410.stderr index 1db2320841ff7..c91d1db4d764a 100644 --- a/src/test/ui/traits/issue-72410.stderr +++ b/src/test/ui/traits/issue-72410.stderr @@ -1,14 +1,21 @@ error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-72410.rs:14:19 | +LL | where for<'a> &'a mut [dyn Bar]: ; + | ^^^^^^^^^^^^^^^^^ `Bar` cannot be made into an object + | +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-72410.rs:13:8 + | LL | pub trait Bar { | --- this trait cannot be made into an object... LL | fn map() - | --- ...because associated function `map` has no `self` parameter -LL | where for<'a> &'a mut [dyn Bar]: ; - | ^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object + | ^^^ ...because associated function `map` has no `self` parameter +help: consider turning `map` into a method by giving it a `&self` argument | -help: consider turning `map` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn map(&self) + | ^^^^^ +help: alternatively, consider constraining `map` so it does not apply to trait objects | LL | where for<'a> &'a mut [dyn Bar]:, Self: Sized ; | ^^^^^^^^^^^^^ diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr index 1f54e03ee6e58..1118a75e0850e 100644 --- a/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr +++ b/src/test/ui/traits/trait-alias/trait-alias-object-fail.stderr @@ -2,12 +2,13 @@ error[E0038]: the trait `Eq` cannot be made into an object --> $DIR/trait-alias-object-fail.rs:7:13 | LL | let _: &dyn EqAlias = &123; - | ^^^^^^^^^^^ the trait `Eq` cannot be made into an object - | - ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | ^^^^^^^^^^^ `Eq` cannot be made into an object + | +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 + --> $SRC_DIR/core/src/cmp.rs:LL:COL | LL | pub trait Eq: PartialEq { - | --------------- the trait cannot be made into an object because it uses `Self` as a type parameter in this + | ^^^^^^^^^^^^^^^ the trait cannot be made into an object because it uses `Self` as a type parameter error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified --> $DIR/trait-alias-object-fail.rs:9:17 diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index 3be4f11097311..4d97d934376bf 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -112,23 +112,25 @@ LL | C::A; error[E0038]: the trait `assoc_const::C` cannot be made into an object --> $DIR/trait-item-privacy.rs:101:5 | +LL | C::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/trait-item-privacy.rs:25:15 + | LL | const A: u8 = 0; - | - ...because it contains this associated `const` + | ^ ...because it contains this associated `const` ... LL | const B: u8 = 0; - | - ...because it contains this associated `const` + | ^ ...because it contains this associated `const` ... 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` -... -LL | C::A; - | ^^^^ the trait `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 + | ^ ...because it contains this associated `const` error[E0223]: ambiguous associated type --> $DIR/trait-item-privacy.rs:115:12 diff --git a/src/test/ui/traits/trait-object-macro-matcher.stderr b/src/test/ui/traits/trait-object-macro-matcher.stderr index bc56736073488..335eeb8f1515b 100644 --- a/src/test/ui/traits/trait-object-macro-matcher.stderr +++ b/src/test/ui/traits/trait-object-macro-matcher.stderr @@ -8,9 +8,10 @@ error[E0038]: the trait `Copy` cannot be made into an object --> $DIR/trait-object-macro-matcher.rs:8:8 | LL | m!(dyn Copy + Send + 'static); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `Copy` cannot be made into an object | = note: the trait cannot be made into an object because it requires `Self: Sized` + = 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 error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr index 3fa7c0c484e29..16f60962cc1d7 100644 --- a/src/test/ui/traits/trait-object-safety.stderr +++ b/src/test/ui/traits/trait-object-safety.stderr @@ -1,17 +1,23 @@ error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:22 | +LL | let _: &dyn Tr = &St; + | ^^^ `Tr` cannot be made into an object + | +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-object-safety.rs:4:8 + | LL | trait Tr { | -- this trait cannot be made into an object... LL | fn foo(); - | --- ...because associated function `foo` has no `self` parameter -... -LL | let _: &dyn Tr = &St; - | ^^^ the trait `Tr` cannot be made into an object - | + | ^^^ ...because associated function `foo` has no `self` parameter = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Tr>` for `&St` = note: required by cast to type `&dyn Tr` -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self); + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() where Self: Sized; | ^^^^^^^^^^^^^^^^^ @@ -19,15 +25,21 @@ LL | fn foo() where Self: Sized; error[E0038]: the trait `Tr` cannot be made into an object --> $DIR/trait-object-safety.rs:15:12 | +LL | let _: &dyn Tr = &St; + | ^^^^^^^ `Tr` cannot be made into an object + | +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-object-safety.rs:4:8 + | LL | trait Tr { | -- this trait cannot be made into an object... LL | fn foo(); - | --- ...because associated function `foo` has no `self` parameter -... -LL | let _: &dyn Tr = &St; - | ^^^^^^^ the trait `Tr` cannot be made into an object + | ^^^ ...because associated function `foo` has no `self` parameter +help: consider turning `foo` into a method by giving it a `&self` argument | -help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects +LL | fn foo(&self); + | ^^^^^ +help: alternatively, consider constraining `foo` so it does not apply to trait objects | LL | fn foo() where Self: Sized; | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/traits/trait-resolution-in-overloaded-op.rs b/src/test/ui/traits/trait-resolution-in-overloaded-op.rs index 286776985168f..a9bacc357bc03 100644 --- a/src/test/ui/traits/trait-resolution-in-overloaded-op.rs +++ b/src/test/ui/traits/trait-resolution-in-overloaded-op.rs @@ -5,7 +5,7 @@ trait MyMul { } fn foo>(a: &T, b: f64) -> f64 { - a * b //~ ERROR cannot multiply `f64` to `&T` + a * b //~ ERROR cannot multiply `&T` by `f64` } fn main() {} diff --git a/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr b/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr index 507d53dc07c4c..ada76cd8b7720 100644 --- a/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr +++ b/src/test/ui/traits/trait-resolution-in-overloaded-op.stderr @@ -1,4 +1,4 @@ -error[E0369]: cannot multiply `f64` to `&T` +error[E0369]: cannot multiply `&T` by `f64` --> $DIR/trait-resolution-in-overloaded-op.rs:8:7 | LL | a * b diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr index 0a62f1aeb2750..a06f6a49194ff 100644 --- a/src/test/ui/traits/trait-test-2.stderr +++ b/src/test/ui/traits/trait-test-2.stderr @@ -13,32 +13,36 @@ LL | 10.blah::(); error[E0038]: the trait `bar` cannot be made into an object --> $DIR/trait-test-2.rs:11:16 | -LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- ---- ---- ...because method `blah` has generic type parameters - | | | - | | ...because method `dup` references the `Self` type in its return type - | this trait cannot be made into an object... -... LL | (box 10 as Box).dup(); - | ^^^^^^^^^^^^ the trait `bar` cannot be made into an object + | ^^^^^^^^^^^^ `bar` 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/trait-test-2.rs:11:6 +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-test-2.rs:4:30 | LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } - | --- ---- ---- ...because method `blah` has generic type parameters + | --- ^^^^ ^^^^ ...because method `blah` has generic type parameters | | | | | ...because method `dup` references the `Self` type in its return type | this trait cannot be made into an object... -... + +error[E0038]: the trait `bar` cannot be made into an object + --> $DIR/trait-test-2.rs:11:6 + | LL | (box 10 as Box).dup(); - | ^^^^^^ the trait `bar` cannot be made into an object + | ^^^^^^ `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/trait-test-2.rs:4:30 + | +LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } + | --- ^^^^ ^^^^ ...because method `blah` has generic type parameters + | | | + | | ...because method `dup` references the `Self` type in its return type + | this trait cannot be made into an object... = 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 539189982a8d7..2de5f6eb0f03a 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 @@ -13,15 +13,17 @@ LL | let y = x as dyn MyAdd; error[E0038]: the trait `MyAdd` cannot be made into an object --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18 | -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... -... LL | let y = x as dyn MyAdd; - | ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object + | ^^^^^^^^^^^^^^ `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 + | +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... error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index e707839a97edc..29dfb585ac682 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -1,42 +1,48 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | +LL | let t_box: Box = Box::new(S); + | ^^^^^^^^^^^ `Trait` cannot be made into an object + | +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-convert-unsafe-trait-obj-box.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | let t_box: Box = Box::new(S); - | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized>` for `Box` = note: required by cast to type `Box` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | +LL | takes_box(Box::new(S)); + | ^^^^^^^^^^^ `Trait` cannot be made into an object + | +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-convert-unsafe-trait-obj-box.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | takes_box(Box::new(S)); - | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized>` for `Box` = note: required by cast to type `Box<(dyn Trait + 'static)>` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 | +LL | Box::new(S) as Box; + | ^^^^^^^^^^^ `Trait` cannot be made into an object + | +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-convert-unsafe-trait-obj-box.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | Box::new(S) as Box; - | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object - | = 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/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr index 08d4808b77d6e..02169f26f9034 100644 --- a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -1,42 +1,48 @@ error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | +LL | let t: &dyn Trait = &S; + | ^^ `Trait` cannot be made into an object + | +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-convert-unsafe-trait-obj.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | let t: &dyn Trait = &S; - | ^^ the trait `Trait` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | +LL | takes_trait(&S); + | ^^ `Trait` cannot be made into an object + | +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-convert-unsafe-trait-obj.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | takes_trait(&S); - | ^^ the trait `Trait` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 | +LL | &S as &dyn Trait; + | ^^ `Trait` cannot be made into an object + | +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-convert-unsafe-trait-obj.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | &S as &dyn Trait; - | ^^ the trait `Trait` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr index e7921f3496c51..988cb2fa5480c 100644 --- a/src/test/ui/wf/wf-fn-where-clause.stderr +++ b/src/test/ui/wf/wf-fn-where-clause.stderr @@ -34,9 +34,10 @@ error[E0038]: the trait `Copy` cannot be made into an object --> $DIR/wf-fn-where-clause.rs:12:16 | LL | fn bar() where Vec:, {} - | ^^^^^^^^^^^^^ the trait `Copy` cannot be made into an object + | ^^^^^^^^^^^^^ `Copy` cannot be made into an object | = note: the trait cannot be made into an object because it requires `Self: Sized` + = 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 error: aborting due to 3 previous errors diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr index 8935d766354fe..9b749f88fb810 100644 --- a/src/test/ui/wf/wf-object-safe.stderr +++ b/src/test/ui/wf/wf-object-safe.stderr @@ -1,15 +1,17 @@ error[E0038]: the trait `A` cannot be made into an object --> $DIR/wf-object-safe.rs:9:13 | -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 -... LL | let _x: &dyn A; - | ^^^^^^ the trait `A` cannot be made into an object + | ^^^^^^ `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 + | +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 error: aborting due to previous error diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr index d0f43f800fd00..9dbd41ca368a1 100644 --- a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -15,28 +15,32 @@ LL | | } error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:26:21 | +LL | Some(()) => &S, + | ^^ `Trait` cannot be made into an object + | +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-unsafe-trait-obj-match.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | Some(()) => &S, - | ^^ the trait `Trait` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&S` = note: required by cast to type `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | +LL | let t: &dyn Trait = match opt() { + | ^^^^^^^^^^^ `Trait` cannot be made into an object + | +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-unsafe-trait-obj-match.rs:6:14 + | LL | trait Trait: Sized {} - | ----- ----- ...because it requires `Self: Sized` + | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... -... -LL | let t: &dyn Trait = match opt() { - | ^^^^^^^^^^^ the trait `Trait` cannot be made into an object - | = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Trait>` for `&R` = note: required by cast to type `&dyn Trait`