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 7be45463f15..149bc6d2698 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -133,9 +133,6 @@ fn maybe_suggest_blanket_trait_impl( return; }; let sugg = self.add_generic_param_suggestion(generics, self_ty.span, &impl_trait_name); - if sugg.is_empty() { - return; - }; diag.multipart_suggestion( format!( "alternatively use a blanket implementation to implement `{of_trait_name}` for \ @@ -170,6 +167,10 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) - let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; // FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0` // and suggest `Trait0`. + // Functions are found in three different contexts. + // 1. Independent functions + // 2. Functions inside trait blocks + // 3. Functions inside impl blocks let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => { (sig, generics, None) @@ -180,6 +181,12 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) - owner_id, .. }) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))), + hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(sig, _), + generics, + owner_id, + .. + }) => (sig, generics, Some(tcx.parent(owner_id.to_def_id()))), _ => return false, }; let Ok(trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { @@ -187,6 +194,8 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) - }; let impl_sugg = vec![(self_ty.span.shrink_to_lo(), "impl ".to_string())]; let mut is_downgradable = true; + + // Check if trait object is safe for suggesting dynamic dispatch. let is_object_safe = match self_ty.kind { hir::TyKind::TraitObject(objects, ..) => { objects.iter().all(|(o, _)| match o.trait_ref.path.res { @@ -202,8 +211,15 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) - } _ => false, }; + + let borrowed = matches!( + tcx.parent_hir_node(self_ty.hir_id), + hir::Node::Ty(hir::Ty { kind: hir::TyKind::Ref(..), .. }) + ); + + // Suggestions for function return type. if let hir::FnRetTy::Return(ty) = sig.decl.output - && ty.hir_id == self_ty.hir_id + && ty.peel_refs().hir_id == self_ty.hir_id { let pre = if !is_object_safe { format!("`{trait_name}` is not object safe, ") @@ -214,14 +230,26 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) - "{pre}use `impl {trait_name}` to return an opaque type, as long as you return a \ single underlying type", ); + diag.multipart_suggestion_verbose(msg, impl_sugg, Applicability::MachineApplicable); + + // Suggest `Box` for return type if is_object_safe { - diag.multipart_suggestion_verbose( - "alternatively, you can return an owned trait object", + // If the return type is `&Trait`, we don't want + // the ampersand to be displayed in the `Box` + // suggestion. + let suggestion = if borrowed { + vec![(ty.span, format!("Box"))] + } else { vec![ (ty.span.shrink_to_lo(), "Box".to_string()), - ], + ] + }; + + diag.multipart_suggestion_verbose( + "alternatively, you can return an owned trait object", + suggestion, Applicability::MachineApplicable, ); } else if is_downgradable { @@ -230,24 +258,24 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) - } return true; } + + // Suggestions for function parameters. for ty in sig.decl.inputs { - if ty.hir_id != self_ty.hir_id { + if ty.peel_refs().hir_id != self_ty.hir_id { continue; } let sugg = self.add_generic_param_suggestion(generics, self_ty.span, &trait_name); - if !sugg.is_empty() { - diag.multipart_suggestion_verbose( - format!("use a new generic type parameter, constrained by `{trait_name}`"), - sugg, - Applicability::MachineApplicable, - ); - diag.multipart_suggestion_verbose( - "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", - impl_sugg, - Applicability::MachineApplicable, - ); - } + diag.multipart_suggestion_verbose( + format!("use a new generic type parameter, constrained by `{trait_name}`"), + sugg, + Applicability::MachineApplicable, + ); + diag.multipart_suggestion_verbose( + "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", + impl_sugg, + Applicability::MachineApplicable, + ); if !is_object_safe { diag.note(format!("`{trait_name}` it is not object safe, so it can't be `dyn`")); if is_downgradable { @@ -255,14 +283,18 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) - diag.downgrade_to_delayed_bug(); } } else { + // No ampersand in suggestion if it's borrowed already + let (dyn_str, paren_dyn_str) = + if borrowed { ("dyn ", "(dyn ") } else { ("&dyn ", "&(dyn ") }; + let sugg = if let hir::TyKind::TraitObject([_, _, ..], _, _) = self_ty.kind { // There are more than one trait bound, we need surrounding parentheses. vec![ - (self_ty.span.shrink_to_lo(), "&(dyn ".to_string()), + (self_ty.span.shrink_to_lo(), paren_dyn_str.to_string()), (self_ty.span.shrink_to_hi(), ")".to_string()), ] } else { - vec![(self_ty.span.shrink_to_lo(), "&dyn ".to_string())] + vec![(self_ty.span.shrink_to_lo(), dyn_str.to_string())] }; diag.multipart_suggestion_verbose( format!( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 5c663e0bf4b..45e157b1080 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -5023,24 +5023,32 @@ fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { } } +/// Suggest a new type parameter name for diagnostic purposes. +/// +/// `name` is the preferred name you'd like to suggest if it's not in use already. pub trait NextTypeParamName { fn next_type_param_name(&self, name: Option<&str>) -> String; } impl NextTypeParamName for &[hir::GenericParam<'_>] { fn next_type_param_name(&self, name: Option<&str>) -> String { - // This is the list of possible parameter names that we might suggest. + // Type names are usually single letters in uppercase. So convert the first letter of input string to uppercase. let name = name.and_then(|n| n.chars().next()).map(|c| c.to_uppercase().to_string()); let name = name.as_deref(); + + // This is the list of possible parameter names that we might suggest. let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"]; - let used_names = self + + // Filter out used names based on `filter_fn`. + let used_names: Vec = self .iter() - .filter_map(|p| match p.name { + .filter_map(|param| match param.name { hir::ParamName::Plain(ident) => Some(ident.name), _ => None, }) - .collect::>(); + .collect(); + // Find a name from `possible_names` that is not in `used_names`. possible_names .iter() .find(|n| !used_names.contains(&Symbol::intern(n))) diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr index b39689afd1c..52ee6c81ab7 100644 --- a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr +++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr @@ -4,7 +4,15 @@ error[E0782]: trait objects must include the `dyn` keyword LL | fn function(x: &SomeTrait, y: Box) { | ^^^^^^^^^ | -help: add `dyn` keyword before this trait +help: use a new generic type parameter, constrained by `SomeTrait` + | +LL | fn function(x: &T, y: Box) { + | ++++++++++++++ ~ +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 function(x: &impl SomeTrait, y: Box) { + | ++++ +help: alternatively, use a trait object to accept any type that implements `SomeTrait`, accessing its methods at runtime using dynamic dispatch | LL | fn function(x: &dyn SomeTrait, y: Box) { | +++ diff --git a/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs new file mode 100644 index 00000000000..dabaa309c16 --- /dev/null +++ b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs @@ -0,0 +1,142 @@ +//@ edition:2021 + +trait Trait {} + +struct IceCream; + +impl IceCream { + fn foo(_: &Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bar(self, _: &'a Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + //~| ERROR: use of undeclared lifetime name + + fn alice<'a>(&self, _: &Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bob<'a>(_: &'a Trait) {} + //~^ ERROR: trait objects must include the `dyn` keyword + + fn cat() -> &Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn dog<'a>() -> &Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn kitten() -> &'a Trait { + //~^ ERROR: use of undeclared lifetime name + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn puppy<'a>() -> &'a Trait { + //~^ ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn parrot() -> &mut Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &mut Type + //~^ ERROR: cannot return reference to temporary value + } +} + +trait Sing { + fn foo(_: &Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bar(_: &'a Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + //~| ERROR: use of undeclared lifetime name + + fn alice<'a>(_: &Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + + fn bob<'a>(_: &'a Trait); + //~^ ERROR: trait objects must include the `dyn` keyword + + fn cat() -> &Trait; + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + + fn dog<'a>() -> &Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn kitten() -> &'a Trait { + //~^ ERROR: use of undeclared lifetime name + //~| ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn puppy<'a>() -> &'a Trait { + //~^ ERROR: trait objects must include the `dyn` keyword + &Type + } + + fn parrot() -> &mut Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &mut Type + //~^ ERROR: cannot return reference to temporary value + } +} + +fn foo(_: &Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword + +fn bar(_: &'a Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword +//~| ERROR: use of undeclared lifetime name + +fn alice<'a>(_: &Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword + +fn bob<'a>(_: &'a Trait) {} +//~^ ERROR: trait objects must include the `dyn` keyword + +struct Type; + +impl Trait for Type {} + +fn cat() -> &Trait { +//~^ ERROR: missing lifetime specifier +//~| ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn dog<'a>() -> &Trait { +//~^ ERROR: missing lifetime specifier +//~| ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn kitten() -> &'a Trait { +//~^ ERROR: use of undeclared lifetime name +//~| ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn puppy<'a>() -> &'a Trait { +//~^ ERROR: trait objects must include the `dyn` keyword + &Type +} + +fn parrot() -> &mut Trait { + //~^ ERROR: missing lifetime specifier + //~| ERROR: trait objects must include the `dyn` keyword + &mut Type + //~^ ERROR: cannot return reference to temporary value +} + +fn main() {} diff --git a/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr new file mode 100644 index 00000000000..8bdfea7766e --- /dev/null +++ b/tests/ui/object-safety/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.stderr @@ -0,0 +1,673 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:11:22 + | +LL | fn bar(self, _: &'a Trait) {} + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn bar<'a>(self, _: &'a Trait) {} + | ++++ +help: consider introducing lifetime `'a` here + | +LL | impl<'a> IceCream { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:21:17 + | +LL | fn cat() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn cat() -> &'static Trait { + | +++++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:27:21 + | +LL | fn dog<'a>() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'a` lifetime + | +LL | fn dog<'a>() -> &'a Trait { + | ++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:33:21 + | +LL | fn kitten() -> &'a Trait { + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn kitten<'a>() -> &'a Trait { + | ++++ +help: consider introducing lifetime `'a` here + | +LL | impl<'a> IceCream { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:44:20 + | +LL | fn parrot() -> &mut Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn parrot() -> &'static mut Trait { + | +++++++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:16 + | +LL | fn bar(_: &'a Trait); + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn bar<'a>(_: &'a Trait); + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait Sing<'a> { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:17 + | +LL | fn cat() -> &Trait; + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn cat() -> &'static Trait; + | +++++++ +help: instead, you are more likely to want to return an owned value + | +LL - fn cat() -> &Trait; +LL + fn cat() -> Trait; + | + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:21 + | +LL | fn dog<'a>() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'a` lifetime + | +LL | fn dog<'a>() -> &'a Trait { + | ++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:21 + | +LL | fn kitten() -> &'a Trait { + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn kitten<'a>() -> &'a Trait { + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait Sing<'a> { + | ++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:20 + | +LL | fn parrot() -> &mut Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn parrot() -> &'static mut Trait { + | +++++++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:12 + | +LL | fn bar(_: &'a Trait) {} + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:13 + | +LL | fn cat() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn cat() -> &'static Trait { + | +++++++ + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:17 + | +LL | fn dog<'a>() -> &Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'a` lifetime + | +LL | fn dog<'a>() -> &'a Trait { + | ++ + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:17 + | +LL | fn kitten() -> &'a Trait { + | - ^^ undeclared lifetime + | | + | help: consider introducing lifetime `'a` here: `<'a>` + +error[E0106]: missing lifetime specifier + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:16 + | +LL | fn parrot() -> &mut Trait { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn parrot() -> &'static mut Trait { + | +++++++ + +error[E0515]: cannot return reference to temporary value + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:47:9 + | +LL | &mut Type + | ^^^^^---- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:90:9 + | +LL | &mut Type + | ^^^^^---- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:138:5 + | +LL | &mut Type + | ^^^^^---- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:53:16 + | +LL | fn foo(_: &Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn foo(_: &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 foo(_: &impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn foo(_: &dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:56:19 + | +LL | fn bar(_: &'a Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bar(_: &'a 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 bar(_: &'a impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bar(_: &'a dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:60:22 + | +LL | fn alice<'a>(_: &Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn alice<'a, T: Trait>(_: &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 alice<'a>(_: &impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn alice<'a>(_: &dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:63:23 + | +LL | fn bob<'a>(_: &'a Trait); + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bob<'a, T: Trait>(_: &'a 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 bob<'a>(_: &'a impl Trait); + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bob<'a>(_: &'a dyn Trait); + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:66:18 + | +LL | fn cat() -> &Trait; + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn cat() -> &impl Trait; + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn cat() -> Box; + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:70:22 + | +LL | fn dog<'a>() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn dog<'a>() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn dog<'a>() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:76:24 + | +LL | fn kitten() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn kitten() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn kitten() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:82:27 + | +LL | fn puppy<'a>() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn puppy<'a>() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn puppy<'a>() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:87:25 + | +LL | fn parrot() -> &mut Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn parrot() -> &mut impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn parrot() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:95:12 + | +LL | fn foo(_: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn foo(_: &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 foo(_: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn foo(_: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:98:15 + | +LL | fn bar(_: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bar(_: &'a 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 bar(_: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bar(_: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:102:18 + | +LL | fn alice<'a>(_: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn alice<'a, T: Trait>(_: &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 alice<'a>(_: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn alice<'a>(_: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:105:19 + | +LL | fn bob<'a>(_: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bob<'a, T: Trait>(_: &'a 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 bob<'a>(_: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bob<'a>(_: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:112:14 + | +LL | fn cat() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn cat() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn cat() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:118:18 + | +LL | fn dog<'a>() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn dog<'a>() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn dog<'a>() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:124:20 + | +LL | fn kitten() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn kitten() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn kitten() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:130:23 + | +LL | fn puppy<'a>() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn puppy<'a>() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn puppy<'a>() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:135:21 + | +LL | fn parrot() -> &mut Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn parrot() -> &mut impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn parrot() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:8:16 + | +LL | fn foo(_: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn foo(_: &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 foo(_: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn foo(_: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:11:25 + | +LL | fn bar(self, _: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bar(self, _: &'a 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 bar(self, _: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bar(self, _: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:15:29 + | +LL | fn alice<'a>(&self, _: &Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn alice<'a, T: Trait>(&self, _: &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 alice<'a>(&self, _: &impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn alice<'a>(&self, _: &dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:18:23 + | +LL | fn bob<'a>(_: &'a Trait) {} + | ^^^^^ + | +help: use a new generic type parameter, constrained by `Trait` + | +LL | fn bob<'a, T: Trait>(_: &'a 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 bob<'a>(_: &'a impl Trait) {} + | ++++ +help: alternatively, use a trait object to accept any type that implements `Trait`, accessing its methods at runtime using dynamic dispatch + | +LL | fn bob<'a>(_: &'a dyn Trait) {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:21:18 + | +LL | fn cat() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn cat() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn cat() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:27:22 + | +LL | fn dog<'a>() -> &Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn dog<'a>() -> &impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn dog<'a>() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:33:24 + | +LL | fn kitten() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn kitten() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn kitten() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:39:27 + | +LL | fn puppy<'a>() -> &'a Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn puppy<'a>() -> &'a impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn puppy<'a>() -> Box { + | ~~~~~~~~~~~~~~ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/reference-to-bare-trait-in-fn-inputs-and-outputs-issue-125139.rs:44:25 + | +LL | fn parrot() -> &mut Trait { + | ^^^^^ + | +help: use `impl Trait` to return an opaque type, as long as you return a single underlying type + | +LL | fn parrot() -> &mut impl Trait { + | ++++ +help: alternatively, you can return an owned trait object + | +LL | fn parrot() -> Box { + | ~~~~~~~~~~~~~~ + +error: aborting due to 45 previous errors + +Some errors have detailed explanations: E0106, E0261, E0515, E0782. +For more information about an error, try `rustc --explain E0106`.