diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f21cd653f962b..25e1a90f676f4 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1984,6 +1984,14 @@ impl<'hir> QPath<'hir> { QPath::LangItem(_, span) => span, } } + + pub fn res(&self) -> Option { + match self { + QPath::LangItem(..) => None, + QPath::Resolved(_, path) => Some(path.res), + QPath::TypeRelative(_, path_segment) => Some(path_segment.res), + } + } } /// Hints at the original code for a let statement. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index d9d36f5299b58..619297415fcf1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -204,15 +204,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { diag.multipart_suggestion_verbose(msg, impl_sugg, Applicability::MachineApplicable); if is_object_safe { diag.multipart_suggestion_verbose( - "alternatively, you can return an owned trait object", + "alternatively, you can return a boxed trait object", vec![ (ty.span.shrink_to_lo(), "Box".to_string()), ], Applicability::MachineApplicable, ); - } else if is_downgradable { - // We'll emit the object safety error already, with a structured suggestion. + } + if is_downgradable + && (matches!(self_ty.kind, hir::TyKind::TraitObject(_, _, TraitObjectSyntax::None)) + || !is_object_safe) + { + // We'll emit the object safety or `!Sized` error already, with a structured + // suggestion. diag.downgrade_to_delayed_bug(); } return true; @@ -242,6 +247,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { diag.downgrade_to_delayed_bug(); } } else { + if let hir::TyKind::TraitObject(.., TraitObjectSyntax::None) = self_ty.kind + && is_downgradable + { + // We'll emit a `Sized` error already, with a structured suggestion. + diag.downgrade_to_delayed_bug(); + } let sugg = if let hir::TyKind::TraitObject([_, _, ..], _, _) = self_ty.kind { // There are more than one trait bound, we need surrounding parentheses. vec![ diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 59a043d1d6996..676069244aa8c 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -86,7 +86,7 @@ pub(super) fn check_fn<'a, 'tcx>( if !params_can_be_unsized { fcx.require_type_is_sized( param_ty, - param.pat.span, + param.ty_span, // ty.span == binding_span iff this is a closure parameter with no type ascription, // or if it's an implicit `self` parameter traits::SizedArgumentType( diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 4da45303d1277..4a0c988ce9ffc 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -582,7 +582,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.require_type_is_sized_deferred( input, span, - traits::SizedArgumentType(None), + traits::SizedArgumentType(args.get(i).map(|e| e.hir_id)), ); } } @@ -600,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.require_type_is_sized_deferred( output, call.map_or(expr.span, |e| e.span), - traits::SizedCallReturnType, + traits::SizedCallReturnType(call.map(|e| e.hir_id)), ); } diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index be5cd6e9d4872..15db349e604db 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -1,4 +1,5 @@ use crate::FnCtxt; +use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::PatKind; @@ -61,11 +62,12 @@ pub(super) struct GatherLocalsVisitor<'a, 'tcx> { // *distinct* cases. so track when we are hitting a pattern *within* an fn // parameter. outermost_fn_param_pat: Option<(Span, hir::HirId)>, + pat_expr_map: FxHashMap, } impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>) -> Self { - Self { fcx, outermost_fn_param_pat: None } + Self { fcx, outermost_fn_param_pat: None, pat_expr_map: Default::default() } } fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option>) -> Ty<'tcx> { @@ -92,18 +94,57 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { /// again during type checking by querying [`FnCtxt::local_ty`] for the same hir_id. fn declare(&mut self, decl: Declaration<'tcx>) { let local_ty = match decl.ty { - Some(ref ty) => { - let o_ty = self.fcx.lower_ty(ty); + Some(ref hir_ty) => { + let o_ty = self.fcx.lower_ty(hir_ty); let c_ty = self.fcx.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty.raw)); - debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty); + debug!(?hir_ty.hir_id, ?o_ty, ?c_ty, "visit_local"); self.fcx .typeck_results .borrow_mut() .user_provided_types_mut() - .insert(ty.hir_id, c_ty); + .insert(hir_ty.hir_id, c_ty); - Some(o_ty.normalized) + let ty = o_ty.normalized; + match decl.pat.kind { + // We explicitly allow `let ref x: str = *"";` + hir::PatKind::Binding(hir::BindingAnnotation(hir::ByRef::Yes(_), _), ..) => {} + // We explicitly allow `let _: dyn Trait;` and allow the `visit_pat` check to + // handle `let (x, _): (sized, str) = *r;`. Otherwise with the later we'd + // complain incorrectly about the `str` that is otherwise unused. + _ if { + let mut is_wild = false; + decl.pat.walk(|pat| { + if let hir::PatKind::Wild = pat.kind { + is_wild = true; + false + } else { + true + } + }); + is_wild + } => {} + _ => { + if self.outermost_fn_param_pat.is_some() { + if !self.fcx.tcx.features().unsized_fn_params { + self.fcx.require_type_is_sized( + ty, + hir_ty.span, + traits::SizedArgumentType(Some(decl.pat.hir_id)), + ); + } + } else { + if !self.fcx.tcx.features().unsized_locals { + self.fcx.require_type_is_sized( + ty, + hir_ty.span, + traits::VariableType(decl.pat.hir_id), + ); + } + } + } + } + Some(ty) } None => None, }; @@ -117,18 +158,95 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { } } +/// Builds a correspondence mapping between the bindings in a pattern and the expression that +/// originates the value. This is then used on unsized locals errors to point at the sub expression +/// That corresponds to the sub-pattern with the `?Sized` type, instead of the binding. +/// +/// This is somewhat limited, as it only supports bindings, tuples and structs for now, falling back +/// on pointing at the binding otherwise. +struct JointVisitorExpr<'hir> { + pat: &'hir hir::Pat<'hir>, + expr: &'hir hir::Expr<'hir>, + map: FxHashMap, +} + +impl<'hir> JointVisitorExpr<'hir> { + fn walk(&mut self) { + match (self.pat.kind, self.expr.kind) { + (hir::PatKind::Tuple(pat_fields, pos), hir::ExprKind::Tup(expr_fields)) + if pat_fields.len() == expr_fields.len() && pos.as_opt_usize() == None => + { + for (pat, expr) in pat_fields.iter().zip(expr_fields.iter()) { + self.map.insert(pat.hir_id, expr.span); + let mut v = JointVisitorExpr { pat, expr, map: Default::default() }; + v.walk(); + self.map.extend(v.map); + } + } + (hir::PatKind::Binding(..), hir::ExprKind::MethodCall(path, ..)) => { + self.map.insert(self.pat.hir_id, path.ident.span); + } + (hir::PatKind::Binding(..), _) => { + self.map.insert(self.pat.hir_id, self.expr.span); + } + ( + hir::PatKind::Struct(pat_path, pat_fields, _), + hir::ExprKind::Struct(call_path, expr_fields, _), + ) if pat_path.res() == call_path.res() && pat_path.res().is_some() => { + for (pat_field, expr_field) in pat_fields.iter().zip(expr_fields.iter()) { + self.map.insert(pat_field.hir_id, expr_field.span); + let mut v = JointVisitorExpr { + pat: pat_field.pat, + expr: expr_field.expr, + map: Default::default(), + }; + v.walk(); + self.map.extend(v.map); + } + } + ( + hir::PatKind::TupleStruct(pat_path, pat_fields, _), + hir::ExprKind::Call( + hir::Expr { kind: hir::ExprKind::Path(expr_path), .. }, + expr_fields, + ), + ) if pat_path.res() == expr_path.res() && pat_path.res().is_some() => { + for (pat, expr) in pat_fields.iter().zip(expr_fields.iter()) { + self.map.insert(pat.hir_id, expr.span); + let mut v = JointVisitorExpr { pat: pat, expr: expr, map: Default::default() }; + v.walk(); + self.map.extend(v.map); + } + } + _ => {} + } + } +} + impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { // Add explicitly-declared locals. fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) { self.declare(local.into()); - intravisit::walk_local(self, local) + if let Some(init) = local.init { + let mut v = JointVisitorExpr { pat: &local.pat, expr: &init, map: Default::default() }; + v.walk(); + self.pat_expr_map.extend(v.map); + } + intravisit::walk_local(self, local); } fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { if let hir::ExprKind::Let(let_expr) = expr.kind { + let mut v = JointVisitorExpr { + pat: &let_expr.pat, + expr: &let_expr.init, + map: Default::default(), + }; + v.walk(); + self.pat_expr_map.extend(v.map); self.declare((let_expr, expr.hir_id).into()); } - intravisit::walk_expr(self, expr) + intravisit::walk_expr(self, expr); } fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { @@ -147,7 +265,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { if !self.fcx.tcx.features().unsized_fn_params { self.fcx.require_type_is_sized( var_ty, - p.span, + ty_span, // ty_span == ident.span iff this is a closure parameter with no type // ascription, or if it's an implicit `self` parameter traits::SizedArgumentType( @@ -163,7 +281,8 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { } } else { if !self.fcx.tcx.features().unsized_locals { - self.fcx.require_type_is_sized(var_ty, p.span, traits::VariableType(p.hir_id)); + let span = *self.pat_expr_map.get(&p.hir_id).unwrap_or(&p.span); + self.fcx.require_type_is_sized(var_ty, span, traits::VariableType(p.hir_id)); } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index ee81679191978..58e43d0573cf5 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -17,8 +17,8 @@ use crate::ty::{GenericArgsRef, TyCtxt}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diag, EmissionGuarantee}; -use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::{HirId, MatchSource}; use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; @@ -262,10 +262,10 @@ pub enum ObligationCauseCode<'tcx> { /// expression that caused the obligation, and the `usize` /// indicates exactly which predicate it is in the list of /// instantiated predicates. - ExprItemObligation(DefId, rustc_hir::HirId, usize), + ExprItemObligation(DefId, HirId, usize), /// Combines `ExprItemObligation` and `BindingObligation`. - ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize), + ExprBindingObligation(DefId, Span, HirId, usize), /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), @@ -287,13 +287,13 @@ pub enum ObligationCauseCode<'tcx> { /// `S { ... }` must be `Sized`. StructInitializerSized, /// Type of each variable must be `Sized`. - VariableType(hir::HirId), + VariableType(HirId), /// Argument type must be `Sized`. - SizedArgumentType(Option), + SizedArgumentType(Option), /// Return type must be `Sized`. SizedReturnType, /// Return type of a call expression must be `Sized`. - SizedCallReturnType, + SizedCallReturnType(Option), /// Yield type must be `Sized`. SizedYieldType, /// Inline asm operand type must be `Sized`. @@ -335,9 +335,9 @@ pub enum ObligationCauseCode<'tcx> { FunctionArgumentObligation { /// The node of the relevant argument in the function call. - arg_hir_id: hir::HirId, + arg_hir_id: HirId, /// The node of the function call. - call_hir_id: hir::HirId, + call_hir_id: HirId, /// The obligation introduced by this argument. parent_code: InternedObligationCauseCode<'tcx>, }, @@ -402,18 +402,18 @@ pub enum ObligationCauseCode<'tcx> { ReturnNoExpression, /// `return` with an expression - ReturnValue(hir::HirId), + ReturnValue(HirId), /// Opaque return type of this function OpaqueReturnType(Option<(Ty<'tcx>, Span)>), /// Block implicit return - BlockTailExpression(hir::HirId, hir::MatchSource), + BlockTailExpression(HirId, MatchSource), /// #[feature(trivial_bounds)] is not enabled TrivialBound, - AwaitableExpr(hir::HirId), + AwaitableExpr(HirId), ForLoopIterator, @@ -431,8 +431,8 @@ pub enum ObligationCauseCode<'tcx> { MatchImpl(ObligationCause<'tcx>, DefId), BinOp { - lhs_hir_id: hir::HirId, - rhs_hir_id: Option, + lhs_hir_id: HirId, + rhs_hir_id: Option, rhs_span: Option, rhs_is_lit: bool, output_ty: Option>, @@ -562,14 +562,14 @@ pub enum StatementAsExpression { #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] #[derive(TypeVisitable, TypeFoldable)] pub struct MatchExpressionArmCause<'tcx> { - pub arm_block_id: Option, + pub arm_block_id: Option, pub arm_ty: Ty<'tcx>, pub arm_span: Span, - pub prior_arm_block_id: Option, + pub prior_arm_block_id: Option, pub prior_arm_ty: Ty<'tcx>, pub prior_arm_span: Span, pub scrut_span: Span, - pub source: hir::MatchSource, + pub source: MatchSource, pub prior_non_diverging_arms: Vec, // Is the expectation of this match expression an RPIT? pub tail_defines_return_position_impl_trait: Option, @@ -578,8 +578,8 @@ pub struct MatchExpressionArmCause<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] pub struct IfExpressionCause<'tcx> { - pub then_id: hir::HirId, - pub else_id: hir::HirId, + pub then_id: HirId, + pub else_id: HirId, pub then_ty: Ty<'tcx>, pub else_ty: Ty<'tcx>, pub outer_span: Option, diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index ee18647cdd8fd..8fa9cd83247f3 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -266,8 +266,9 @@ pub fn suggest_constraining_type_params<'a>( constraints.extract_if(|(_, def_id)| *def_id == tcx.lang_items().sized_trait()); if let Some((_, def_id)) = sized_constraints.next() { applicability = Applicability::MaybeIncorrect; - - err.span_label(param.span, "this type parameter needs to be `Sized`"); + if !param.name.ident().as_str().starts_with("impl ") { + err.span_label(param.span, "this type parameter needs to be `Sized`"); + } suggest_changing_unsized_bound(generics, &mut suggestions, param, def_id); } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index af90372b97ce3..1afab42461529 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -10,6 +10,7 @@ use crate::infer::InferCtxt; use crate::traits::{ImplDerivedObligationCause, NormalizeExt, ObligationCtxt}; use hir::def::CtorOf; +use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ @@ -1791,27 +1792,123 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.primary_message("return type cannot have an unboxed trait object"); err.children.clear(); - let span = obligation.cause.span; - if let Ok(snip) = self.tcx.sess.source_map().span_to_snippet(span) - && snip.starts_with("dyn ") - { - err.span_suggestion( - span.with_hi(span.lo() + BytePos(4)), - "return an `impl Trait` instead of a `dyn Trait`, \ - if all returned values are the same type", - "impl ", - Applicability::MaybeIncorrect, - ); - } - let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(obligation.cause.body_id)); let mut visitor = ReturnsVisitor::default(); visitor.visit_body(body); - let mut sugg = - vec![(span.shrink_to_lo(), "Box<".to_string()), (span.shrink_to_hi(), ">".to_string())]; - sugg.extend(visitor.returns.into_iter().flat_map(|expr| { + let fn_id = self.tcx.hir().body_owner(body.id()); + let Some(fn_decl) = self.tcx.hir_node(fn_id).fn_decl() else { + return false; + }; + let (traits, tr, syn, span, can_be_impl) = match fn_decl.output { + hir::FnRetTy::Return(hir::Ty { + kind: hir::TyKind::TraitObject(traits @ [tr, ..], _lt, syn), + span, + .. + }) => (traits, tr, syn, span, true), + hir::FnRetTy::Return(hir::Ty { + kind: + hir::TyKind::Path(hir::QPath::Resolved( + None, + hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, + )), + span, + .. + }) => { + if let ty::Dynamic(..) = self.tcx.type_of(def_id).instantiate_identity().kind() { + // We have a `type Alias = dyn Trait;` and a return type `-> Alias`. + if let Some(def_id) = def_id.as_local() + && let node = self.tcx.hir_node_by_def_id(def_id) + && let Some(hir::Ty { + kind: hir::TyKind::TraitObject(traits @ [tr, ..], _lt, syn), + .. + }) = node.ty() + { + (traits, tr, syn, span, false) + } else { + let mut span: MultiSpan = (*span).into(); + span.push_span_label(self.tcx.def_span(def_id), "defined here"); + err.span_note(span, "the return type is a type alias to a trait object"); + err.help("consider boxing or borrowing it"); + return false; + } + } else { + return false; + } + } + _ => return false, + }; + + // Suggest `-> impl Trait` + let ret_tys = if let Some(typeck) = &self.typeck_results { + visitor + .returns + .iter() + .filter_map(|expr| typeck.node_type_opt(expr.hir_id).map(|ty| (expr, ty))) + .collect() + } else { + vec![] + }; + + // FIXME: account for `impl` assoc `fn`, where suggesting `Box` if `impl Trait` + // is expected is ok, but suggesting `impl Trait` where `Box` is expected is not. + // FIXME: account for the case where `-> dyn Trait` but the returned value is + // `Box`, like in `tests/ui/unsized/issue-91801.rs`. + + let mut all_same_ty = true; + let mut prev_ty = None; + for (_, ty) in &ret_tys { + if let Some(prev_ty) = prev_ty { + if prev_ty != ty { + all_same_ty = false; + break; + } + } else { + prev_ty = Some(ty); + } + } + let mut alternatively = ""; + if all_same_ty || visitor.returns.len() == 1 { + // We're certain that `impl Trait` will work. + if can_be_impl { + // We know it's not a `type Alias = dyn Trait;`. + err.span_suggestion_verbose( + // This will work for both `Dyn` and `None` object syntax. + span.until(tr.span), + "return an `impl Trait` instead of a `dyn Trait`", + "impl ", + Applicability::MachineApplicable, + ); + alternatively = "alternatively, "; + } + } else { + let mut span: MultiSpan = + ret_tys.iter().map(|(expr, _)| expr.span).collect::>().into(); + for (expr, ty) in &ret_tys { + span.push_span_label(expr.span, format!("this returned value has type `{ty}`")); + } + + err.span_help( + span, + format!( + "the returned values do not all have the same type, so `impl Trait` can't be \ + used", + ), + ); + } + + // Suggest `-> Box` + let pre = match syn { + TraitObjectSyntax::None => "dyn ", + _ => "", + }; + let mut sugg = vec![ + (span.shrink_to_lo(), format!("Box<{pre}")), + (span.shrink_to_hi(), ">".to_string()), + ]; + + sugg.extend(visitor.returns.iter().flat_map(|expr| { let span = expr.span.find_ancestor_in_same_ctxt(obligation.cause.span).unwrap_or(expr.span); if !span.can_be_used_for_suggestions() { @@ -1835,11 +1932,82 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } })); - err.multipart_suggestion( - "box the return type, and wrap all of the returned values in `Box::new`", - sugg, - Applicability::MaybeIncorrect, - ); + let object_unsafe: Vec<_> = traits + .iter() + .filter_map(|tr| { + tr.trait_ref + .path + .res + .opt_def_id() + .filter(|def_id| !self.tcx.object_safety_violations(def_id).is_empty()) + .map(|def_id| (def_id, tr.span)) + }) + .collect(); + if !object_unsafe.is_empty() { + let span: MultiSpan = + object_unsafe.iter().map(|(_, sp)| *sp).collect::>().into(); + err.span_help( + span, + format!( + "{} not object safe, so you can't return a boxed trait object `{}`", + if let [(def_id, _)] = &object_unsafe[..] { + format!("trait `{}` is", self.tcx.def_path_str(*def_id)) + } else { + "the following traits are".to_string() + }, + format!( + "Box", + object_unsafe + .iter() + .map(|(def_id, _)| self.tcx.def_path_str(*def_id)) + .collect::>() + .join(" + ") + ), + ), + ); + } else { + err.multipart_suggestion( + format!( + "{alternatively}box the return type to make a boxed trait object, and wrap \ + all of the returned values in `Box::new`", + ), + sugg, + Applicability::MaybeIncorrect, + ); + alternatively = if alternatively.is_empty() { "alternatively, " } else { "finally, " }; + } + + // Suggest `-> &dyn Trait` + let borrow_input_tys: Vec<_> = fn_decl + .inputs + .iter() + .filter(|hir_ty| matches!(hir_ty.kind, hir::TyKind::Ref(..))) + .collect(); + if !borrow_input_tys.is_empty() { + // Maybe returning a `&dyn Trait` borrowing from an argument might be ok? + err.span_suggestion_verbose( + // This will work for both `Dyn` and `None` object syntax. + span.shrink_to_lo(), + format!( + "{alternatively}you might be able to borrow from {}", + if borrow_input_tys.len() == 1 { + "the function's argument" + } else { + "one of the function's arguments" + }, + ), + match syn { + TraitObjectSyntax::None => "&dyn ", + _ => "&", + }, + Applicability::MachineApplicable, + ); + } else { + err.help( + "if the returned value came from a borrowed argument that implements the trait, \ + then you could return `&dyn Trait`", + ); + } true } @@ -2969,11 +3137,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }) => { err.span_suggestion_verbose( ty.span.shrink_to_lo(), - "consider borrowing here", + "borrowed types have a statically known size", "&", Applicability::MachineApplicable, ); - err.note("all local variables must have a statically known size"); } Node::LetStmt(hir::LetStmt { init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }), @@ -2984,11 +3151,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // order to use have a slice instead. err.span_suggestion_verbose( span.shrink_to_lo(), - "consider borrowing here", + "borrowed values have a statically known size", "&", Applicability::MachineApplicable, ); - err.note("all local variables must have a statically known size"); } Node::Param(param) => { err.span_suggestion_verbose( @@ -3000,11 +3166,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } _ => { - err.note("all local variables must have a statically known size"); + if !tcx.sess.opts.unstable_features.is_nightly_build() + && !tcx.features().unsized_locals + { + err.note("all bindings must have a statically known size"); + } } } - if !tcx.features().unsized_locals { - err.help("unsized locals are gated as an unstable feature"); + if tcx.sess.opts.unstable_features.is_nightly_build() + && !tcx.features().unsized_locals + { + err.help( + "unsized locals are gated as unstable feature \ + `#[feature(unsized_locals)]`", + ); } } ObligationCauseCode::SizedArgumentType(hir_id) => { @@ -3029,67 +3204,72 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { ty = Some(t); } - if let Some(ty) = ty { - match ty.kind { - hir::TyKind::TraitObject(traits, _, _) => { - let (span, kw) = match traits { - [first, ..] if first.span.lo() == ty.span.lo() => { - // Missing `dyn` in front of trait object. - (ty.span.shrink_to_lo(), "dyn ") - } - [first, ..] => (ty.span.until(first.span), ""), - [] => span_bug!(ty.span, "trait object with no traits: {ty:?}"), - }; - let needs_parens = traits.len() != 1; - err.span_suggestion_verbose( - span, - "you can use `impl Trait` as the argument type", - "impl ", - Applicability::MaybeIncorrect, - ); - let sugg = if !needs_parens { - vec![(span.shrink_to_lo(), format!("&{kw}"))] - } else { - vec![ - (span.shrink_to_lo(), format!("&({kw}")), - (ty.span.shrink_to_hi(), ")".to_string()), - ] - }; - err.multipart_suggestion_verbose( - borrowed_msg, - sugg, - Applicability::MachineApplicable, - ); - } - hir::TyKind::Slice(_ty) => { - err.span_suggestion_verbose( - ty.span.shrink_to_lo(), - "function arguments must have a statically known size, borrowed \ - slices always have a known size", - "&", - Applicability::MachineApplicable, - ); - } - hir::TyKind::Path(_) => { - err.span_suggestion_verbose( - ty.span.shrink_to_lo(), - borrowed_msg, - "&", - Applicability::MachineApplicable, - ); + match ty.map(|ty| (ty.kind, ty.span)) { + Some((hir::TyKind::TraitObject(traits, _, _), sp)) => { + let (span, kw) = match traits { + [first, ..] if first.span.lo() == sp.lo() => { + // Missing `dyn` in front of trait object. + (sp.shrink_to_lo(), "dyn ") + } + [first, ..] => (sp.until(first.span), ""), + [] => span_bug!(sp, "trait object with no traits: {ty:?}"), + }; + let needs_parens = traits.len() != 1; + err.span_suggestion_verbose( + span, + "you can use `impl Trait` as the argument type", + "impl ", + Applicability::MaybeIncorrect, + ); + let sugg = if !needs_parens { + vec![(span.shrink_to_lo(), format!("&{kw}"))] + } else { + vec![ + (span.shrink_to_lo(), format!("&({kw}")), + (sp.shrink_to_hi(), ")".to_string()), + ] + }; + err.multipart_suggestion_verbose( + borrowed_msg, + sugg, + Applicability::MachineApplicable, + ); + } + Some((hir::TyKind::Slice(_ty), span)) => { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "function arguments must have a statically known size, borrowed \ + slices always have a known size", + "&", + Applicability::MachineApplicable, + ); + } + Some((hir::TyKind::Path(_), span)) => { + err.span_suggestion_verbose( + span.shrink_to_lo(), + borrowed_msg, + "&", + Applicability::MachineApplicable, + ); + } + _ => { + if !tcx.sess.opts.unstable_features.is_nightly_build() + && !tcx.features().unsized_fn_params + { + err.note("all bindings must have a statically known size"); } - _ => {} } - } else { - err.note("all function arguments must have a statically known size"); } if tcx.sess.opts.unstable_features.is_nightly_build() && !tcx.features().unsized_fn_params { - err.help("unsized fn params are gated as an unstable feature"); + err.help( + "unsized fn params are gated as unstable feature \ + `#[feature(unsized_fn_params)]`", + ); } } - ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType => { + ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType(_) => { err.note("the return type of a function must have a statically known size"); } ObligationCauseCode::SizedYieldType => { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 144971b63c0ad..0aad3f4b3dbda 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -94,6 +94,66 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { predicate: ty::Predicate<'tcx>, index: Option, // None if this is an old error } + let dedup_span = |obligation: &Obligation<'_, ty::Predicate<'_>>| { + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = obligation.cause.span; + if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = + obligation.predicate.kind().skip_binder() + && Some(pred.def_id()) == self.tcx.lang_items().sized_trait() + { + // For `Sized` bounds exclusively, we deduplicate based on `let` binding origin. + // We could do this for other traits, but in cases like the tests at + // `tests/ui/coroutine/clone-impl-async.rs` we'd end up with fewer errors than we do + // now, because different `fn` calls might have different sources of the obligation, + // which are unrelated between calls. FIXME: We could rework the dedup logic below + // to go further from evaluating only a single span, instead grouping multiple + // errors associated to the same binding and emitting a single error with *all* the + // appropriate context. + match obligation.cause.code() { + ObligationCauseCode::VariableType(hir_id) => { + if let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id) { + // `let` binding obligations will not necessarily point at the + // identifier, so point at it. + span = pat.span; + } + } + ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } => { + if let hir::Node::Expr(expr) = self.tcx.hir_node(*arg_hir_id) + && let hir::ExprKind::Path(hir::QPath::Resolved( + None, + hir::Path { res: hir::def::Res::Local(hir_id), .. }, + )) = expr.peel_borrows().kind + && let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id) + { + // When we have a call argument that is a `!Sized` `let` binding, + // deduplicate all the `!Sized` errors referencing that binding. + span = pat.span; + } + } + ObligationCauseCode::SizedCallReturnType(Some(hir_id)) => { + // This is a special case: when `fn foo() -> dyn Trait` and we call `foo()` + // in the init of a `let` binding, we will already emit an unsized local + // error, so we check for this case and unify the errors. + if let hir::Node::LetStmt(local) = self.tcx.parent_hir_node(*hir_id) { + span = local.pat.span; + } + } + ObligationCauseCode::ExprBindingObligation(_, _, hir_id, _) => { + // For method calls like `let x = y.foo();` that are `?Sized`, we also dedup + if let hir::Node::LetStmt(local) = self.tcx.parent_hir_node(*hir_id) { + span = local.pat.span; + } + } + _ => {} + } + } + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + span + }; let mut error_map: FxIndexMap<_, Vec<_>> = self .reported_trait_errors @@ -125,15 +185,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }); for (index, error) in errors.iter().enumerate() { - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; - } - - error_map.entry(span).or_default().push(ErrorDescriptor { + error_map.entry(dedup_span(&error.obligation)).or_default().push(ErrorDescriptor { predicate: error.obligation.predicate, index: Some(index), }); @@ -177,16 +229,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { let guar = self.report_fulfillment_error(error); reported = Some(guar); - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; - } self.reported_trait_errors .borrow_mut() - .entry(span) + .entry(dedup_span(&error.obligation)) .or_insert_with(|| (vec![], guar)) .0 .push(error.obligation.predicate); @@ -365,6 +410,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { error: &SelectionError<'tcx>, ) -> ErrorGuaranteed { let tcx = self.tcx; + let mut span = obligation.cause.span; if tcx.sess.opts.unstable_opts.next_solver.map(|c| c.dump_tree).unwrap_or_default() == DumpSolverProofTree::OnError @@ -372,8 +418,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { dump_proof_tree(root_obligation, self.infcx); } - let mut span = obligation.cause.span; - let mut err = match *error { SelectionError::Unimplemented => { // If this obligation was generated as a result of well-formedness checking, see if we @@ -644,15 +688,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ObligationCauseCode::Coercion { source, target } = *obligation.cause.code().peel_derives() + && Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { - if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { - self.suggest_borrowing_for_object_cast( - &mut err, - root_obligation, - source, - target, - ); - } + self.suggest_borrowing_for_object_cast( + &mut err, + root_obligation, + source, + target, + ); } let UnsatisfiedConst(unsatisfied_const) = self diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs index c29e46b941c60..99a250f8e6fd7 100644 --- a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs +++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs @@ -137,7 +137,6 @@ fn assert_len_expr<'hir>( if let Some(higher::If { cond, then, .. }) = higher::If::hir(expr) && let ExprKind::Unary(UnOp::Not, condition) = &cond.kind && let ExprKind::Binary(bin_op, left, right) = &condition.kind - && let Some((cmp, asserted_len, slice_len)) = len_comparison(*bin_op, left, right) && let ExprKind::MethodCall(method, recv, ..) = &slice_len.kind && cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice() diff --git a/src/tools/clippy/tests/ui/crashes/ice-6251.stderr b/src/tools/clippy/tests/ui/crashes/ice-6251.stderr index 82e7d72358697..5f15fc0f4ec93 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6251.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6251.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> tests/ui/crashes/ice-6251.rs:4:45 + --> tests/ui/crashes/ice-6251.rs:4:48 | LL | fn bug() -> impl Iterator { - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `[u8]` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed slices always have a known size | LL | fn bug() -> impl Iterator { diff --git a/tests/ui/associated-types/associated-types-unsized.stderr b/tests/ui/associated-types/associated-types-unsized.stderr index e46b2a394640b..d0395f3ca09a4 100644 --- a/tests/ui/associated-types/associated-types-unsized.stderr +++ b/tests/ui/associated-types/associated-types-unsized.stderr @@ -1,12 +1,11 @@ error[E0277]: the size for values of type `::Value` cannot be known at compilation time - --> $DIR/associated-types-unsized.rs:10:9 + --> $DIR/associated-types-unsized.rs:10:15 | LL | let x = t.get(); - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `::Value` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider further restricting the associated type | LL | fn foo(t: T) where ::Value: Sized { diff --git a/tests/ui/associated-types/issue-20005.rs b/tests/ui/associated-types/issue-20005.rs index e6e83d92061c3..13b27ad2a27d2 100644 --- a/tests/ui/associated-types/issue-20005.rs +++ b/tests/ui/associated-types/issue-20005.rs @@ -9,6 +9,7 @@ trait To { self //~ ERROR the size for values of type ) -> >::Result where Dst: From { //~ ERROR the size for values of type From::from(self) //~ ERROR the size for values of type + //~^ ERROR the size for values of type } } diff --git a/tests/ui/associated-types/issue-20005.stderr b/tests/ui/associated-types/issue-20005.stderr index 1600227c82da9..ca8f28cc520d7 100644 --- a/tests/ui/associated-types/issue-20005.stderr +++ b/tests/ui/associated-types/issue-20005.stderr @@ -24,7 +24,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | self | ^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider further restricting `Self` | LL | ) -> >::Result where Dst: From, Self: Sized { @@ -54,6 +54,18 @@ help: consider relaxing the implicit `Sized` restriction LL | trait From { | ++++++++ -error: aborting due to 3 previous errors +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/issue-20005.rs:11:20 + | +LL | From::from(self) + | ^^^^ doesn't have a size known at compile-time + | + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` +help: consider further restricting `Self` + | +LL | ) -> >::Result where Dst: From, Self: Sized { + | +++++++++++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr index f50d86580f8b0..f45fe5dc50648 100644 --- a/tests/ui/associated-types/issue-59324.stderr +++ b/tests/ui/associated-types/issue-59324.stderr @@ -79,13 +79,13 @@ LL | pub trait Foo: NotFoo { | ^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time - --> $DIR/issue-59324.rs:23:20 + --> $DIR/issue-59324.rs:23:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} - | ^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn ThriftService<(), AssocType = _> + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn with_factory(factory: impl ThriftService<()>) {} diff --git a/tests/ui/async-await/issue-72590-type-error-sized.stderr b/tests/ui/async-await/issue-72590-type-error-sized.stderr index 1b822234d80cc..9ae4dba1e952c 100644 --- a/tests/ui/async-await/issue-72590-type-error-sized.stderr +++ b/tests/ui/async-await/issue-72590-type-error-sized.stderr @@ -22,7 +22,7 @@ note: required because it appears within the type `Foo` | LL | struct Foo { | ^^^ - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | async fn frob(&self) {} diff --git a/tests/ui/closures/cannot-call-unsized-via-ptr-2.stderr b/tests/ui/closures/cannot-call-unsized-via-ptr-2.stderr index d88b84365dfae..007c58659488d 100644 --- a/tests/ui/closures/cannot-call-unsized-via-ptr-2.stderr +++ b/tests/ui/closures/cannot-call-unsized-via-ptr-2.stderr @@ -5,7 +5,6 @@ LL | let f = if true { |_a| {} } else { |_b| {} }; | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all function arguments must have a statically known size error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/cannot-call-unsized-via-ptr-2.rs:5:41 @@ -14,7 +13,6 @@ LL | let f = if true { |_a| {} } else { |_b| {} }; | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all function arguments must have a statically known size error: aborting due to 2 previous errors diff --git a/tests/ui/closures/cannot-call-unsized-via-ptr.stderr b/tests/ui/closures/cannot-call-unsized-via-ptr.stderr index 7c73372e33c9c..145eea9f967da 100644 --- a/tests/ui/closures/cannot-call-unsized-via-ptr.stderr +++ b/tests/ui/closures/cannot-call-unsized-via-ptr.stderr @@ -5,7 +5,6 @@ LL | let f: fn([u8]) = |_result| {}; | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all function arguments must have a statically known size error: aborting due to 1 previous error diff --git a/tests/ui/closures/issue-111932.rs b/tests/ui/closures/issue-111932.rs index eb3fe08cbc409..da6c97d712872 100644 --- a/tests/ui/closures/issue-111932.rs +++ b/tests/ui/closures/issue-111932.rs @@ -2,7 +2,7 @@ trait Foo: std::fmt::Debug {} fn print_foos(foos: impl Iterator) { foos.for_each(|foo| { //~ ERROR [E0277] - println!("{:?}", foo); //~ ERROR [E0277] + println!("{:?}", foo); // no `!Sized` error, already reported above }); } diff --git a/tests/ui/closures/issue-111932.stderr b/tests/ui/closures/issue-111932.stderr index ff46b10d005dc..f5fbfb132ef5b 100644 --- a/tests/ui/closures/issue-111932.stderr +++ b/tests/ui/closures/issue-111932.stderr @@ -5,22 +5,8 @@ LL | foos.for_each(|foo| { | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` - = note: all function arguments must have a statically known size - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` -error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time - --> $DIR/issue-111932.rs:5:26 - | -LL | println!("{:?}", foo); - | ---- ^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call - | - = help: the trait `Sized` is not implemented for `dyn Foo` -note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'a>::new_debug` - --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 2f57c7616f121..9e43cea7586d0 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -43,7 +43,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | fn map2(self, f: F) -> Map2 {} | ^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider further restricting `Self` | LL | fn map2(self, f: F) -> Map2 where Self: Sized {} diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr index a5182eb5d9c32..d81294c187eee 100644 --- a/tests/ui/coherence/occurs-check/opaques.next.stderr +++ b/tests/ui/coherence/occurs-check/opaques.next.stderr @@ -8,10 +8,10 @@ LL | impl Trait for defining_scope::Alias { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0282]: type annotations needed - --> $DIR/opaques.rs:13:20 + --> $DIR/opaques.rs:13:23 | LL | pub fn cast(x: Container, T>) -> Container { - | ^ cannot infer type for struct `Container` + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for struct `Container` error: aborting due to 2 previous errors diff --git a/tests/ui/coroutine/issue-88653.rs b/tests/ui/coroutine/issue-88653.rs index ec4c205475877..8340d5c87cae3 100644 --- a/tests/ui/coroutine/issue-88653.rs +++ b/tests/ui/coroutine/issue-88653.rs @@ -6,13 +6,13 @@ use std::ops::Coroutine; fn foo(bar: bool) -> impl Coroutine<(bool,)> { - //~^ ERROR: type mismatch in coroutine arguments [E0631] - //~| NOTE: expected due to this - //~| NOTE: expected coroutine signature `fn((bool,)) -> _` - //~| NOTE: in this expansion of desugaring of `impl Trait` - //~| NOTE: in this expansion of desugaring of `impl Trait` + //~^ ERROR type mismatch in coroutine arguments [E0631] + //~| NOTE expected due to this + //~| NOTE expected coroutine signature `fn((bool,)) -> _` + //~| NOTE in this expansion of desugaring of `impl Trait` + //~| NOTE in this expansion of desugaring of `impl Trait` |bar| { - //~^ NOTE: found signature defined here + //~^ NOTE found signature defined here if bar { yield bar; } diff --git a/tests/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr b/tests/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr index 6f38def69981f..96742f8bf47cf 100644 --- a/tests/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr +++ b/tests/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr @@ -14,10 +14,10 @@ LL | fn bar(i: i32, t: usize, s: &()) -> (usize, i32) { | ~~~ ~~~~~ ~~~ ~~~~~~~~~~~~ error[E0282]: type annotations needed - --> $DIR/replace-impl-infer-ty-from-trait.rs:9:12 + --> $DIR/replace-impl-infer-ty-from-trait.rs:9:15 | LL | fn bar(i: _, t: _, s: _) -> _ { - | ^ cannot infer type + | ^ cannot infer type error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0038.stderr b/tests/ui/error-codes/E0038.stderr index 6e8eaab8ddf43..c1df9459eb1dd 100644 --- a/tests/ui/error-codes/E0038.stderr +++ b/tests/ui/error-codes/E0038.stderr @@ -29,14 +29,13 @@ LL | fn foo(&self) -> Self; = help: consider moving `foo` to another trait error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time - --> $DIR/E0038.rs:7:9 + --> $DIR/E0038.rs:7:15 | LL | let y = x.foo(); - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `dyn Trait` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` error: aborting due to 3 previous errors diff --git a/tests/ui/error-codes/E0277.stderr b/tests/ui/error-codes/E0277.stderr index aeb97290cf856..4898cabdffcff 100644 --- a/tests/ui/error-codes/E0277.stderr +++ b/tests/ui/error-codes/E0277.stderr @@ -1,13 +1,13 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/E0277.rs:11:6 + --> $DIR/E0277.rs:11:9 | LL | fn f(p: Path) { } - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: within `Path`, the trait `Sized` is not implemented for `[u8]`, which is required by `Path: Sized` note: required because it appears within the type `Path` --> $SRC_DIR/std/src/path.rs:LL:COL - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn f(p: &Path) { } diff --git a/tests/ui/error-codes/E0746.stderr b/tests/ui/error-codes/E0746.stderr index 9fe90ab7bec7f..1ef0efa2e5b98 100644 --- a/tests/ui/error-codes/E0746.stderr +++ b/tests/ui/error-codes/E0746.stderr @@ -4,11 +4,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn foo() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn foo() -> impl Trait { Struct } | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL | fn foo() -> Box { Box::new(Struct) } | ++++ + +++++++++ + @@ -19,11 +20,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn bar() -> impl Trait { | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn bar() -> Box { LL | if true { diff --git a/tests/ui/feature-gates/feature-gate-unsized_fn_params.stderr b/tests/ui/feature-gates/feature-gate-unsized_fn_params.stderr index b11c30eaad4b7..157ebf8b68d3e 100644 --- a/tests/ui/feature-gates/feature-gate-unsized_fn_params.stderr +++ b/tests/ui/feature-gates/feature-gate-unsized_fn_params.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time - --> $DIR/feature-gate-unsized_fn_params.rs:17:8 + --> $DIR/feature-gate-unsized_fn_params.rs:17:11 | LL | fn foo(x: dyn Foo) { - | ^ doesn't have a size known at compile-time + | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn foo(x: impl Foo) { @@ -16,13 +16,13 @@ LL | fn foo(x: &dyn Foo) { | + error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time - --> $DIR/feature-gate-unsized_fn_params.rs:21:8 + --> $DIR/feature-gate-unsized_fn_params.rs:21:11 | LL | fn bar(x: Foo) { - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn bar(x: impl Foo) { @@ -33,13 +33,13 @@ LL | fn bar(x: &dyn Foo) { | ++++ error[E0277]: the size for values of type `[()]` cannot be known at compilation time - --> $DIR/feature-gate-unsized_fn_params.rs:25:8 + --> $DIR/feature-gate-unsized_fn_params.rs:25:11 | LL | fn qux(_: [()]) {} - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[()]` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed slices always have a known size | LL | fn qux(_: &[()]) {} @@ -52,8 +52,7 @@ LL | foo(*x); | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` - = note: all function arguments must have a statically known size - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` error: aborting due to 4 previous errors diff --git a/tests/ui/feature-gates/feature-gate-unsized_locals.stderr b/tests/ui/feature-gates/feature-gate-unsized_locals.stderr index f1595e034be55..23f8edffecb7c 100644 --- a/tests/ui/feature-gates/feature-gate-unsized_locals.stderr +++ b/tests/ui/feature-gates/feature-gate-unsized_locals.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `(dyn FnOnce() + 'static)` cannot be known at compilation time - --> $DIR/feature-gate-unsized_locals.rs:1:6 + --> $DIR/feature-gate-unsized_locals.rs:1:9 | LL | fn f(f: dyn FnOnce()) {} - | ^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn FnOnce() + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn f(f: impl FnOnce()) {} diff --git a/tests/ui/generic-associated-types/issue-79636-1.stderr b/tests/ui/generic-associated-types/issue-79636-1.stderr index c31064dec6296..afffc10228b93 100644 --- a/tests/ui/generic-associated-types/issue-79636-1.stderr +++ b/tests/ui/generic-associated-types/issue-79636-1.stderr @@ -20,7 +20,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | fn bind(self, f: F) -> Self::Wrapped { | ^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider further restricting `Self` | LL | fn bind(self, f: F) -> Self::Wrapped where Self: Sized { diff --git a/tests/ui/impl-trait/dyn-impl-type-mismatch.rs b/tests/ui/impl-trait/dyn-impl-type-mismatch.rs index c6170abb58285..4858f42e192e3 100644 --- a/tests/ui/impl-trait/dyn-impl-type-mismatch.rs +++ b/tests/ui/impl-trait/dyn-impl-type-mismatch.rs @@ -10,7 +10,7 @@ fn main() { } else { foo() //~ ERROR E0308 }; - let a: dyn Trait = if true { + let a: dyn Trait = if true { //~ ERROR E0277 Struct //~ ERROR E0308 } else { foo() //~ ERROR E0308 diff --git a/tests/ui/impl-trait/dyn-impl-type-mismatch.stderr b/tests/ui/impl-trait/dyn-impl-type-mismatch.stderr index ddbdaf3eb4b03..f16a64358aa43 100644 --- a/tests/ui/impl-trait/dyn-impl-type-mismatch.stderr +++ b/tests/ui/impl-trait/dyn-impl-type-mismatch.stderr @@ -1,3 +1,16 @@ +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/dyn-impl-type-mismatch.rs:13:12 + | +LL | let a: dyn Trait = if true { + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` +help: borrowed types have a statically known size + | +LL | let a: &dyn Trait = if true { + | + + error[E0308]: mismatched types --> $DIR/dyn-impl-type-mismatch.rs:11:9 | @@ -38,6 +51,7 @@ LL | foo() found opaque type `impl Trait` = help: you can box the `impl Trait` to coerce it to `Box`, but you'll have to change the expected type as well -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index f25269ca03207..393f0cee303e1 100644 --- a/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/tests/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -48,10 +48,15 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bap() -> Trait { Struct } | ^^^^^ doesn't have a size known at compile-time | -help: box the return type, and wrap all of the returned values in `Box::new` + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | -LL | fn bap() -> Box { Box::new(Struct) } - | ++++ + +++++++++ + +LL | fn bap() -> impl Trait { Struct } + | ++++ +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` + | +LL | fn bap() -> Box { Box::new(Struct) } + | +++++++ + +++++++++ + error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13 @@ -59,11 +64,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn ban() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn ban() -> impl Trait { Struct } | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL | fn ban() -> Box { Box::new(Struct) } | ++++ + +++++++++ + @@ -74,11 +80,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bak() -> dyn Trait { unimplemented!() } | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn bak() -> impl Trait { unimplemented!() } | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL | fn bak() -> Box { Box::new(unimplemented!()) } | ++++ + +++++++++ + @@ -89,11 +96,16 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bal() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type +help: the returned values do not all have the same type, so `impl Trait` can't be used + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:21:16 | -LL | fn bal() -> impl Trait { - | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +LL | return Struct; + | ^^^^^^ this returned value has type `Struct` +LL | } +LL | 42 + | ^^ this returned value has type `{integer}` + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn bal() -> Box { LL | if true { @@ -108,11 +120,16 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bax() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type +help: the returned values do not all have the same type, so `impl Trait` can't be used + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:9 | -LL | fn bax() -> impl Trait { - | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +LL | Struct + | ^^^^^^ this returned value has type `Struct` +LL | } else { +LL | 42 + | ^^ this returned value has type `{integer}` + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn bax() -> Box { LL | if true { @@ -263,11 +280,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn bat() -> impl Trait { | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn bat() -> Box { LL | if true { @@ -282,11 +300,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bay() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn bay() -> impl Trait { | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn bay() -> Box { LL | if true { diff --git a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs index 068f7d3eea6da..773311c29efa0 100644 --- a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs +++ b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs @@ -33,4 +33,10 @@ fn cat() -> Box { //~ ERROR the trait `NotObjectSafe` cannot Box::new(B) //~ ERROR cannot be made into an object } +fn can(x: &A) -> dyn NotObjectSafe { //~ ERROR the trait `NotObjectSafe` cannot be made into an object +//~^ ERROR return type cannot have an unboxed trait object + x +} + + fn main() {} diff --git a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index fc9c30abf1336..411f962737c1f 100644 --- a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -48,25 +48,51 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o 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:36:18 + | +LL | fn can(x: &A) -> 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 + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `NotObjectSafe` for this new enum and using it instead: + A + B +help: consider turning `foo` into a method by giving it a `&self` argument + | +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; + | +++++++++++++++++ + error[E0746]: return type cannot have an unboxed trait object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:13 | LL | fn car() -> dyn NotObjectSafe { | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type +help: the returned values do not all have the same type, so `impl Trait` can't be used + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:24:16 | -LL | fn car() -> impl NotObjectSafe { - | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` - | -LL ~ fn car() -> Box { -LL | -LL | if true { -LL ~ return Box::new(A); +LL | return A; + | ^ this returned value has type `A` LL | } -LL ~ Box::new(B) +LL | B + | ^ this returned value has type `B` +help: trait `NotObjectSafe` is not object safe, so you can't return a boxed trait object `Box` + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:17 | +LL | fn car() -> dyn NotObjectSafe { + | ^^^^^^^^^^^^^ + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` error[E0038]: the trait `NotObjectSafe` cannot be made into an object --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:31:16 @@ -120,7 +146,27 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o LL | fn foo() -> Self where Self: Sized; | +++++++++++++++++ -error: aborting due to 5 previous errors +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:36:18 + | +LL | fn can(x: &A) -> dyn NotObjectSafe { + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | +help: trait `NotObjectSafe` is not object safe, so you can't return a boxed trait object `Box` + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:36:22 + | +LL | fn can(x: &A) -> dyn NotObjectSafe { + | ^^^^^^^^^^^^^ +help: return an `impl Trait` instead of a `dyn Trait` + | +LL | fn can(x: &A) -> impl NotObjectSafe { + | ~~~~ +help: alternatively, you might be able to borrow from the function's argument + | +LL | fn can(x: &A) -> &dyn NotObjectSafe { + | + + +error: aborting due to 7 previous errors Some errors have detailed explanations: E0038, E0746. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr index 9205d74504f6f..41000d9425540 100644 --- a/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/tests/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr @@ -171,11 +171,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn hat() -> dyn std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn hat() -> impl std::fmt::Display { | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn hat() -> Box { LL | match 13 { @@ -192,11 +193,12 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn pug() -> dyn std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn pug() -> impl std::fmt::Display { | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn pug() -> Box { LL | match 13 { @@ -211,11 +213,16 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn man() -> dyn std::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type +help: the returned values do not all have the same type, so `impl Trait` can't be used + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:87:9 | -LL | fn man() -> impl std::fmt::Display { - | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +LL | 0i32 + | ^^^^ this returned value has type `i32` +LL | } else { +LL | 1u32 + | ^^^^ this returned value has type `u32` + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn man() -> Box { LL | if false { diff --git a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr index e2ddf474c4a97..1f1df23866cfc 100644 --- a/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr +++ b/tests/ui/inference/ice-ifer-var-leaked-out-of-rollback-122098.stderr @@ -36,12 +36,12 @@ LL | struct Query<'q> {} = help: consider removing `'q`, referring to it in a field, or using a marker such as `PhantomData` error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:7:17 + --> $DIR/ice-ifer-var-leaked-out-of-rollback-122098.rs:7:21 | LL | fn for_each(mut self, mut f: Box) + 'static>) {} - | ^^^^^^^^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider further restricting `Self` | LL | fn for_each(mut self, mut f: Box) + 'static>) where Self: Sized {} diff --git a/tests/ui/issues/issue-15756.stderr b/tests/ui/issues/issue-15756.stderr index af50fe467d17c..0cff00f8b96eb 100644 --- a/tests/ui/issues/issue-15756.stderr +++ b/tests/ui/issues/issue-15756.stderr @@ -5,8 +5,7 @@ LL | &mut something | ^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[T]` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-18107.stderr b/tests/ui/issues/issue-18107.stderr index 702207c30f7cd..3d882826cebdf 100644 --- a/tests/ui/issues/issue-18107.stderr +++ b/tests/ui/issues/issue-18107.stderr @@ -4,11 +4,11 @@ error[E0746]: return type cannot have an unboxed trait object LL | dyn AbstractRenderer | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type +help: return an `impl Trait` instead of a `dyn Trait` | LL | impl AbstractRenderer | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ Box LL | @@ -16,6 +16,10 @@ LL | { LL | match 0 { LL ~ _ => Box::new(unimplemented!()) | +help: finally, you might be able to borrow from the function's argument + | +LL | &dyn AbstractRenderer + | + error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-27078.stderr b/tests/ui/issues/issue-27078.stderr index d0ba9f6ae2b18..a65e0fdb470e4 100644 --- a/tests/ui/issues/issue-27078.stderr +++ b/tests/ui/issues/issue-27078.stderr @@ -4,7 +4,7 @@ error[E0277]: the size for values of type `Self` cannot be known at compilation LL | fn foo(self) -> &'static i32 { | ^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider further restricting `Self` | LL | fn foo(self) -> &'static i32 where Self: Sized { diff --git a/tests/ui/issues/issue-38954.stderr b/tests/ui/issues/issue-38954.stderr index 4dd83ddf32d3a..eaa5d318beab8 100644 --- a/tests/ui/issues/issue-38954.stderr +++ b/tests/ui/issues/issue-38954.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/issue-38954.rs:1:10 + --> $DIR/issue-38954.rs:1:18 | LL | fn _test(ref _p: str) {} - | ^^^^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn _test(ref _p: &str) {} diff --git a/tests/ui/issues/issue-41229-ref-str.stderr b/tests/ui/issues/issue-41229-ref-str.stderr index afc2cac7343f3..2a9cf3e7b1912 100644 --- a/tests/ui/issues/issue-41229-ref-str.stderr +++ b/tests/ui/issues/issue-41229-ref-str.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/issue-41229-ref-str.rs:1:16 + --> $DIR/issue-41229-ref-str.rs:1:23 | LL | pub fn example(ref s: str) {} - | ^^^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | pub fn example(ref s: &str) {} diff --git a/tests/ui/issues/issue-42312.stderr b/tests/ui/issues/issue-42312.stderr index 3ca6a2957e14b..5d81e381febe5 100644 --- a/tests/ui/issues/issue-42312.stderr +++ b/tests/ui/issues/issue-42312.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `::Target` cannot be known at compilation time - --> $DIR/issue-42312.rs:4:12 + --> $DIR/issue-42312.rs:4:15 | LL | fn baz(_: Self::Target) where Self: Deref {} - | ^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `::Target` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider further restricting the associated type | LL | fn baz(_: Self::Target) where Self: Deref, ::Target: Sized {} @@ -16,13 +16,13 @@ LL | fn baz(_: &Self::Target) where Self: Deref {} | + error[E0277]: the size for values of type `(dyn ToString + 'static)` cannot be known at compilation time - --> $DIR/issue-42312.rs:8:10 + --> $DIR/issue-42312.rs:8:13 | LL | pub fn f(_: dyn ToString) {} - | ^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn ToString + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | pub fn f(_: impl ToString) {} diff --git a/tests/ui/issues/issue-5883.stderr b/tests/ui/issues/issue-5883.stderr index 51d9708e0fa40..5938e2e403d29 100644 --- a/tests/ui/issues/issue-5883.stderr +++ b/tests/ui/issues/issue-5883.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/issue-5883.rs:8:5 + --> $DIR/issue-5883.rs:8:8 | LL | r: dyn A + 'static - | ^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn A + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | r: impl A + 'static diff --git a/tests/ui/issues/issue-66706.stderr b/tests/ui/issues/issue-66706.stderr index ffdd61e7723be..b2849e2b04b25 100644 --- a/tests/ui/issues/issue-66706.stderr +++ b/tests/ui/issues/issue-66706.stderr @@ -29,10 +29,10 @@ LL | [0; match [|f @ &ref _| () ] {} ] | while parsing this `match` expression error[E0282]: type annotations needed - --> $DIR/issue-66706.rs:2:11 + --> $DIR/issue-66706.rs:2:14 | LL | [0; [|_: _ &_| ()].len()] - | ^ cannot infer type + | ^ cannot infer type error: aborting due to 5 previous errors diff --git a/tests/ui/iterators/collect-into-slice.rs b/tests/ui/iterators/collect-into-slice.rs index 120e56a6549e4..4543faa4074d5 100644 --- a/tests/ui/iterators/collect-into-slice.rs +++ b/tests/ui/iterators/collect-into-slice.rs @@ -5,13 +5,9 @@ fn process_slice(data: &[i32]) { fn main() { let some_generated_vec = (0..10).collect(); //~^ ERROR the size for values of type `[i32]` cannot be known at compilation time - //~| ERROR the size for values of type `[i32]` cannot be known at compilation time //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size //~| NOTE try explicitly collecting into a `Vec<{integer}>` - //~| NOTE required by an implicit `Sized` bound in `collect` //~| NOTE required by a bound in `collect` - //~| NOTE all local variables must have a statically known size - //~| NOTE doesn't have a size known at compile-time //~| NOTE doesn't have a size known at compile-time process_slice(&some_generated_vec); diff --git a/tests/ui/iterators/collect-into-slice.stderr b/tests/ui/iterators/collect-into-slice.stderr index 56f1bf770607e..b0abbd6123e3c 100644 --- a/tests/ui/iterators/collect-into-slice.stderr +++ b/tests/ui/iterators/collect-into-slice.stderr @@ -8,16 +8,6 @@ LL | let some_generated_vec = (0..10).collect(); note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL -error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/collect-into-slice.rs:6:9 - | -LL | let some_generated_vec = (0..10).collect(); - | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[i32]` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature - error[E0277]: the size for values of type `[i32]` cannot be known at compilation time --> $DIR/collect-into-slice.rs:6:38 | @@ -25,11 +15,10 @@ LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` -note: required by an implicit `Sized` bound in `collect` - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` error[E0277]: a slice of type `&[i32]` cannot be built since we need to store the elements somewhere - --> $DIR/collect-into-slice.rs:18:38 + --> $DIR/collect-into-slice.rs:14:38 | LL | let some_generated_vec = (0..10).collect(); | ^^^^^^^ try explicitly collecting into a `Vec<{integer}>` @@ -38,6 +27,6 @@ LL | let some_generated_vec = (0..10).collect(); note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/iterators/float_iterator_hint.rs b/tests/ui/iterators/float_iterator_hint.rs index a3335ca41f77e..6eba65c08981c 100644 --- a/tests/ui/iterators/float_iterator_hint.rs +++ b/tests/ui/iterators/float_iterator_hint.rs @@ -4,12 +4,12 @@ fn main() { for i in 0.2 { //~^ ERROR `{float}` is not an iterator //~| `{float}` is not an iterator + //~| NOTE if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` + //~| NOTE required for `{float}` to implement `IntoIterator` //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE in this expansion of desugaring of `for` loop - //~| NOTE if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` - //~| NOTE required for `{float}` to implement `IntoIterator` println!(); } } diff --git a/tests/ui/kinds-of-primitive-impl.stderr b/tests/ui/kinds-of-primitive-impl.stderr index 1c8c417e88c1f..d1b047aa4443f 100644 --- a/tests/ui/kinds-of-primitive-impl.stderr +++ b/tests/ui/kinds-of-primitive-impl.stderr @@ -38,7 +38,7 @@ LL | fn bar(self) {} | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn bar(&self) {} diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr index 0bc396390d7d2..882ec59171b8a 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.new.stderr @@ -19,13 +19,13 @@ LL | f() | call expression requires function error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time - --> $DIR/avoid-ice-on-warning-2.rs:4:10 + --> $DIR/avoid-ice-on-warning-2.rs:4:13 | LL | fn id(f: Copy) -> usize { - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn id(f: impl Copy) -> usize { diff --git a/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr index f1f33a6c6d671..fcfbcaaeb64d0 100644 --- a/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr +++ b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr @@ -47,13 +47,13 @@ LL | f() | call expression requires function error[E0277]: the size for values of type `(dyn Copy + 'static)` cannot be known at compilation time - --> $DIR/avoid-ice-on-warning-2.rs:4:10 + --> $DIR/avoid-ice-on-warning-2.rs:4:13 | LL | fn id(f: Copy) -> usize { - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Copy + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn id(f: impl Copy) -> usize { diff --git a/tests/ui/resolve/issue-3907-2.stderr b/tests/ui/resolve/issue-3907-2.stderr index 364edb788c68a..2d2d7aa06ff93 100644 --- a/tests/ui/resolve/issue-3907-2.stderr +++ b/tests/ui/resolve/issue-3907-2.stderr @@ -11,13 +11,13 @@ LL | fn bar(); | ^^^ the trait cannot be made into an object because associated function `bar` has no `self` parameter error[E0277]: the size for values of type `(dyn issue_3907::Foo + 'static)` cannot be known at compilation time - --> $DIR/issue-3907-2.rs:11:8 + --> $DIR/issue-3907-2.rs:11:12 | LL | fn bar(_x: Foo) {} - | ^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn issue_3907::Foo + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn bar(_x: &Foo) {} diff --git a/tests/ui/resolve/issue-5035-2.stderr b/tests/ui/resolve/issue-5035-2.stderr index 30721c0a206e7..5970a2540994d 100644 --- a/tests/ui/resolve/issue-5035-2.stderr +++ b/tests/ui/resolve/issue-5035-2.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `(dyn I + 'static)` cannot be known at compilation time - --> $DIR/issue-5035-2.rs:4:8 + --> $DIR/issue-5035-2.rs:4:12 | LL | fn foo(_x: K) {} - | ^^ doesn't have a size known at compile-time + | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn I + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo(_x: &K) {} diff --git a/tests/ui/sized/let-ref-pat-unsized-works.rs b/tests/ui/sized/let-ref-pat-unsized-works.rs new file mode 100644 index 0000000000000..e10ab17cfb6c7 --- /dev/null +++ b/tests/ui/sized/let-ref-pat-unsized-works.rs @@ -0,0 +1,11 @@ +//@ build-pass +#![allow(unused)] + +fn main() { + let ref x: str = *""; +} + +fn foo(r: &(usize, str)) -> usize { + let (x, _): (usize, str) = *r; + x +} diff --git a/tests/ui/sized/unsized-binding.rs b/tests/ui/sized/unsized-binding.rs index 3b99b0f6e9654..ea824048223c4 100644 --- a/tests/ui/sized/unsized-binding.rs +++ b/tests/ui/sized/unsized-binding.rs @@ -1,5 +1,17 @@ +struct Foo(i32, T); +trait T {} + +fn bar() -> dyn T { //~ ERROR E0746 + panic!() +} + fn main() { let x = *""; //~ ERROR E0277 println!("{}", x); println!("{}", x); + let Foo(a, b) = Foo(1, bar()); + //~^ ERROR E0277 + //~| ERROR E0277 + // The second error above could be deduplicated if we remove or unify the additional `note` + // explaining unsized locals and fn arguments. } diff --git a/tests/ui/sized/unsized-binding.stderr b/tests/ui/sized/unsized-binding.stderr index 7c3276032c2b4..ebc8ff503afb1 100644 --- a/tests/ui/sized/unsized-binding.stderr +++ b/tests/ui/sized/unsized-binding.stderr @@ -1,13 +1,48 @@ +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/unsized-binding.rs:4:13 + | +LL | fn bar() -> dyn T { + | ^^^^^ doesn't have a size known at compile-time + | + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` + | +LL | fn bar() -> impl T { + | ~~~~ +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` + | +LL ~ fn bar() -> Box { +LL ~ Box::new(panic!()) + | + error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-binding.rs:2:9 + --> $DIR/unsized-binding.rs:9:13 | LL | let x = *""; - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` + +error[E0277]: the size for values of type `dyn T` cannot be known at compilation time + --> $DIR/unsized-binding.rs:12:28 + | +LL | let Foo(a, b) = Foo(1, bar()); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn T` + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` + +error[E0277]: the size for values of type `dyn T` cannot be known at compilation time + --> $DIR/unsized-binding.rs:12:28 + | +LL | let Foo(a, b) = Foo(1, bar()); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn T` + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` -error: aborting due to 1 previous error +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0746. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/sized/unsized-return.rs b/tests/ui/sized/unsized-return.rs new file mode 100644 index 0000000000000..1963b3dc825ac --- /dev/null +++ b/tests/ui/sized/unsized-return.rs @@ -0,0 +1,10 @@ +trait T {} + +fn foo() -> dyn T { //~ E0746 + todo!() +} + +fn main() { + let x = foo(); //~ ERROR E0277 + let x: dyn T = foo(); //~ ERROR E0277 +} diff --git a/tests/ui/sized/unsized-return.stderr b/tests/ui/sized/unsized-return.stderr new file mode 100644 index 0000000000000..8b15cabb41dd0 --- /dev/null +++ b/tests/ui/sized/unsized-return.stderr @@ -0,0 +1,43 @@ +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/unsized-return.rs:3:13 + | +LL | fn foo() -> dyn T { + | ^^^^^ doesn't have a size known at compile-time + | + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` + | +LL | fn foo() -> impl T { + | ~~~~ +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` + | +LL ~ fn foo() -> Box { +LL ~ Box::new(todo!()) + | + +error[E0277]: the size for values of type `dyn T` cannot be known at compilation time + --> $DIR/unsized-return.rs:9:12 + | +LL | let x: dyn T = foo(); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn T` + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` +help: borrowed types have a statically known size + | +LL | let x: &dyn T = foo(); + | + + +error[E0277]: the size for values of type `dyn T` cannot be known at compilation time + --> $DIR/unsized-return.rs:8:13 + | +LL | let x = foo(); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn T` + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0746. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/str/str-array-assignment.stderr b/tests/ui/str/str-array-assignment.stderr index 515cb9e12f858..5915dcac0c010 100644 --- a/tests/ui/str/str-array-assignment.stderr +++ b/tests/ui/str/str-array-assignment.stderr @@ -18,15 +18,14 @@ LL | let u: &str = if true { &s[..2] } else { s }; | + error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/str-array-assignment.rs:7:7 + --> $DIR/str-array-assignment.rs:7:11 | LL | let v = s[..2]; - | ^ doesn't have a size known at compile-time + | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature -help: consider borrowing here + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` +help: borrowed values have a statically known size | LL | let v = &s[..2]; | + diff --git a/tests/ui/suggestions/object-unsafe-trait-references-self.stderr b/tests/ui/suggestions/object-unsafe-trait-references-self.stderr index 6427006847115..668a1554a17a0 100644 --- a/tests/ui/suggestions/object-unsafe-trait-references-self.stderr +++ b/tests/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -32,12 +32,12 @@ LL | trait Other: Sized {} | this trait cannot be made into an object... error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/object-unsafe-trait-references-self.rs:2:19 + --> $DIR/object-unsafe-trait-references-self.rs:2:22 | LL | fn baz(&self, _: Self) {} - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider further restricting `Self` | LL | fn baz(&self, _: Self) where Self: Sized {} diff --git a/tests/ui/suggestions/path-by-value.stderr b/tests/ui/suggestions/path-by-value.stderr index 46002d4e257e6..03a169b29e0d9 100644 --- a/tests/ui/suggestions/path-by-value.stderr +++ b/tests/ui/suggestions/path-by-value.stderr @@ -1,13 +1,13 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/path-by-value.rs:3:6 + --> $DIR/path-by-value.rs:3:9 | LL | fn f(p: Path) { } - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: within `Path`, the trait `Sized` is not implemented for `[u8]`, which is required by `Path: Sized` note: required because it appears within the type `Path` --> $SRC_DIR/std/src/path.rs:LL:COL - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn f(p: &Path) { } diff --git a/tests/ui/suggestions/unsized-function-parameter.fixed b/tests/ui/suggestions/unsized-function-parameter.fixed index 24f0698f176e4..11ac038898888 100644 --- a/tests/ui/suggestions/unsized-function-parameter.fixed +++ b/tests/ui/suggestions/unsized-function-parameter.fixed @@ -5,19 +5,19 @@ fn foo1(bar: &str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` -//~| HELP unsized fn params are gated as an unstable feature +//~| HELP unsized fn params are gated as unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo2(_bar: &str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` -//~| HELP unsized fn params are gated as an unstable feature +//~| HELP unsized fn params are gated as unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo3(_: &str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` -//~| HELP unsized fn params are gated as an unstable feature +//~| HELP unsized fn params are gated as unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn main() {} diff --git a/tests/ui/suggestions/unsized-function-parameter.rs b/tests/ui/suggestions/unsized-function-parameter.rs index b2c6aa4ee060a..9573205cc50bd 100644 --- a/tests/ui/suggestions/unsized-function-parameter.rs +++ b/tests/ui/suggestions/unsized-function-parameter.rs @@ -5,19 +5,19 @@ fn foo1(bar: str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` -//~| HELP unsized fn params are gated as an unstable feature +//~| HELP unsized fn params are gated as unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo2(_bar: str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` -//~| HELP unsized fn params are gated as an unstable feature +//~| HELP unsized fn params are gated as unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn foo3(_: str) {} //~^ ERROR the size for values of type `str` cannot be known at compilation time //~| HELP the trait `Sized` is not implemented for `str` -//~| HELP unsized fn params are gated as an unstable feature +//~| HELP unsized fn params are gated as unstable feature //~| HELP function arguments must have a statically known size, borrowed types always have a known size fn main() {} diff --git a/tests/ui/suggestions/unsized-function-parameter.stderr b/tests/ui/suggestions/unsized-function-parameter.stderr index 55d8d1ab1bc06..036234380efa1 100644 --- a/tests/ui/suggestions/unsized-function-parameter.stderr +++ b/tests/ui/suggestions/unsized-function-parameter.stderr @@ -1,37 +1,37 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-function-parameter.rs:5:9 + --> $DIR/unsized-function-parameter.rs:5:14 | LL | fn foo1(bar: str) {} - | ^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo1(bar: &str) {} | + error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-function-parameter.rs:11:9 + --> $DIR/unsized-function-parameter.rs:11:15 | LL | fn foo2(_bar: str) {} - | ^^^^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo2(_bar: &str) {} | + error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/unsized-function-parameter.rs:17:9 + --> $DIR/unsized-function-parameter.rs:17:12 | LL | fn foo3(_: str) {} - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: function arguments must have a statically known size, borrowed types always have a known size | LL | fn foo3(_: &str) {} diff --git a/tests/ui/trait-bounds/apit-unsized.stderr b/tests/ui/trait-bounds/apit-unsized.stderr index 0f2dc52599f63..4d19b26281e57 100644 --- a/tests/ui/trait-bounds/apit-unsized.stderr +++ b/tests/ui/trait-bounds/apit-unsized.stderr @@ -1,12 +1,10 @@ error[E0277]: the size for values of type `impl Iterator + ?Sized` cannot be known at compilation time - --> $DIR/apit-unsized.rs:1:8 + --> $DIR/apit-unsized.rs:1:11 | LL | fn foo(_: impl Iterator + ?Sized) {} - | ^ ---------------------------------- this type parameter needs to be `Sized` - | | - | doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn foo(_: impl Iterator + ?Sized) {} @@ -18,14 +16,12 @@ LL | fn foo(_: &impl Iterator + ?Sized) {} | + error[E0277]: the size for values of type `impl ?Sized` cannot be known at compilation time - --> $DIR/apit-unsized.rs:2:8 + --> $DIR/apit-unsized.rs:2:11 | LL | fn bar(_: impl ?Sized) {} - | ^ ----------- this type parameter needs to be `Sized` - | | - | doesn't have a size known at compile-time + | ^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider replacing `?Sized` with `Sized` | LL - fn bar(_: impl ?Sized) {} diff --git a/tests/ui/traits/alias/dont-elaborate-non-self.stderr b/tests/ui/traits/alias/dont-elaborate-non-self.stderr index 4e2edb474c06a..f6edfd7cdf572 100644 --- a/tests/ui/traits/alias/dont-elaborate-non-self.stderr +++ b/tests/ui/traits/alias/dont-elaborate-non-self.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `(dyn Fn() -> Fut + 'static)` cannot be known at compilation time - --> $DIR/dont-elaborate-non-self.rs:7:11 + --> $DIR/dont-elaborate-non-self.rs:7:14 | LL | fn f(a: dyn F) {} - | ^ doesn't have a size known at compile-time + | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Fn() -> Fut + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn f(a: impl F) {} diff --git a/tests/ui/traits/bound/not-on-bare-trait-2021.rs b/tests/ui/traits/bound/not-on-bare-trait-2021.rs index 07b866cb4a65b..58d9e7d0aa4ff 100644 --- a/tests/ui/traits/bound/not-on-bare-trait-2021.rs +++ b/tests/ui/traits/bound/not-on-bare-trait-2021.rs @@ -6,14 +6,25 @@ trait Foo { // This should emit the less confusing error, not the more confusing one. fn foo(_x: Foo + Send) { - //~^ ERROR trait objects must include the `dyn` keyword - //~| ERROR size for values of type + //~^ ERROR size for values of type } fn bar(x: Foo) -> Foo { + //~^ ERROR size for values of type + x +} +fn bat(x: &Foo) -> Foo { + //~^ ERROR return type cannot have an unboxed trait object + //~| ERROR trait objects must include the `dyn` keyword + x +} +fn bae(x: &Foo) -> &Foo { //~^ ERROR trait objects must include the `dyn` keyword //~| ERROR trait objects must include the `dyn` keyword - //~| ERROR size for values of type x } +fn qux() -> Foo { + //~^ ERROR return type cannot have an unboxed trait object + todo!() +} fn main() {} diff --git a/tests/ui/traits/bound/not-on-bare-trait-2021.stderr b/tests/ui/traits/bound/not-on-bare-trait-2021.stderr index 57d3bc8f10948..e5722edfc5a04 100644 --- a/tests/ui/traits/bound/not-on-bare-trait-2021.stderr +++ b/tests/ui/traits/bound/not-on-bare-trait-2021.stderr @@ -1,11 +1,11 @@ error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time - --> $DIR/not-on-bare-trait-2021.rs:8:8 + --> $DIR/not-on-bare-trait-2021.rs:8:12 | LL | fn foo(_x: Foo + Send) { - | ^^ doesn't have a size known at compile-time + | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn foo(_x: impl Foo + Send) { @@ -16,13 +16,13 @@ LL | fn foo(_x: &(dyn Foo + Send)) { | +++++ + error[E0277]: the size for values of type `(dyn Foo + 'static)` cannot be known at compilation time - --> $DIR/not-on-bare-trait-2021.rs:12:8 + --> $DIR/not-on-bare-trait-2021.rs:11:11 | LL | fn bar(x: Foo) -> Foo { - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn bar(x: impl Foo) -> Foo { @@ -32,60 +32,80 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn bar(x: &dyn Foo) -> Foo { | ++++ -error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/not-on-bare-trait-2021.rs:8:12 +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/not-on-bare-trait-2021.rs:15:20 | -LL | fn foo(_x: Foo + Send) { - | ^^^^^^^^^^ +LL | fn bat(x: &Foo) -> Foo { + | ^^^ doesn't have a size known at compile-time | -help: use a new generic type parameter, constrained by `Foo + Send` +help: return an `impl Trait` instead of a `dyn Trait` | -LL | fn foo(_x: T) { - | +++++++++++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference +LL | fn bat(x: &Foo) -> impl Foo { + | ++++ +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | -LL | fn foo(_x: impl Foo + Send) { - | ++++ -help: alternatively, use a trait object to accept any type that implements `Foo + Send`, accessing its methods at runtime using dynamic dispatch +LL ~ fn bat(x: &Foo) -> Box { +LL | +LL | +LL ~ Box::new(x) | -LL | fn foo(_x: &(dyn Foo + Send)) { - | +++++ + +help: finally, you might be able to borrow from the function's argument + | +LL | fn bat(x: &Foo) -> &dyn Foo { + | ++++ -error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/not-on-bare-trait-2021.rs:12:11 +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/not-on-bare-trait-2021.rs:25:13 | -LL | fn bar(x: Foo) -> Foo { - | ^^^ +LL | fn qux() -> Foo { + | ^^^ doesn't have a size known at compile-time | -help: use a new generic type parameter, constrained by `Foo` + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` | -LL | fn bar(x: T) -> Foo { - | ++++++++ ~ -help: you can also use an opaque type, but users won't be able to specify the type parameter when calling the `fn`, having to rely exclusively on type inference +LL | fn qux() -> impl Foo { + | ++++ +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | -LL | fn bar(x: impl Foo) -> Foo { - | ++++ -help: alternatively, use a trait object to accept any type that implements `Foo`, accessing its methods at runtime using dynamic dispatch +LL ~ fn qux() -> Box { +LL | +LL ~ Box::new(todo!()) | -LL | fn bar(x: &dyn Foo) -> Foo { - | ++++ error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/not-on-bare-trait-2021.rs:12:19 + --> $DIR/not-on-bare-trait-2021.rs:15:12 | -LL | fn bar(x: Foo) -> Foo { - | ^^^ +LL | fn bat(x: &Foo) -> Foo { + | ^^^ + | +help: add `dyn` keyword before this trait + | +LL | fn bat(x: &dyn Foo) -> Foo { + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/not-on-bare-trait-2021.rs:20:12 + | +LL | fn bae(x: &Foo) -> &Foo { + | ^^^ + | +help: add `dyn` keyword before this trait + | +LL | fn bae(x: &dyn Foo) -> &Foo { + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/not-on-bare-trait-2021.rs:20:21 | -help: use `impl Foo` to return an opaque type, as long as you return a single underlying type +LL | fn bae(x: &Foo) -> &Foo { + | ^^^ | -LL | fn bar(x: Foo) -> impl Foo { - | ++++ -help: alternatively, you can return an owned trait object +help: add `dyn` keyword before this trait | -LL | fn bar(x: Foo) -> Box { - | +++++++ + +LL | fn bae(x: &Foo) -> &dyn Foo { + | +++ -error: aborting due to 5 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0277, E0782. +Some errors have detailed explanations: E0277, E0746, E0782. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/bound/not-on-bare-trait.rs b/tests/ui/traits/bound/not-on-bare-trait.rs index 9e717f3c045e3..ce54bf8c02a4a 100644 --- a/tests/ui/traits/bound/not-on-bare-trait.rs +++ b/tests/ui/traits/bound/not-on-bare-trait.rs @@ -12,5 +12,28 @@ fn foo(_x: Foo + Send) { fn bar(_x: (dyn Foo + Send)) { //~^ ERROR the size for values of type } +fn bat(x: &Foo) -> Foo { + //~^ ERROR return type cannot have an unboxed trait object + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + //~| WARN this is accepted in the current edition + //~| WARN this is accepted in the current edition + x +} +fn bae(x: &Foo) -> &Foo { + //~^ WARN trait objects without an explicit `dyn` are deprecated + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + //~| WARN this is accepted in the current edition + x +} +fn qux() -> Foo { + //~^ ERROR return type cannot have an unboxed trait object + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + todo!() +} fn main() {} diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr index f1e7a28654a74..f14eabf7c6801 100644 --- a/tests/ui/traits/bound/not-on-bare-trait.stderr +++ b/tests/ui/traits/bound/not-on-bare-trait.stderr @@ -12,14 +12,79 @@ help: if this is an object-safe trait, use `dyn` LL | fn foo(_x: dyn Foo + Send) { | +++ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/not-on-bare-trait.rs:15:12 + | +LL | fn bat(x: &Foo) -> Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is an object-safe trait, use `dyn` + | +LL | fn bat(x: &dyn Foo) -> Foo { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/not-on-bare-trait.rs:15:20 + | +LL | fn bat(x: &Foo) -> Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is an object-safe trait, use `dyn` + | +LL | fn bat(x: &Foo) -> dyn Foo { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/not-on-bare-trait.rs:25:12 + | +LL | fn bae(x: &Foo) -> &Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is an object-safe trait, use `dyn` + | +LL | fn bae(x: &dyn Foo) -> &Foo { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/not-on-bare-trait.rs:25:21 + | +LL | fn bae(x: &Foo) -> &Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is an object-safe trait, use `dyn` + | +LL | fn bae(x: &Foo) -> &dyn Foo { + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/not-on-bare-trait.rs:32:13 + | +LL | fn qux() -> Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is an object-safe trait, use `dyn` + | +LL | fn qux() -> dyn Foo { + | +++ + error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time - --> $DIR/not-on-bare-trait.rs:7:8 + --> $DIR/not-on-bare-trait.rs:7:12 | LL | fn foo(_x: Foo + Send) { - | ^^ doesn't have a size known at compile-time + | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn foo(_x: impl Foo + Send) { @@ -30,13 +95,13 @@ LL | fn foo(_x: &(dyn Foo + Send)) { | +++++ + error[E0277]: the size for values of type `(dyn Foo + Send + 'static)` cannot be known at compilation time - --> $DIR/not-on-bare-trait.rs:12:8 + --> $DIR/not-on-bare-trait.rs:12:12 | LL | fn bar(_x: (dyn Foo + Send)) { - | ^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Foo + Send + 'static)` - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: you can use `impl Trait` as the argument type | LL | fn bar(_x: (impl Foo + Send)) { @@ -46,6 +111,64 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn bar(_x: (&(dyn Foo + Send))) { | ++ + -error: aborting due to 2 previous errors; 1 warning emitted +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/not-on-bare-trait.rs:15:20 + | +LL | fn bat(x: &Foo) -> Foo { + | ^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: if this is an object-safe trait, use `dyn` + | +LL | fn bat(x: &Foo) -> dyn Foo { + | +++ + +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/not-on-bare-trait.rs:15:20 + | +LL | fn bat(x: &Foo) -> Foo { + | ^^^ doesn't have a size known at compile-time + | +help: return an `impl Trait` instead of a `dyn Trait` + | +LL | fn bat(x: &Foo) -> impl Foo { + | ++++ +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` + | +LL ~ fn bat(x: &Foo) -> Box { +LL | + ... +LL | +LL ~ Box::new(x) + | +help: finally, you might be able to borrow from the function's argument + | +LL | fn bat(x: &Foo) -> &dyn Foo { + | ++++ + +error[E0746]: return type cannot have an unboxed trait object + --> $DIR/not-on-bare-trait.rs:32:13 + | +LL | fn qux() -> Foo { + | ^^^ doesn't have a size known at compile-time + | + = help: if the returned value came from a borrowed argument that implements the trait, then you could return `&dyn Trait` +help: return an `impl Trait` instead of a `dyn Trait` + | +LL | fn qux() -> impl Foo { + | ++++ +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` + | +LL ~ fn qux() -> Box { +LL | +LL | +LL | +LL ~ Box::new(todo!()) + | + +error: aborting due to 4 previous errors; 7 warnings emitted -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0746. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/type/type-check/unknown_type_for_closure.stderr b/tests/ui/type/type-check/unknown_type_for_closure.stderr index e5e29aabf374b..4a9212862bd60 100644 --- a/tests/ui/type/type-check/unknown_type_for_closure.stderr +++ b/tests/ui/type/type-check/unknown_type_for_closure.stderr @@ -16,10 +16,10 @@ LL | let x = |_: /* Type */| {}; | ++++++++++++ error[E0282]: type annotations needed - --> $DIR/unknown_type_for_closure.rs:10:14 + --> $DIR/unknown_type_for_closure.rs:10:17 | LL | let x = |k: _| {}; - | ^ cannot infer type + | ^ cannot infer type error[E0282]: type annotations needed --> $DIR/unknown_type_for_closure.rs:14:28 diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 7977504dae1d6..39301af7e7a50 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -358,10 +358,10 @@ LL ~ b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:128:18 + --> $DIR/typeck_type_placeholder_item.rs:128:21 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } - | ^ cannot infer type + | ^ cannot infer type error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:128:28 diff --git a/tests/ui/unsized-locals/issue-30276-feature-flagged.stderr b/tests/ui/unsized-locals/issue-30276-feature-flagged.stderr index ee8e4f3eee26b..ea6bc7c5ab62d 100644 --- a/tests/ui/unsized-locals/issue-30276-feature-flagged.stderr +++ b/tests/ui/unsized-locals/issue-30276-feature-flagged.stderr @@ -14,8 +14,7 @@ LL | let _x: fn(_) -> Test = Test; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` - = note: all function arguments must have a statically known size - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/unsized-locals/issue-30276.stderr b/tests/ui/unsized-locals/issue-30276.stderr index 15f70b18b3245..38cee287d85cb 100644 --- a/tests/ui/unsized-locals/issue-30276.stderr +++ b/tests/ui/unsized-locals/issue-30276.stderr @@ -5,8 +5,7 @@ LL | let _x: fn(_) -> Test = Test; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` - = note: all function arguments must have a statically known size - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` error: aborting due to 1 previous error diff --git a/tests/ui/unsized-locals/issue-50940.stderr b/tests/ui/unsized-locals/issue-50940.stderr index 160e14794d514..234f13d6742d0 100644 --- a/tests/ui/unsized-locals/issue-50940.stderr +++ b/tests/ui/unsized-locals/issue-50940.stderr @@ -5,8 +5,7 @@ LL | A as fn(str) -> A; | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: all function arguments must have a statically known size - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` error: aborting due to 1 previous error diff --git a/tests/ui/unsized-locals/issue-67981.stderr b/tests/ui/unsized-locals/issue-67981.stderr index e1fa41de2a80a..d9c8d14432cf8 100644 --- a/tests/ui/unsized-locals/issue-67981.stderr +++ b/tests/ui/unsized-locals/issue-67981.stderr @@ -5,7 +5,6 @@ LL | let f: fn([u8]) = |_| {}; | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all function arguments must have a statically known size error: aborting due to 1 previous error diff --git a/tests/ui/unsized-locals/suggest-borrow.stderr b/tests/ui/unsized-locals/suggest-borrow.stderr index 8741b35cdcff8..c2750cd958186 100644 --- a/tests/ui/unsized-locals/suggest-borrow.stderr +++ b/tests/ui/unsized-locals/suggest-borrow.stderr @@ -1,13 +1,12 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/suggest-borrow.rs:2:9 + --> $DIR/suggest-borrow.rs:2:12 | LL | let x: [u8] = vec!(1, 2, 3)[..]; - | ^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature -help: consider borrowing here + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` +help: borrowed types have a statically known size | LL | let x: &[u8] = vec!(1, 2, 3)[..]; | + @@ -44,15 +43,14 @@ LL | let x: &[u8] = &vec!(1, 2, 3)[..]; | + error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/suggest-borrow.rs:4:9 + --> $DIR/suggest-borrow.rs:4:19 | LL | let x: [u8] = &vec!(1, 2, 3)[..]; - | ^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature -help: consider borrowing here + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` +help: borrowed types have a statically known size | LL | let x: &[u8] = &vec!(1, 2, 3)[..]; | + diff --git a/tests/ui/unsized-locals/unsized-exprs3.stderr b/tests/ui/unsized-locals/unsized-exprs3.stderr index 9dfedfd8ada78..4513033c1c942 100644 --- a/tests/ui/unsized-locals/unsized-exprs3.stderr +++ b/tests/ui/unsized-locals/unsized-exprs3.stderr @@ -5,8 +5,7 @@ LL | udrop as fn([u8]); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all function arguments must have a statically known size - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` error: aborting due to 1 previous error diff --git a/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr b/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr index ace5a87187b8d..60b95df276620 100644 --- a/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr +++ b/tests/ui/unsized-locals/unsized-locals-using-unsized-fn-params.stderr @@ -5,8 +5,7 @@ LL | fn f1(box box _b: Box>) {} | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` error[E0277]: the size for values of type `[i32]` cannot be known at compilation time --> $DIR/unsized-locals-using-unsized-fn-params.rs:8:12 @@ -15,19 +14,17 @@ LL | fn f2((_x, _y): (i32, [i32])) {} | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[i32]` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-locals-using-unsized-fn-params.rs:13:9 + --> $DIR/unsized-locals-using-unsized-fn-params.rs:13:15 | LL | let _foo: [u8] = *foo; - | ^^^^ doesn't have a size known at compile-time + | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature -help: consider borrowing here + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` +help: borrowed types have a statically known size | LL | let _foo: &[u8] = *foo; | + diff --git a/tests/ui/unsized/box-instead-of-dyn-fn.stderr b/tests/ui/unsized/box-instead-of-dyn-fn.stderr index f2828b384b254..b32af94128e7f 100644 --- a/tests/ui/unsized/box-instead-of-dyn-fn.stderr +++ b/tests/ui/unsized/box-instead-of-dyn-fn.stderr @@ -4,17 +4,21 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> dyn Fn() + 'a { | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> impl Fn() + 'a { | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL ~ fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> Box { LL | LL | if a % 2 == 0 { LL ~ Box::new(move || println!("{a}")) | +help: finally, you might be able to borrow from the function's argument + | +LL | fn print_on_or_the_other<'a>(a: i32, b: &'a String) -> &dyn Fn() + 'a { + | + error: aborting due to 1 previous error diff --git a/tests/ui/unsized/issue-30355.stderr b/tests/ui/unsized/issue-30355.stderr index cfbcd0aea901d..5519f38bc16bb 100644 --- a/tests/ui/unsized/issue-30355.stderr +++ b/tests/ui/unsized/issue-30355.stderr @@ -5,8 +5,7 @@ LL | &X(*Y) | ^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: all function arguments must have a statically known size - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` error: aborting due to 1 previous error diff --git a/tests/ui/unsized/issue-91801.stderr b/tests/ui/unsized/issue-91801.stderr index d1d652d1860f9..003d8e9e096ce 100644 --- a/tests/ui/unsized/issue-91801.stderr +++ b/tests/ui/unsized/issue-91801.stderr @@ -4,10 +4,14 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: box the return type, and wrap all of the returned values in `Box::new` +help: box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box> { | ++++ + +help: alternatively, you might be able to borrow from one of the function's arguments + | +LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> &Validator<'a> { + | + error: aborting due to 1 previous error diff --git a/tests/ui/unsized/issue-91803.stderr b/tests/ui/unsized/issue-91803.stderr index 632af02b4b6ce..bc09df6e13704 100644 --- a/tests/ui/unsized/issue-91803.stderr +++ b/tests/ui/unsized/issue-91803.stderr @@ -4,14 +4,18 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn or<'a>(first: &'static dyn Foo<'a>) -> dyn Foo<'a> { | ^^^^^^^^^^^ doesn't have a size known at compile-time | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type +help: return an `impl Trait` instead of a `dyn Trait` | LL | fn or<'a>(first: &'static dyn Foo<'a>) -> impl Foo<'a> { | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` +help: alternatively, box the return type to make a boxed trait object, and wrap all of the returned values in `Box::new` | LL | fn or<'a>(first: &'static dyn Foo<'a>) -> Box> { | ++++ + +help: finally, you might be able to borrow from the function's argument + | +LL | fn or<'a>(first: &'static dyn Foo<'a>) -> &dyn Foo<'a> { + | + error: aborting due to 1 previous error diff --git a/tests/ui/unsized/unsized-fn-arg.stderr b/tests/ui/unsized/unsized-fn-arg.stderr index c8a6622b80929..1a8438cff48e1 100644 --- a/tests/ui/unsized/unsized-fn-arg.stderr +++ b/tests/ui/unsized/unsized-fn-arg.stderr @@ -1,12 +1,12 @@ error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/unsized-fn-arg.rs:5:17 + --> $DIR/unsized-fn-arg.rs:5:20 | LL | fn f(t: T) {} - | - ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `Sized` | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f(t: T) {} diff --git a/tests/ui/unsized/unsized6.stderr b/tests/ui/unsized/unsized6.stderr index 56e7f60f9ff08..6bbbe88d24856 100644 --- a/tests/ui/unsized/unsized6.stderr +++ b/tests/ui/unsized/unsized6.stderr @@ -1,20 +1,19 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation time - --> $DIR/unsized6.rs:9:9 + --> $DIR/unsized6.rs:9:12 | LL | fn f1(x: &X) { | - this type parameter needs to be `Sized` ... LL | let y: Y; - | ^ doesn't have a size known at compile-time + | ^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f1(x: &X) { LL + fn f1(x: &X) { | -help: consider borrowing here +help: borrowed types have a statically known size | LL | let y: &Y; | + @@ -52,21 +51,20 @@ LL + fn f1(x: &X) { | error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:15:9 + --> $DIR/unsized6.rs:15:12 | LL | fn f2(x: &X) { | - this type parameter needs to be `Sized` LL | let y: X; - | ^ doesn't have a size known at compile-time + | ^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f2(x: &X) { LL + fn f2(x: &X) { | -help: consider borrowing here +help: borrowed types have a statically known size | LL | let y: &X; | + @@ -88,36 +86,34 @@ LL + fn f2(x: &X) { | error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:22:9 + --> $DIR/unsized6.rs:22:12 | LL | fn f3(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` LL | let y: X = *x1; - | ^ doesn't have a size known at compile-time + | ^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f3(x1: Box, x2: Box, x3: Box) { LL + fn f3(x1: Box, x2: Box, x3: Box) { | -help: consider borrowing here +help: borrowed types have a statically known size | LL | let y: &X = *x1; | + error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:24:9 + --> $DIR/unsized6.rs:24:13 | LL | fn f3(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` ... LL | let y = *x2; - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f3(x1: Box, x2: Box, x3: Box) { @@ -125,16 +121,15 @@ LL + fn f3(x1: Box, x2: Box, x3: Box) { | error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:26:10 + --> $DIR/unsized6.rs:26:19 | LL | fn f3(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` ... LL | let (y, z) = (*x3, 4); - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f3(x1: Box, x2: Box, x3: Box) { @@ -142,36 +137,34 @@ LL + fn f3(x1: Box, x2: Box, x3: Box) { | error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:30:9 + --> $DIR/unsized6.rs:30:12 | LL | fn f4(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` LL | let y: X = *x1; - | ^ doesn't have a size known at compile-time + | ^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f4(x1: Box, x2: Box, x3: Box) { LL + fn f4(x1: Box, x2: Box, x3: Box) { | -help: consider borrowing here +help: borrowed types have a statically known size | LL | let y: &X = *x1; | + error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:32:9 + --> $DIR/unsized6.rs:32:13 | LL | fn f4(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` ... LL | let y = *x2; - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f4(x1: Box, x2: Box, x3: Box) { @@ -179,16 +172,15 @@ LL + fn f4(x1: Box, x2: Box, x3: Box) { | error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:34:10 + --> $DIR/unsized6.rs:34:19 | LL | fn f4(x1: Box, x2: Box, x3: Box) { | - this type parameter needs to be `Sized` ... LL | let (y, z) = (*x3, 4); - | ^ doesn't have a size known at compile-time + | ^^^ doesn't have a size known at compile-time | - = note: all local variables must have a statically known size - = help: unsized locals are gated as an unstable feature + = help: unsized locals are gated as unstable feature `#[feature(unsized_locals)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f4(x1: Box, x2: Box, x3: Box) { @@ -196,14 +188,14 @@ LL + fn f4(x1: Box, x2: Box, x3: Box) { | error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:38:18 + --> $DIR/unsized6.rs:38:21 | LL | fn g1(x: X) {} - | - ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `Sized` | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn g1(x: X) {} @@ -215,14 +207,14 @@ LL | fn g1(x: &X) {} | + error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized6.rs:40:22 + --> $DIR/unsized6.rs:40:25 | LL | fn g2(x: X) {} - | - ^ doesn't have a size known at compile-time + | - ^ doesn't have a size known at compile-time | | | this type parameter needs to be `Sized` | - = help: unsized fn params are gated as an unstable feature + = help: unsized fn params are gated as unstable feature `#[feature(unsized_fn_params)]` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn g2(x: X) {}