From 3988ff25bc577a007926f016fac04333b1ea57bc Mon Sep 17 00:00:00 2001 From: yukang <moorekang@gmail.com> Date: Mon, 28 Aug 2023 16:57:29 +0800 Subject: [PATCH 1/9] suggest iter_mut() where trying to modify elements from .iter() --- .../src/diagnostics/mutability_errors.rs | 42 ++++++++++++++++++- .../issue-115259-suggest-iter-mut.fixed | 20 +++++++++ .../borrowck/issue-115259-suggest-iter-mut.rs | 20 +++++++++ .../issue-115259-suggest-iter-mut.stderr | 16 +++++++ .../issue-62387-suggest-iter-mut-2.fixed | 36 ++++++++++++++++ .../issue-62387-suggest-iter-mut-2.rs | 36 ++++++++++++++++ .../issue-62387-suggest-iter-mut-2.stderr | 16 +++++++ .../issue-62387-suggest-iter-mut.fixed | 30 +++++++++++++ .../borrowck/issue-62387-suggest-iter-mut.rs | 30 +++++++++++++ .../issue-62387-suggest-iter-mut.stderr | 29 +++++++++++++ 10 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 tests/ui/borrowck/issue-115259-suggest-iter-mut.fixed create mode 100644 tests/ui/borrowck/issue-115259-suggest-iter-mut.rs create mode 100644 tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr create mode 100644 tests/ui/borrowck/issue-62387-suggest-iter-mut-2.fixed create mode 100644 tests/ui/borrowck/issue-62387-suggest-iter-mut-2.rs create mode 100644 tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr create mode 100644 tests/ui/borrowck/issue-62387-suggest-iter-mut.fixed create mode 100644 tests/ui/borrowck/issue-62387-suggest-iter-mut.rs create mode 100644 tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 31e863b8a4ed6..54a557c514547 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1,9 +1,10 @@ +use hir::ExprKind; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt}; use rustc_middle::{ hir::place::PlaceBase, mir::{self, BindingForm, Local, LocalDecl, LocalInfo, LocalKind, Location}, @@ -491,6 +492,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ), ); + self.suggest_using_iter_mut(&mut err); self.suggest_make_local_mut(&mut err, local, name); } _ => { @@ -953,6 +955,44 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } + fn suggest_using_iter_mut(&self, err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>) { + let source = self.body.source; + let hir = self.infcx.tcx.hir(); + if let InstanceDef::Item(def_id) = source.instance + && let Some(Node::Expr(hir::Expr { hir_id, kind, ..})) = hir.get_if_local(def_id) + && let ExprKind::Closure(closure) = kind && closure.movability == None + && let Some(Node::Expr(expr)) = hir.find_parent(*hir_id) { + let mut cur_expr = expr; + while let ExprKind::MethodCall(path_segment, recv, _, _) = cur_expr.kind { + if path_segment.ident.name == sym::iter { + // check `_ty` has `iter_mut` method + let res = self + .infcx + .tcx + .typeck(path_segment.hir_id.owner.def_id) + .type_dependent_def_id(cur_expr.hir_id) + .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) + .map(|def_id| self.infcx.tcx.associated_items(def_id)) + .map(|assoc_items| { + assoc_items.filter_by_name_unhygienic(sym::iter_mut).peekable() + }); + + if let Some(mut res) = res && res.peek().is_some() { + err.span_suggestion_verbose( + path_segment.ident.span, + "you may want to use `iter_mut` here", + "iter_mut", + Applicability::MaybeIncorrect, + ); + } + break; + } else { + cur_expr = recv; + } + } + } + } + fn suggest_make_local_mut( &self, err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, diff --git a/tests/ui/borrowck/issue-115259-suggest-iter-mut.fixed b/tests/ui/borrowck/issue-115259-suggest-iter-mut.fixed new file mode 100644 index 0000000000000..4653fe7375d38 --- /dev/null +++ b/tests/ui/borrowck/issue-115259-suggest-iter-mut.fixed @@ -0,0 +1,20 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +pub trait Layer { + fn process(&mut self) -> u32; +} + +pub struct State { + layers: Vec<Box<dyn Layer>>, +} + +impl State { + pub fn process(&mut self) -> u32 { + self.layers.iter_mut().fold(0, |result, mut layer| result + layer.process()) + //~^ ERROR cannot borrow `**layer` as mutable, as it is behind a `&` reference + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-115259-suggest-iter-mut.rs b/tests/ui/borrowck/issue-115259-suggest-iter-mut.rs new file mode 100644 index 0000000000000..e0f6ab1321f83 --- /dev/null +++ b/tests/ui/borrowck/issue-115259-suggest-iter-mut.rs @@ -0,0 +1,20 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +pub trait Layer { + fn process(&mut self) -> u32; +} + +pub struct State { + layers: Vec<Box<dyn Layer>>, +} + +impl State { + pub fn process(&mut self) -> u32 { + self.layers.iter().fold(0, |result, mut layer| result + layer.process()) + //~^ ERROR cannot borrow `**layer` as mutable, as it is behind a `&` reference + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr b/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr new file mode 100644 index 0000000000000..7e0fc2cf298b0 --- /dev/null +++ b/tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr @@ -0,0 +1,16 @@ +error[E0596]: cannot borrow `**layer` as mutable, as it is behind a `&` reference + --> $DIR/issue-115259-suggest-iter-mut.rs:15:65 + | +LL | self.layers.iter().fold(0, |result, mut layer| result + layer.process()) + | --------- ^^^^^ `layer` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut Box<dyn Layer>` + | +help: you may want to use `iter_mut` here + | +LL | self.layers.iter_mut().fold(0, |result, mut layer| result + layer.process()) + | ~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.fixed b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.fixed new file mode 100644 index 0000000000000..f02374d8e11de --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.fixed @@ -0,0 +1,36 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] +use std::path::PathBuf; + +#[derive(Clone)] +struct Container { + things: Vec<PathBuf>, +} + +impl Container { + fn things(&mut self) -> &[PathBuf] { + &self.things + } +} + +// contains containers +struct ContainerContainer { + contained: Vec<Container>, +} + +impl ContainerContainer { + fn contained(&self) -> &[Container] { + &self.contained + } + + fn all_the_things(&mut self) -> &[PathBuf] { + let mut vec = self.contained.clone(); + let _a = + vec.iter_mut().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + //~^ ERROR cannot borrow `*container` as mutable, as it is behind a `&` reference + unimplemented!(); + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.rs b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.rs new file mode 100644 index 0000000000000..2d0b837a946ca --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.rs @@ -0,0 +1,36 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] +use std::path::PathBuf; + +#[derive(Clone)] +struct Container { + things: Vec<PathBuf>, +} + +impl Container { + fn things(&mut self) -> &[PathBuf] { + &self.things + } +} + +// contains containers +struct ContainerContainer { + contained: Vec<Container>, +} + +impl ContainerContainer { + fn contained(&self) -> &[Container] { + &self.contained + } + + fn all_the_things(&mut self) -> &[PathBuf] { + let mut vec = self.contained.clone(); + let _a = + vec.iter().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + //~^ ERROR cannot borrow `*container` as mutable, as it is behind a `&` reference + unimplemented!(); + } +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr new file mode 100644 index 0000000000000..19f194100a199 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr @@ -0,0 +1,16 @@ +error[E0596]: cannot borrow `*container` as mutable, as it is behind a `&` reference + --> $DIR/issue-62387-suggest-iter-mut-2.rs:30:45 + | +LL | vec.iter().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + | --------- ^^^^^^^^^ `container` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut Container` + | +help: you may want to use `iter_mut` here + | +LL | vec.iter_mut().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>(); + | ~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut.fixed b/tests/ui/borrowck/issue-62387-suggest-iter-mut.fixed new file mode 100644 index 0000000000000..8bf2625de6da6 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut.fixed @@ -0,0 +1,30 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +#[derive(Debug)] +struct A { + a: i32, +} + +impl A { + fn double(&mut self) { + self.a += self.a + } +} + +fn baz() { + let mut v = [A { a: 4 }]; + v.iter_mut().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn bar() { + let mut v = [A { a: 4 }]; + v.iter_mut().rev().rev().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut.rs b/tests/ui/borrowck/issue-62387-suggest-iter-mut.rs new file mode 100644 index 0000000000000..39bc30bf29452 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut.rs @@ -0,0 +1,30 @@ +// run-rustfix +#![allow(unused_mut)] +#![allow(dead_code)] + +#[derive(Debug)] +struct A { + a: i32, +} + +impl A { + fn double(&mut self) { + self.a += self.a + } +} + +fn baz() { + let mut v = [A { a: 4 }]; + v.iter().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn bar() { + let mut v = [A { a: 4 }]; + v.iter().rev().rev().for_each(|a| a.double()); + //~^ ERROR cannot borrow `*a` as mutable, as it is behind a `&` reference + println!("{:?}", v); +} + +fn main() {} diff --git a/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr b/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr new file mode 100644 index 0000000000000..fd58e43302025 --- /dev/null +++ b/tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr @@ -0,0 +1,29 @@ +error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference + --> $DIR/issue-62387-suggest-iter-mut.rs:18:27 + | +LL | v.iter().for_each(|a| a.double()); + | - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut A` + | +help: you may want to use `iter_mut` here + | +LL | v.iter_mut().for_each(|a| a.double()); + | ~~~~~~~~ + +error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference + --> $DIR/issue-62387-suggest-iter-mut.rs:25:39 + | +LL | v.iter().rev().rev().for_each(|a| a.double()); + | - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | | + | consider changing this binding's type to be: `&mut A` + | +help: you may want to use `iter_mut` here + | +LL | v.iter_mut().rev().rev().for_each(|a| a.double()); + | ~~~~~~~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0596`. From a8f3c7684df5ac15c770ef92d58436aa3386cfcf Mon Sep 17 00:00:00 2001 From: surechen <chenshuo17@huawei.com> Date: Wed, 6 Sep 2023 11:33:03 +0800 Subject: [PATCH 2/9] fixes #114896 --- .../src/diagnostics/mutability_errors.rs | 84 +++++++++++++++++-- tests/ui/pattern/issue-114896.rs | 7 ++ tests/ui/pattern/issue-114896.stderr | 11 +++ 3 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 tests/ui/pattern/issue-114896.rs create mode 100644 tests/ui/pattern/issue-114896.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 31e863b8a4ed6..1df4e94b9145a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -370,12 +370,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_label(span, format!("cannot {act}")); } if suggest { - err.span_suggestion_verbose( - local_decl.source_info.span.shrink_to_lo(), - "consider changing this to be mutable", - "mut ", - Applicability::MachineApplicable, - ); + self.construct_mut_suggestion_for_local_binding_patterns(&mut err, local); let tcx = self.infcx.tcx; if let ty::Closure(id, _) = *the_place_err.ty(self.body, tcx).ty.kind() { self.show_mutating_upvar(tcx, id.expect_local(), the_place_err, &mut err); @@ -710,6 +705,83 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ) } + fn construct_mut_suggestion_for_local_binding_patterns( + &self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + local: Local, + ) { + let local_decl = &self.body.local_decls[local]; + debug!("local_decl: {:?}", local_decl); + let pat_span = match *local_decl.local_info() { + LocalInfo::User(BindingForm::Var(mir::VarBindingForm { + binding_mode: ty::BindingMode::BindByValue(Mutability::Not), + opt_ty_info: _, + opt_match_place: _, + pat_span, + })) => pat_span, + _ => local_decl.source_info.span, + }; + + struct BindingFinder { + span: Span, + hir_id: Option<hir::HirId>, + } + + impl<'tcx> Visitor<'tcx> for BindingFinder { + fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) { + if let hir::StmtKind::Local(local) = s.kind { + if local.pat.span == self.span { + self.hir_id = Some(local.hir_id); + } + } + hir::intravisit::walk_stmt(self, s); + } + } + + let hir_map = self.infcx.tcx.hir(); + let def_id = self.body.source.def_id(); + let hir_id = if let Some(local_def_id) = def_id.as_local() + && let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) + { + let body = hir_map.body(body_id); + let mut v = BindingFinder { + span: pat_span, + hir_id: None, + }; + v.visit_body(body); + v.hir_id + } else { + None + }; + + // With ref-binding patterns, the mutability suggestion has to apply to + // the binding, not the reference (which would be a type error): + // + // `let &b = a;` -> `let &(mut b) = a;` + if let Some(hir_id) = hir_id + && let Some(hir::Node::Local(hir::Local { + pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. }, + .. + })) = hir_map.find(hir_id) + && let Ok(name) = self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span) + { + err.span_suggestion( + pat_span, + "consider changing this to be mutable", + format!("&(mut {name})"), + Applicability::MachineApplicable, + ); + return; + } + + err.span_suggestion_verbose( + local_decl.source_info.span.shrink_to_lo(), + "consider changing this to be mutable", + "mut ", + Applicability::MachineApplicable, + ); + } + // point to span of upvar making closure call require mutable borrow fn show_mutating_upvar( &self, diff --git a/tests/ui/pattern/issue-114896.rs b/tests/ui/pattern/issue-114896.rs new file mode 100644 index 0000000000000..cde37f658d6ae --- /dev/null +++ b/tests/ui/pattern/issue-114896.rs @@ -0,0 +1,7 @@ +fn main() { + fn x(a: &char) { + let &b = a; + b.make_ascii_uppercase(); +//~^ cannot borrow `b` as mutable, as it is not declared as mutable + } +} diff --git a/tests/ui/pattern/issue-114896.stderr b/tests/ui/pattern/issue-114896.stderr new file mode 100644 index 0000000000000..ffeb7bc136508 --- /dev/null +++ b/tests/ui/pattern/issue-114896.stderr @@ -0,0 +1,11 @@ +error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable + --> $DIR/issue-114896.rs:4:9 + | +LL | let &b = a; + | -- help: consider changing this to be mutable: `&(mut b)` +LL | b.make_ascii_uppercase(); + | ^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. From 8488c27860d3aeade58a562f6d8468142f139644 Mon Sep 17 00:00:00 2001 From: Jonas Schievink <jonasschievink@gmail.com> Date: Sat, 9 Sep 2023 12:22:06 +0200 Subject: [PATCH 3/9] Update mailmap --- .mailmap | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.mailmap b/.mailmap index c072f6282f19b..eb82cf4de8d0b 100644 --- a/.mailmap +++ b/.mailmap @@ -205,6 +205,10 @@ Gareth Daniel Smith <garethdanielsmith@gmail.com> gareth <gareth@gareth-N56VM.(n Gareth Daniel Smith <garethdanielsmith@gmail.com> Gareth Smith <garethdanielsmith@gmail.com> Gauri Kholkar <f2013002@goa.bits-pilani.ac.in> Georges Dubus <georges.dubus@gmail.com> <georges.dubus@compiletoi.net> +Ghost <ghost> <jonasschievink@gmail.com> +Ghost <ghost> <jonas.schievink@ferrous-systems.com> +Ghost <ghost> <jonas@schievink.net> +Ghost <ghost> <Jonas.Schievink@sony.com> Giles Cope <gilescope@gmail.com> Glen De Cauwsemaecker <decauwsemaecker.glen@gmail.com> Graham Fawcett <graham.fawcett@gmail.com> Graham Fawcett <fawcett@uwindsor.ca> From 254e13d9f9dd38817a28880b99acd29a2fcc5613 Mon Sep 17 00:00:00 2001 From: Ralf Jung <post@ralfj.de> Date: Sun, 10 Sep 2023 07:38:03 +0200 Subject: [PATCH 4/9] fix homogeneous_aggregate not ignoring some 1-ZST --- compiler/rustc_target/src/abi/call/mod.rs | 13 ++++-- tests/ui/abi/compatibility.rs | 10 +---- .../ui/layout/homogeneous-aggr-transparent.rs | 44 +++++++++++++++++++ .../homogeneous-aggr-transparent.stderr | 32 ++++++++++++++ 4 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 tests/ui/layout/homogeneous-aggr-transparent.rs create mode 100644 tests/ui/layout/homogeneous-aggr-transparent.stderr diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 5d75974279ed0..1a4a46ceb4025 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -382,8 +382,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// only a single type (e.g., `(u32, u32)`). Such aggregates are often /// special-cased in ABIs. /// - /// Note: We generally ignore fields of zero-sized type when computing - /// this value (see #56877). + /// Note: We generally ignore 1-ZST fields when computing this value (see #56877). /// /// This is public so that it can be used in unit tests, but /// should generally only be relevant to the ABI details of @@ -441,12 +440,18 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { let mut total = start; for i in 0..layout.fields.count() { + let field = layout.field(cx, i); + if field.is_1zst() { + // No data here and no impact on layout, can be ignored. + // (We might be able to also ignore all aligned ZST but that's less clear.) + continue; + } + if !is_union && total != layout.fields.offset(i) { + // This field isn't just after the previous one we considered, abort. return Err(Heterogeneous); } - let field = layout.field(cx, i); - result = result.merge(field.homogeneous_aggregate(cx)?)?; // Keep track of the offset (without padding). diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 0bbcba200c7e3..56ff1ebc52429 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -105,6 +105,8 @@ test_transparent!(zst, Zst); test_transparent!(unit, ()); test_transparent!(pair, (i32, f32)); // mixing in some floats since they often get special treatment test_transparent!(triple, (i8, i16, f32)); // chosen to fit into 64bit +test_transparent!(triple_f32, (f32, f32, f32)); // homogeneous case +test_transparent!(triple_f64, (f64, f64, f64)); test_transparent!(tuple, (i32, f32, i64, f64)); test_transparent!(empty_array, [u32; 0]); test_transparent!(empty_1zst_array, [u8; 0]); @@ -112,14 +114,6 @@ test_transparent!(small_array, [i32; 2]); // chosen to fit into 64bit test_transparent!(large_array, [i32; 16]); test_transparent!(enum_, Option<i32>); test_transparent!(enum_niched, Option<&'static i32>); -// Pure-float types that are not ScalarPair seem to be tricky. -// FIXME: <https://github.com/rust-lang/rust/issues/115664> -#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] -mod tricky { - use super::*; - test_transparent!(triple_f32, (f32, f32, f32)); - test_transparent!(triple_f64, (f64, f64, f64)); -} // RFC 3391 <https://rust-lang.github.io/rfcs/3391-result_ffi_guarantees.html>. macro_rules! test_nonnull { diff --git a/tests/ui/layout/homogeneous-aggr-transparent.rs b/tests/ui/layout/homogeneous-aggr-transparent.rs new file mode 100644 index 0000000000000..9703d2bf294f6 --- /dev/null +++ b/tests/ui/layout/homogeneous-aggr-transparent.rs @@ -0,0 +1,44 @@ +#![feature(rustc_attrs)] +#![feature(transparent_unions)] +use std::marker::PhantomData; + +// Regression test for #115664. We want to ensure that `repr(transparent)` wrappers do not affect +// the result of `homogeneous_aggregate`. + +type Tuple = (f32, f32, f32); + +struct Zst; + +#[repr(transparent)] +struct Wrapper1<T>(T); +#[repr(transparent)] +struct Wrapper2<T>((), Zst, T); +#[repr(transparent)] +struct Wrapper3<T>(T, [u8; 0], PhantomData<u64>); +#[repr(transparent)] +union WrapperUnion<T: Copy> { + nothing: (), + something: T, +} + +#[rustc_layout(homogeneous_aggregate)] +pub type Test0 = Tuple; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test1 = Wrapper1<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test2 = Wrapper2<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test3 = Wrapper3<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +#[rustc_layout(homogeneous_aggregate)] +pub type Test4 = WrapperUnion<Tuple>; +//~^ ERROR homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + +fn main() {} diff --git a/tests/ui/layout/homogeneous-aggr-transparent.stderr b/tests/ui/layout/homogeneous-aggr-transparent.stderr new file mode 100644 index 0000000000000..99eb703ac82b8 --- /dev/null +++ b/tests/ui/layout/homogeneous-aggr-transparent.stderr @@ -0,0 +1,32 @@ +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:25:1 + | +LL | pub type Test0 = Tuple; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:29:1 + | +LL | pub type Test1 = Wrapper1<Tuple>; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:33:1 + | +LL | pub type Test2 = Wrapper2<Tuple>; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:37:1 + | +LL | pub type Test3 = Wrapper3<Tuple>; + | ^^^^^^^^^^^^^^ + +error: homogeneous_aggregate: Ok(Homogeneous(Reg { kind: Float, size: Size(4 bytes) })) + --> $DIR/homogeneous-aggr-transparent.rs:41:1 + | +LL | pub type Test4 = WrapperUnion<Tuple>; + | ^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + From ce3b0442983e3689464f512b93b0c6bf020e7c36 Mon Sep 17 00:00:00 2001 From: Alex Macleod <alex@macleod.io> Date: Sun, 10 Sep 2023 18:17:47 +0000 Subject: [PATCH 5/9] Call `LateLintPass::check_attribute` from `with_lint_attrs` --- compiler/rustc_lint/src/late.rs | 25 +++++++++---------- .../clippy/tests/ui/allow_attributes.fixed | 7 ++++++ src/tools/clippy/tests/ui/allow_attributes.rs | 7 ++++++ .../blanket_clippy_restriction_lints.stderr | 14 +++++------ 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 73af51d9e9061..b24186ae1aa7f 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -21,7 +21,6 @@ use rustc_data_structures::sync::join; use rustc_hir as hir; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit as hir_visit; -use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::LintPass; @@ -61,6 +60,9 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { self.context.last_node_with_lint_attrs = id; debug!("late context: enter_attrs({:?})", attrs); lint_callback!(self, enter_lint_attrs, attrs); + for attr in attrs { + lint_callback!(self, check_attribute, attr); + } f(self); debug!("late context: exit_attrs({:?})", attrs); lint_callback!(self, exit_lint_attrs, attrs); @@ -377,20 +379,18 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>( let (module, _span, hir_id) = tcx.hir().get_module(module_def_id); - // There is no module lint that will have the crate itself as an item, so check it here. - if hir_id == hir::CRATE_HIR_ID { - lint_callback!(cx, check_crate,); - } + cx.with_lint_attrs(hir_id, |cx| { + // There is no module lint that will have the crate itself as an item, so check it here. + if hir_id == hir::CRATE_HIR_ID { + lint_callback!(cx, check_crate,); + } - cx.process_mod(module, hir_id); + cx.process_mod(module, hir_id); - // Visit the crate attributes - if hir_id == hir::CRATE_HIR_ID { - for attr in tcx.hir().attrs(hir::CRATE_HIR_ID).iter() { - cx.visit_attribute(attr) + if hir_id == hir::CRATE_HIR_ID { + lint_callback!(cx, check_crate_post,); } - lint_callback!(cx, check_crate_post,); - } + }); } fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { @@ -431,7 +431,6 @@ fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>( // item), warn for it here. lint_callback!(cx, check_crate,); tcx.hir().walk_toplevel_module(cx); - tcx.hir().walk_attributes(cx); lint_callback!(cx, check_crate_post,); }) } diff --git a/src/tools/clippy/tests/ui/allow_attributes.fixed b/src/tools/clippy/tests/ui/allow_attributes.fixed index 945ba83611c0d..b506a9890f5b9 100644 --- a/src/tools/clippy/tests/ui/allow_attributes.fixed +++ b/src/tools/clippy/tests/ui/allow_attributes.fixed @@ -22,6 +22,13 @@ struct T4; #[cfg_attr(panic = "unwind", expect(dead_code))] struct CfgT; +#[allow(clippy::allow_attributes, unused)] +struct Allowed; + +#[expect(clippy::allow_attributes)] +#[allow(unused)] +struct Expected; + fn ignore_external() { external! { #[allow(clippy::needless_borrow)] // Should not lint diff --git a/src/tools/clippy/tests/ui/allow_attributes.rs b/src/tools/clippy/tests/ui/allow_attributes.rs index 8afa61c7002c5..c7daa7abd9d41 100644 --- a/src/tools/clippy/tests/ui/allow_attributes.rs +++ b/src/tools/clippy/tests/ui/allow_attributes.rs @@ -22,6 +22,13 @@ struct T4; #[cfg_attr(panic = "unwind", allow(dead_code))] struct CfgT; +#[allow(clippy::allow_attributes, unused)] +struct Allowed; + +#[expect(clippy::allow_attributes)] +#[allow(unused)] +struct Expected; + fn ignore_external() { external! { #[allow(clippy::needless_borrow)] // Should not lint diff --git a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr index d04ea7151c2a5..afb634f34b41a 100644 --- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr +++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr @@ -1,10 +1,3 @@ -error: `clippy::restriction` is not meant to be enabled as a group - | - = note: because of the command line `--warn clippy::restriction` - = help: enable the restriction lints you need individually - = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::blanket_clippy_restriction_lints)]` - error: `clippy::restriction` is not meant to be enabled as a group --> $DIR/blanket_clippy_restriction_lints.rs:6:9 | @@ -12,6 +5,8 @@ LL | #![warn(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ | = help: enable the restriction lints you need individually + = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::blanket_clippy_restriction_lints)]` error: `clippy::restriction` is not meant to be enabled as a group --> $DIR/blanket_clippy_restriction_lints.rs:8:9 @@ -29,5 +24,10 @@ LL | #![forbid(clippy::restriction)] | = help: enable the restriction lints you need individually +error: `clippy::restriction` is not meant to be enabled as a group + | + = note: because of the command line `--warn clippy::restriction` + = help: enable the restriction lints you need individually + error: aborting due to 4 previous errors From b00e408e613700124463b72f0a449a28c44a8178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= <me@fmease.dev> Date: Sun, 10 Sep 2023 23:06:14 +0200 Subject: [PATCH 6/9] Generalize E0401 --- .../src/error_codes/E0401.md | 6 ++-- compiler/rustc_resolve/src/diagnostics.rs | 22 +++++-------- compiler/rustc_resolve/src/ident.rs | 10 ++---- compiler/rustc_resolve/src/lib.rs | 4 +-- .../early/const-param-from-outer-fn.rs | 2 +- .../early/const-param-from-outer-fn.stderr | 8 ++--- tests/ui/error-codes/E0401.stderr | 22 ++++++------- tests/ui/generics/issue-94432-garbage-ice.rs | 2 +- tests/ui/generics/issue-98432.rs | 2 +- tests/ui/generics/issue-98432.stderr | 8 ++--- tests/ui/inner-static-type-parameter.rs | 2 +- tests/ui/inner-static-type-parameter.stderr | 6 ++-- tests/ui/issues/issue-3214.rs | 2 +- tests/ui/issues/issue-3214.stderr | 8 ++--- tests/ui/issues/issue-5997-enum.rs | 2 +- tests/ui/issues/issue-5997-enum.stderr | 8 ++--- tests/ui/issues/issue-5997-struct.rs | 2 +- tests/ui/issues/issue-5997-struct.stderr | 8 ++--- tests/ui/nested-ty-params.rs | 2 +- tests/ui/nested-ty-params.stderr | 16 +++++----- tests/ui/resolve/bad-type-env-capture.stderr | 8 ++--- tests/ui/resolve/issue-12796.rs | 2 +- tests/ui/resolve/issue-12796.stderr | 4 +-- tests/ui/resolve/issue-3021-c.rs | 4 +-- tests/ui/resolve/issue-3021-c.stderr | 16 +++++----- ...sue-65025-extern-static-parent-generics.rs | 2 +- ...65025-extern-static-parent-generics.stderr | 6 ++-- ...issue-65035-static-with-parent-generics.rs | 10 +++--- ...e-65035-static-with-parent-generics.stderr | 30 ++++++++--------- .../resolve-type-param-in-item-in-trait.rs | 8 ++--- ...resolve-type-param-in-item-in-trait.stderr | 32 +++++++++---------- tests/ui/resolve/use-self-in-inner-fn.rs | 6 ++-- tests/ui/resolve/use-self-in-inner-fn.stderr | 6 ++-- tests/ui/type/type-arg-out-of-scope.rs | 2 +- tests/ui/type/type-arg-out-of-scope.stderr | 16 +++++----- 35 files changed, 141 insertions(+), 153 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0401.md b/compiler/rustc_error_codes/src/error_codes/E0401.md index 4c93053d5f8b6..45d083681e574 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0401.md +++ b/compiler/rustc_error_codes/src/error_codes/E0401.md @@ -1,4 +1,4 @@ -Inner items do not inherit type or const parameters from the functions +Inner items do not inherit the generic parameters from the items they are embedded in. Erroneous code example: @@ -32,8 +32,8 @@ fn foo<T>(x: T) { } ``` -Items inside functions are basically just like top-level items, except -that they can only be used from the function they are in. +Items nested inside other items are basically just like top-level items, except +that they can only be used from the item they are in. There are a couple of solutions for this. diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index d99fc07a7cd28..a99b610ed36af 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -553,14 +553,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { resolution_error: ResolutionError<'a>, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { match resolution_error { - ResolutionError::GenericParamsFromOuterFunction(outer_res, has_generic_params) => { + ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => { let mut err = struct_span_err!( self.tcx.sess, span, E0401, - "can't use generic parameters from outer function", + "can't use generic parameters from outer item", ); - err.span_label(span, "use of generic parameter from outer function"); + err.span_label(span, "use of generic parameter from outer item"); let sm = self.tcx.sess.source_map(); let def_id = match outer_res { @@ -573,23 +573,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { reduce_impl_span_to_impl_keyword(sm, self.def_span(def_id)), "`Self` type implicitly declared here, by this `impl`", ); - err.span_label(span, "use a type here instead"); + err.span_label(span, "refer to the type directly here instead"); return err; } Res::Def(DefKind::TyParam, def_id) => { - err.span_label(self.def_span(def_id), "type parameter from outer function"); + err.span_label(self.def_span(def_id), "type parameter from outer item"); def_id } Res::Def(DefKind::ConstParam, def_id) => { - err.span_label( - self.def_span(def_id), - "const parameter from outer function", - ); + err.span_label(self.def_span(def_id), "const parameter from outer item"); def_id } _ => { bug!( - "GenericParamsFromOuterFunction should only be used with \ + "GenericParamsFromOuterItem should only be used with \ Res::SelfTyParam, Res::SelfTyAlias, DefKind::TyParam or \ DefKind::ConstParam" ); @@ -597,9 +594,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; if let HasGenericParams::Yes(span) = has_generic_params { - // Try to retrieve the span of the function signature and generate a new - // message with a local type or const parameter. - let sugg_msg = "try using a local generic parameter instead"; + let sugg_msg = "try introducing a local generic parameter here"; let name = self.tcx.item_name(def_id); let (span, snippet) = if span.is_empty() { let snippet = format!("<{name}>"); @@ -609,7 +604,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let snippet = format!("{name}, "); (span, snippet) }; - // Suggest the modification to the user err.span_suggestion(span, sugg_msg, snippet, Applicability::MaybeIncorrect); } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 61e05b65f90f5..4817484f56435 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1229,10 +1229,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(span) = finalize { self.report_error( span, - ResolutionError::GenericParamsFromOuterFunction( - res, - has_generic_params, - ), + ResolutionError::GenericParamsFromOuterItem(res, has_generic_params), ); } return Res::Err; @@ -1296,10 +1293,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(span) = finalize { self.report_error( span, - ResolutionError::GenericParamsFromOuterFunction( - res, - has_generic_params, - ), + ResolutionError::GenericParamsFromOuterItem(res, has_generic_params), ); } return Res::Err; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b757f42eaa026..5bb8a21513849 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -186,8 +186,8 @@ struct BindingError { #[derive(Debug)] enum ResolutionError<'a> { - /// Error E0401: can't use type or const parameters from outer function. - GenericParamsFromOuterFunction(Res, HasGenericParams), + /// Error E0401: can't use type or const parameters from outer item. + GenericParamsFromOuterItem(Res, HasGenericParams), /// Error E0403: the name is already used for a type or const parameter in this generic /// parameter list. NameAlreadyUsedInParameterList(Symbol, Span), diff --git a/tests/ui/const-generics/early/const-param-from-outer-fn.rs b/tests/ui/const-generics/early/const-param-from-outer-fn.rs index c3b418ee3f8ad..ee57f3c4fc32c 100644 --- a/tests/ui/const-generics/early/const-param-from-outer-fn.rs +++ b/tests/ui/const-generics/early/const-param-from-outer-fn.rs @@ -1,6 +1,6 @@ fn foo<const X: u32>() { fn bar() -> u32 { - X //~ ERROR can't use generic parameters from outer function + X //~ ERROR can't use generic parameters from outer item } } diff --git a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr index e3bf38b702e75..826f2657905d3 100644 --- a/tests/ui/const-generics/early/const-param-from-outer-fn.stderr +++ b/tests/ui/const-generics/early/const-param-from-outer-fn.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/const-param-from-outer-fn.rs:3:9 | LL | fn foo<const X: u32>() { - | - const parameter from outer function + | - const parameter from outer item LL | fn bar() -> u32 { - | - help: try using a local generic parameter instead: `<X>` + | - help: try introducing a local generic parameter here: `<X>` LL | X - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to previous error diff --git a/tests/ui/error-codes/E0401.stderr b/tests/ui/error-codes/E0401.stderr index fa4b91cacef72..928c8d11d2030 100644 --- a/tests/ui/error-codes/E0401.stderr +++ b/tests/ui/error-codes/E0401.stderr @@ -1,26 +1,26 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:4:39 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item LL | fn bfnr<U, V: Baz<U>, W: Fn()>(y: T) { - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `T,` + | help: try introducing a local generic parameter here: `T,` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:9:16 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item ... LL | fn baz<U, - | - help: try using a local generic parameter instead: `T,` + | - help: try introducing a local generic parameter here: `T,` ... LL | (y: T) { - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/E0401.rs:24:25 | LL | impl<T> Iterator for A<T> { @@ -29,8 +29,8 @@ LL | impl<T> Iterator for A<T> { LL | fn helper(sel: &Self) -> u8 { | ^^^^ | | - | use of generic parameter from outer function - | use a type here instead + | use of generic parameter from outer item + | refer to the type directly here instead error[E0282]: type annotations needed --> $DIR/E0401.rs:11:5 diff --git a/tests/ui/generics/issue-94432-garbage-ice.rs b/tests/ui/generics/issue-94432-garbage-ice.rs index d0709e2d2a46c..4ddb3a7e9f86b 100644 --- a/tests/ui/generics/issue-94432-garbage-ice.rs +++ b/tests/ui/generics/issue-94432-garbage-ice.rs @@ -4,7 +4,7 @@ fn�a<e>(){fn�p(){e}} //~ ERROR unknown start of token: \u{fffd} //~^ ERROR unknown start of token: \u{fffd} -//~^^ ERROR can't use generic parameters from outer function [E0401] +//~^^ ERROR can't use generic parameters from outer item [E0401] //~^^^ WARN type parameter `e` should have an upper camel case name fn main(){} diff --git a/tests/ui/generics/issue-98432.rs b/tests/ui/generics/issue-98432.rs index 780c50d6ffa19..c31dea76c090c 100644 --- a/tests/ui/generics/issue-98432.rs +++ b/tests/ui/generics/issue-98432.rs @@ -2,7 +2,7 @@ struct Struct<T>(T); impl<T> Struct<T> { const CONST: fn() = || { - struct _Obligation where T:; //~ ERROR can't use generic parameters from outer function + struct _Obligation where T:; //~ ERROR can't use generic parameters from outer item }; } diff --git a/tests/ui/generics/issue-98432.stderr b/tests/ui/generics/issue-98432.stderr index c7b5c33618d5f..0736d94106e7d 100644 --- a/tests/ui/generics/issue-98432.stderr +++ b/tests/ui/generics/issue-98432.stderr @@ -1,13 +1,13 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-98432.rs:5:34 | LL | impl<T> Struct<T> { - | - type parameter from outer function + | - type parameter from outer item LL | const CONST: fn() = || { LL | struct _Obligation where T:; - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to previous error diff --git a/tests/ui/inner-static-type-parameter.rs b/tests/ui/inner-static-type-parameter.rs index c08ccd29d8011..a1994e7529cb7 100644 --- a/tests/ui/inner-static-type-parameter.rs +++ b/tests/ui/inner-static-type-parameter.rs @@ -4,7 +4,7 @@ enum Bar<T> { What } //~ ERROR parameter `T` is never used fn foo<T>() { static a: Bar<T> = Bar::What; -//~^ ERROR can't use generic parameters from outer function +//~^ ERROR can't use generic parameters from outer item } fn main() { diff --git a/tests/ui/inner-static-type-parameter.stderr b/tests/ui/inner-static-type-parameter.stderr index e4e449e4159b6..ff6558e494b11 100644 --- a/tests/ui/inner-static-type-parameter.stderr +++ b/tests/ui/inner-static-type-parameter.stderr @@ -1,10 +1,10 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/inner-static-type-parameter.rs:6:19 | LL | fn foo<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | static a: Bar<T> = Bar::What; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error[E0392]: parameter `T` is never used --> $DIR/inner-static-type-parameter.rs:3:10 diff --git a/tests/ui/issues/issue-3214.rs b/tests/ui/issues/issue-3214.rs index e3c07bb3f724f..b2c27f5be957c 100644 --- a/tests/ui/issues/issue-3214.rs +++ b/tests/ui/issues/issue-3214.rs @@ -1,6 +1,6 @@ fn foo<T>() { struct Foo { - x: T, //~ ERROR can't use generic parameters from outer function + x: T, //~ ERROR can't use generic parameters from outer item } impl<T> Drop for Foo<T> { diff --git a/tests/ui/issues/issue-3214.stderr b/tests/ui/issues/issue-3214.stderr index 7a2d772f0a1b5..5b57c1baf90ba 100644 --- a/tests/ui/issues/issue-3214.stderr +++ b/tests/ui/issues/issue-3214.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-3214.rs:3:12 | LL | fn foo<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | struct Foo { - | - help: try using a local generic parameter instead: `<T>` + | - help: try introducing a local generic parameter here: `<T>` LL | x: T, - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-3214.rs:6:22 diff --git a/tests/ui/issues/issue-5997-enum.rs b/tests/ui/issues/issue-5997-enum.rs index 3ff4e036c60be..0b1857ae3df30 100644 --- a/tests/ui/issues/issue-5997-enum.rs +++ b/tests/ui/issues/issue-5997-enum.rs @@ -1,6 +1,6 @@ fn f<Z>() -> bool { enum E { V(Z) } - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item true } diff --git a/tests/ui/issues/issue-5997-enum.stderr b/tests/ui/issues/issue-5997-enum.stderr index 3a79215d3ae9c..d07258ea7a2f9 100644 --- a/tests/ui/issues/issue-5997-enum.stderr +++ b/tests/ui/issues/issue-5997-enum.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-5997-enum.rs:2:16 | LL | fn f<Z>() -> bool { - | - type parameter from outer function + | - type parameter from outer item LL | enum E { V(Z) } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<Z>` + | help: try introducing a local generic parameter here: `<Z>` error: aborting due to previous error diff --git a/tests/ui/issues/issue-5997-struct.rs b/tests/ui/issues/issue-5997-struct.rs index 6cf510b0a9d75..19d994b0dfb7a 100644 --- a/tests/ui/issues/issue-5997-struct.rs +++ b/tests/ui/issues/issue-5997-struct.rs @@ -1,5 +1,5 @@ fn f<T>() -> bool { - struct S(T); //~ ERROR can't use generic parameters from outer function + struct S(T); //~ ERROR can't use generic parameters from outer item true } diff --git a/tests/ui/issues/issue-5997-struct.stderr b/tests/ui/issues/issue-5997-struct.stderr index d2e97f767719f..83229e02c6ca0 100644 --- a/tests/ui/issues/issue-5997-struct.stderr +++ b/tests/ui/issues/issue-5997-struct.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-5997-struct.rs:2:14 | LL | fn f<T>() -> bool { - | - type parameter from outer function + | - type parameter from outer item LL | struct S(T); - | -^ use of generic parameter from outer function + | -^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to previous error diff --git a/tests/ui/nested-ty-params.rs b/tests/ui/nested-ty-params.rs index 85413acdb1491..25bac1ba24bd1 100644 --- a/tests/ui/nested-ty-params.rs +++ b/tests/ui/nested-ty-params.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use generic parameters from outer function +// error-pattern:can't use generic parameters from outer item fn hd<U>(v: Vec<U> ) -> U { fn hd1(w: [U]) -> U { return w[0]; } diff --git a/tests/ui/nested-ty-params.stderr b/tests/ui/nested-ty-params.stderr index 8f4746f5ec3bd..a9cdec667199a 100644 --- a/tests/ui/nested-ty-params.stderr +++ b/tests/ui/nested-ty-params.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/nested-ty-params.rs:3:16 | LL | fn hd<U>(v: Vec<U> ) -> U { - | - type parameter from outer function + | - type parameter from outer item LL | fn hd1(w: [U]) -> U { return w[0]; } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<U>` + | help: try introducing a local generic parameter here: `<U>` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/nested-ty-params.rs:3:23 | LL | fn hd<U>(v: Vec<U> ) -> U { - | - type parameter from outer function + | - type parameter from outer item LL | fn hd1(w: [U]) -> U { return w[0]; } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<U>` + | help: try introducing a local generic parameter here: `<U>` error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/bad-type-env-capture.stderr b/tests/ui/resolve/bad-type-env-capture.stderr index b6282c2d0703b..941b6b7a68c35 100644 --- a/tests/ui/resolve/bad-type-env-capture.stderr +++ b/tests/ui/resolve/bad-type-env-capture.stderr @@ -1,12 +1,12 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/bad-type-env-capture.rs:2:15 | LL | fn foo<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | fn bar(b: T) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to previous error diff --git a/tests/ui/resolve/issue-12796.rs b/tests/ui/resolve/issue-12796.rs index 942d6b9a5686e..de3e73437f080 100644 --- a/tests/ui/resolve/issue-12796.rs +++ b/tests/ui/resolve/issue-12796.rs @@ -1,7 +1,7 @@ trait Trait { fn outer(&self) { fn inner(_: &Self) { - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } } diff --git a/tests/ui/resolve/issue-12796.stderr b/tests/ui/resolve/issue-12796.stderr index a01fd2d65420b..ef59d00360b88 100644 --- a/tests/ui/resolve/issue-12796.stderr +++ b/tests/ui/resolve/issue-12796.stderr @@ -1,10 +1,10 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-12796.rs:3:22 | LL | fn inner(_: &Self) { | ^^^^ | | - | use of generic parameter from outer function + | use of generic parameter from outer item | can't use `Self` here error: aborting due to previous error diff --git a/tests/ui/resolve/issue-3021-c.rs b/tests/ui/resolve/issue-3021-c.rs index 94ed1fdf78191..bd21d1244235d 100644 --- a/tests/ui/resolve/issue-3021-c.rs +++ b/tests/ui/resolve/issue-3021-c.rs @@ -1,8 +1,8 @@ fn siphash<T>() { trait U { - fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer function - //~^ ERROR can't use generic parameters from outer function + fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer item + //~^ ERROR can't use generic parameters from outer item } } diff --git a/tests/ui/resolve/issue-3021-c.stderr b/tests/ui/resolve/issue-3021-c.stderr index 5176efc3a6be7..537bbaf7b6a56 100644 --- a/tests/ui/resolve/issue-3021-c.stderr +++ b/tests/ui/resolve/issue-3021-c.stderr @@ -1,24 +1,24 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-3021-c.rs:4:24 | LL | fn siphash<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | LL | trait U { - | - help: try using a local generic parameter instead: `<T>` + | - help: try introducing a local generic parameter here: `<T>` LL | fn g(&self, x: T) -> T; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-3021-c.rs:4:30 | LL | fn siphash<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | LL | trait U { - | - help: try using a local generic parameter instead: `<T>` + | - help: try introducing a local generic parameter here: `<T>` LL | fn g(&self, x: T) -> T; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs b/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs index ce45f630e48a5..4fa3f12d024d5 100644 --- a/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs +++ b/tests/ui/resolve/issue-65025-extern-static-parent-generics.rs @@ -1,7 +1,7 @@ unsafe fn foo<A>() { extern "C" { static baz: *const A; - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } let bar: *const u64 = core::mem::transmute(&baz); diff --git a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr index 6bbf76dd1fbb2..3e9c3fd11b74d 100644 --- a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr +++ b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr @@ -1,11 +1,11 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65025-extern-static-parent-generics.rs:3:28 | LL | unsafe fn foo<A>() { - | - type parameter from outer function + | - type parameter from outer item LL | extern "C" { LL | static baz: *const A; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to previous error diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.rs b/tests/ui/resolve/issue-65035-static-with-parent-generics.rs index f96c04841dd28..bc99584a8d26a 100644 --- a/tests/ui/resolve/issue-65035-static-with-parent-generics.rs +++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.rs @@ -1,26 +1,26 @@ fn f<T>() { extern "C" { static a: *const T; - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } fn g<T: Default>() { static a: *const T = Default::default(); - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } fn h<const N: usize>() { extern "C" { static a: [u8; N]; - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } fn i<const N: usize>() { static a: [u8; N] = [0; N]; - //~^ ERROR can't use generic parameters from outer function - //~| ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item + //~| ERROR can't use generic parameters from outer item } fn main() {} diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr index 7ed572f80b896..f1fe1a6002c93 100644 --- a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr +++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr @@ -1,44 +1,44 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:3:26 | LL | fn f<T>() { - | - type parameter from outer function + | - type parameter from outer item LL | extern "C" { LL | static a: *const T; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:9:22 | LL | fn g<T: Default>() { - | - type parameter from outer function + | - type parameter from outer item LL | static a: *const T = Default::default(); - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:15:24 | LL | fn h<const N: usize>() { - | - const parameter from outer function + | - const parameter from outer item LL | extern "C" { LL | static a: [u8; N]; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:21:20 | LL | fn i<const N: usize>() { - | - const parameter from outer function + | - const parameter from outer item LL | static a: [u8; N] = [0; N]; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/issue-65035-static-with-parent-generics.rs:21:29 | LL | fn i<const N: usize>() { - | - const parameter from outer function + | - const parameter from outer item LL | static a: [u8; N] = [0; N]; - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item error: aborting due to 5 previous errors diff --git a/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs b/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs index c77a66524f73f..2d5f34c62a6f9 100644 --- a/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs +++ b/tests/ui/resolve/resolve-type-param-in-item-in-trait.rs @@ -6,7 +6,7 @@ trait TraitA<A> { fn outer(&self) { enum Foo<B> { Variance(A) - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } } @@ -14,21 +14,21 @@ trait TraitA<A> { trait TraitB<A> { fn outer(&self) { struct Foo<B>(A); - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } trait TraitC<A> { fn outer(&self) { struct Foo<B> { a: A } - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } trait TraitD<A> { fn outer(&self) { fn foo<B>(a: A) { } - //~^ ERROR can't use generic parameters from outer function + //~^ ERROR can't use generic parameters from outer item } } diff --git a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr index 0a6d1cc3bcd45..1ab56fdc50441 100644 --- a/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr +++ b/tests/ui/resolve/resolve-type-param-in-item-in-trait.stderr @@ -1,46 +1,46 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:8:22 | LL | trait TraitA<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | enum Foo<B> { - | - help: try using a local generic parameter instead: `A,` + | - help: try introducing a local generic parameter here: `A,` LL | Variance(A) - | ^ use of generic parameter from outer function + | ^ use of generic parameter from outer item -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:16:23 | LL | trait TraitB<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo<B>(A); - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `A,` + | help: try introducing a local generic parameter here: `A,` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:23:28 | LL | trait TraitC<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | struct Foo<B> { a: A } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `A,` + | help: try introducing a local generic parameter here: `A,` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/resolve-type-param-in-item-in-trait.rs:30:22 | LL | trait TraitD<A> { - | - type parameter from outer function + | - type parameter from outer item LL | fn outer(&self) { LL | fn foo<B>(a: A) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `A,` + | help: try introducing a local generic parameter here: `A,` error: aborting due to 4 previous errors diff --git a/tests/ui/resolve/use-self-in-inner-fn.rs b/tests/ui/resolve/use-self-in-inner-fn.rs index eccb315feb1e2..f4dfa4c40ab24 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.rs +++ b/tests/ui/resolve/use-self-in-inner-fn.rs @@ -4,9 +4,9 @@ impl A { //~^ NOTE `Self` type implicitly declared here, by this `impl` fn banana(&mut self) { fn peach(this: &Self) { - //~^ ERROR can't use generic parameters from outer function - //~| NOTE use of generic parameter from outer function - //~| NOTE use a type here instead + //~^ ERROR can't use generic parameters from outer item + //~| NOTE use of generic parameter from outer item + //~| NOTE refer to the type directly here instead } } } diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr index 966093499241d..832aaacaf49c8 100644 --- a/tests/ui/resolve/use-self-in-inner-fn.stderr +++ b/tests/ui/resolve/use-self-in-inner-fn.stderr @@ -1,4 +1,4 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/use-self-in-inner-fn.rs:6:25 | LL | impl A { @@ -7,8 +7,8 @@ LL | impl A { LL | fn peach(this: &Self) { | ^^^^ | | - | use of generic parameter from outer function - | use a type here instead + | use of generic parameter from outer item + | refer to the type directly here instead error: aborting due to previous error diff --git a/tests/ui/type/type-arg-out-of-scope.rs b/tests/ui/type/type-arg-out-of-scope.rs index 02aad00770793..c36f9904e5dc1 100644 --- a/tests/ui/type/type-arg-out-of-scope.rs +++ b/tests/ui/type/type-arg-out-of-scope.rs @@ -1,4 +1,4 @@ -// error-pattern:can't use generic parameters from outer function +// error-pattern:can't use generic parameters from outer item fn foo<T>(x: T) { fn bar(f: Box<dyn FnMut(T) -> T>) { } } diff --git a/tests/ui/type/type-arg-out-of-scope.stderr b/tests/ui/type/type-arg-out-of-scope.stderr index 7f18b4510f4b2..8665001e24319 100644 --- a/tests/ui/type/type-arg-out-of-scope.stderr +++ b/tests/ui/type/type-arg-out-of-scope.stderr @@ -1,22 +1,22 @@ -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/type-arg-out-of-scope.rs:3:29 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` -error[E0401]: can't use generic parameters from outer function +error[E0401]: can't use generic parameters from outer item --> $DIR/type-arg-out-of-scope.rs:3:35 | LL | fn foo<T>(x: T) { - | - type parameter from outer function + | - type parameter from outer item LL | fn bar(f: Box<dyn FnMut(T) -> T>) { } - | - ^ use of generic parameter from outer function + | - ^ use of generic parameter from outer item | | - | help: try using a local generic parameter instead: `<T>` + | help: try introducing a local generic parameter here: `<T>` error: aborting due to 2 previous errors From 9b3625247782650d57efa141ee4378eafe0d8dee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= <me@fmease.dev> Date: Sun, 10 Sep 2023 23:06:28 +0200 Subject: [PATCH 7/9] Make E0401 translatable --- compiler/rustc_resolve/messages.ftl | 29 ++++++++---------- compiler/rustc_resolve/src/diagnostics.rs | 37 +++++++++++------------ compiler/rustc_resolve/src/errors.rs | 34 +++++++++++++++++++++ 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index f98918cba8800..619c30ac54a33 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -64,9 +64,6 @@ resolve_cannot_find_ident_in_this_scope = resolve_cannot_glob_import_possible_crates = cannot glob-import all possible crates -resolve_cannot_use_self_type_here = - can't use `Self` here - resolve_change_import_binding = you can use `as` to change the binding name of the import @@ -86,9 +83,6 @@ resolve_const_not_member_of_trait = const `{$const_}` is not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}` -resolve_const_param_from_outer_fn = - const parameter from outer function - resolve_const_param_in_enum_discriminant = const parameters may not be used in enum discriminant values @@ -115,10 +109,19 @@ resolve_forward_declared_generic_param = generic parameters with a default cannot use forward declared identifiers .label = defaulted generic parameters cannot be forward declared -resolve_generic_params_from_outer_function = - can't use generic parameters from outer function - .label = use of generic parameter from outer function - .suggestion = try using a local generic parameter instead +resolve_generic_params_from_outer_item = + can't use generic parameters from outer item + .label = use of generic parameter from outer item + .refer_to_type_directly = refer to the type directly here instead + .suggestion = try introducing a local generic parameter here + +resolve_generic_params_from_outer_item_const_param = const parameter from outer item + +resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl` + +resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here + +resolve_generic_params_from_outer_item_ty_param = type parameter from outer item resolve_glob_import_doesnt_reexport = glob import doesn't reexport anything because no candidate is public enough @@ -273,9 +276,6 @@ resolve_type_not_member_of_trait = type `{$type_}` is not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}` -resolve_type_param_from_outer_fn = - type parameter from outer function - resolve_type_param_in_enum_discriminant = type parameters may not be used in enum discriminant values @@ -311,9 +311,6 @@ resolve_unreachable_label_suggestion_use_similarly_named = resolve_unreachable_label_with_similar_name_exists = a label with a similar name exists but is unreachable -resolve_use_a_type_here_instead = - use a type here instead - resolve_variable_bound_with_different_mode = variable `{$variable_name}` is bound inconsistently across alternatives separated by `|` .label = bound in different ways diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index a99b610ed36af..bcf62d8a2f290 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -554,34 +554,34 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { match resolution_error { ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => { - let mut err = struct_span_err!( - self.tcx.sess, + use errs::GenericParamsFromOuterItemLabel as Label; + let mut err = errs::GenericParamsFromOuterItem { span, - E0401, - "can't use generic parameters from outer item", - ); - err.span_label(span, "use of generic parameter from outer item"); + label: None, + refer_to_type_directly: None, + sugg: None, + }; let sm = self.tcx.sess.source_map(); let def_id = match outer_res { Res::SelfTyParam { .. } => { - err.span_label(span, "can't use `Self` here"); - return err; + err.label = Some(Label::SelfTyParam(span)); + return self.tcx.sess.create_err(err); } Res::SelfTyAlias { alias_to: def_id, .. } => { - err.span_label( - reduce_impl_span_to_impl_keyword(sm, self.def_span(def_id)), - "`Self` type implicitly declared here, by this `impl`", - ); - err.span_label(span, "refer to the type directly here instead"); - return err; + err.label = Some(Label::SelfTyAlias(reduce_impl_span_to_impl_keyword( + sm, + self.def_span(def_id), + ))); + err.refer_to_type_directly = Some(span); + return self.tcx.sess.create_err(err); } Res::Def(DefKind::TyParam, def_id) => { - err.span_label(self.def_span(def_id), "type parameter from outer item"); + err.label = Some(Label::TyParam(self.def_span(def_id))); def_id } Res::Def(DefKind::ConstParam, def_id) => { - err.span_label(self.def_span(def_id), "const parameter from outer item"); + err.label = Some(Label::ConstParam(self.def_span(def_id))); def_id } _ => { @@ -594,7 +594,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; if let HasGenericParams::Yes(span) = has_generic_params { - let sugg_msg = "try introducing a local generic parameter here"; let name = self.tcx.item_name(def_id); let (span, snippet) = if span.is_empty() { let snippet = format!("<{name}>"); @@ -604,10 +603,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let snippet = format!("{name}, "); (span, snippet) }; - err.span_suggestion(span, sugg_msg, snippet, Applicability::MaybeIncorrect); + err.sugg = Some(errs::GenericParamsFromOuterItemSugg { span, snippet }); } - err + self.tcx.sess.create_err(err) } ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self .tcx diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index e4b89c65853d0..4f91f6aa90f79 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -32,6 +32,40 @@ pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate) #[diag(resolve_crate_root_imports_must_be_named_explicitly)] pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span); +#[derive(Diagnostic)] +#[diag(resolve_generic_params_from_outer_item, code = "E0401")] +pub(crate) struct GenericParamsFromOuterItem { + #[primary_span] + #[label] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) label: Option<GenericParamsFromOuterItemLabel>, + #[label(resolve_refer_to_type_directly)] + pub(crate) refer_to_type_directly: Option<Span>, + #[subdiagnostic] + pub(crate) sugg: Option<GenericParamsFromOuterItemSugg>, +} + +#[derive(Subdiagnostic)] +pub(crate) enum GenericParamsFromOuterItemLabel { + #[label(resolve_generic_params_from_outer_item_self_ty_param)] + SelfTyParam(#[primary_span] Span), + #[label(resolve_generic_params_from_outer_item_self_ty_alias)] + SelfTyAlias(#[primary_span] Span), + #[label(resolve_generic_params_from_outer_item_ty_param)] + TyParam(#[primary_span] Span), + #[label(resolve_generic_params_from_outer_item_const_param)] + ConstParam(#[primary_span] Span), +} + +#[derive(Subdiagnostic)] +#[suggestion(resolve_suggestion, code = "{snippet}", applicability = "maybe-incorrect")] +pub(crate) struct GenericParamsFromOuterItemSugg { + #[primary_span] + pub(crate) span: Span, + pub(crate) snippet: String, +} + #[derive(Diagnostic)] #[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")] pub(crate) struct NameAlreadyUsedInParameterList { From daf3c45531815e8015e8a508f2650fcfa166cf29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= <me@fmease.dev> Date: Sun, 10 Sep 2023 22:29:37 +0200 Subject: [PATCH 8/9] Do not suggest generic const items unless enabled --- compiler/rustc_resolve/src/late.rs | 6 ++- ...om-outer-item-in-const-item.default.stderr | 28 +++++++++++++ ...m-in-const-item.generic_const_items.stderr | 34 ++++++++++++++++ ...ic-params-from-outer-item-in-const-item.rs | 39 +++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr create mode 100644 tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr create mode 100644 tests/ui/resolve/generic-params-from-outer-item-in-const-item.rs diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 486d60eab2101..d40b1b2e3a900 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2450,7 +2450,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => { self.with_generic_param_rib( &generics.params, - RibKind::Item(HasGenericParams::Yes(generics.span)), + RibKind::Item(if self.r.tcx.features().generic_const_items { + HasGenericParams::Yes(generics.span) + } else { + HasGenericParams::No + }), LifetimeRibKind::Generics { binder: item.id, kind: LifetimeBinderKind::ConstItem, diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr new file mode 100644 index 0000000000000..4f8538292792c --- /dev/null +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr @@ -0,0 +1,28 @@ +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:12:20 + | +LL | fn outer<T: Tr>() { // outer function + | - type parameter from outer item +LL | const K: u32 = T::C; + | ^^^^ use of generic parameter from outer item + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24 + | +LL | impl<T> Tr for T { // outer impl block + | - type parameter from outer item +LL | const C: u32 = { +LL | const I: u32 = T::C; + | ^^^^ use of generic parameter from outer item + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20 + | +LL | struct S<T: Tr>(U32<{ // outer struct + | - type parameter from outer item +LL | const _: u32 = T::C; + | ^^^^ use of generic parameter from outer item + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr new file mode 100644 index 0000000000000..1cb55842bc665 --- /dev/null +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr @@ -0,0 +1,34 @@ +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:12:20 + | +LL | fn outer<T: Tr>() { // outer function + | - type parameter from outer item +LL | const K: u32 = T::C; + | - ^^^^ use of generic parameter from outer item + | | + | help: try introducing a local generic parameter here: `<T>` + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24 + | +LL | impl<T> Tr for T { // outer impl block + | - type parameter from outer item +LL | const C: u32 = { +LL | const I: u32 = T::C; + | - ^^^^ use of generic parameter from outer item + | | + | help: try introducing a local generic parameter here: `<T>` + +error[E0401]: can't use generic parameters from outer item + --> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20 + | +LL | struct S<T: Tr>(U32<{ // outer struct + | - type parameter from outer item +LL | const _: u32 = T::C; + | - ^^^^ use of generic parameter from outer item + | | + | help: try introducing a local generic parameter here: `<T>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0401`. diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.rs b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.rs new file mode 100644 index 0000000000000..e5647d72cba35 --- /dev/null +++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.rs @@ -0,0 +1,39 @@ +// Regression test for issue #115720. +// If a const item contains generic params from an outer items, only suggest +// turning the const item generic if the feature `generic_const_items` is enabled. + +// revisions: default generic_const_items + +#![cfg_attr(generic_const_items, feature(generic_const_items))] +#![feature(generic_const_exprs)] // only used for the test case "outer struct" +#![allow(incomplete_features)] + +fn outer<T: Tr>() { // outer function + const K: u32 = T::C; + //~^ ERROR can't use generic parameters from outer item + //[generic_const_items]~| HELP try introducing a local generic parameter here +} + +impl<T> Tr for T { // outer impl block + const C: u32 = { + const I: u32 = T::C; + //~^ ERROR can't use generic parameters from outer item + //[generic_const_items]~| HELP try introducing a local generic parameter here + I + }; +} + +struct S<T: Tr>(U32<{ // outer struct + const _: u32 = T::C; + //~^ ERROR can't use generic parameters from outer item + //[generic_const_items]~| HELP try introducing a local generic parameter here + 0 +}>); + +trait Tr { + const C: u32; +} + +struct U32<const N: u32>; + +fn main() {} From 30e6cea0ae4780bdd99e56fc85719dcb4305c900 Mon Sep 17 00:00:00 2001 From: Michael Goulet <michael@errs.io> Date: Sun, 10 Sep 2023 03:33:07 +0000 Subject: [PATCH 9/9] Point out if a local trait has no implementations --- compiler/rustc_middle/src/ty/trait_def.rs | 4 + compiler/rustc_trait_selection/messages.ftl | 2 + .../src/traits/error_reporting/mod.rs | 24 +- .../associated-const-array-len.stderr | 6 + .../ui/associated-consts/issue-105330.stderr | 10 + ...ypes-ICE-when-projecting-out-of-err.stderr | 6 + ...ciated-types-no-suitable-supertrait.stderr | 6 + .../defaults-suitability.stderr | 5 + tests/ui/associated-types/issue-59324.stderr | 6 + tests/ui/associated-types/issue-64855.stderr | 6 + ...int-at-type-on-obligation-failure-2.stderr | 15 ++ .../coherence-unsafe-trait-object-impl.stderr | 5 + .../dont-evaluate-array-len-on-err-1.stderr | 6 + .../generic_const_exprs/issue-85848.stderr | 6 +- .../const-generics/issues/issue-86530.stderr | 5 + tests/ui/cross/cross-fn-cache-hole.stderr | 5 + tests/ui/dst/dst-bad-coerce1.stderr | 10 + tests/ui/dyn-star/error.stderr | 6 + tests/ui/error-codes/E0277.stderr | 5 + .../issue-101020.stderr | 5 + .../normalize-under-binder/issue-89118.stderr | 15 ++ tests/ui/issues/issue-18611.stderr | 6 + tests/ui/issues/issue-25076.stderr | 5 + tests/ui/issues/issue-35570.stderr | 6 + tests/ui/issues/issue-60218.stderr | 5 + tests/ui/issues/issue-66353.stderr | 12 + .../lifetime-elision-return-type-trait.stderr | 6 + tests/ui/namespace/namespace-mix.stderr | 220 ++++++++++++++++++ .../feature-gate-never_type_fallback.stderr | 5 + .../ui/never_type/impl_trait_fallback3.stderr | 6 + .../ui/never_type/impl_trait_fallback4.stderr | 6 + tests/ui/on-unimplemented/on-trait.stderr | 10 + tests/ui/on-unimplemented/parent-label.stderr | 20 ++ tests/ui/proc-macro/bad-projection.stderr | 6 + tests/ui/span/issue-29595.stderr | 6 + tests/ui/specialization/issue-38091.stderr | 5 + tests/ui/suggestions/issue-89333.stderr | 5 + tests/ui/trait-bounds/issue-82038.stderr | 6 + .../bound/on-structs-and-enums-in-fns.stderr | 10 + .../on-structs-and-enums-in-impls.stderr | 5 + .../bound/on-structs-and-enums-locals.stderr | 10 + .../bound/on-structs-and-enums-static.stderr | 5 + .../traits/bound/on-structs-and-enums.stderr | 20 ++ .../deny-builtin-object-impl.current.stderr | 5 + .../deny-builtin-object-impl.next.stderr | 5 + ...dont-autoderef-ty-with-escaping-var.stderr | 5 + tests/ui/traits/impl-bounds-checking.stderr | 5 + .../new-solver/projection-discr-kind.stderr | 5 + .../traits/non_lifetime_binders/fail.stderr | 5 + .../traits/object-does-not-impl-trait.stderr | 5 + tests/ui/traits/vtable-res-trait-param.stderr | 5 + .../trivial-bounds/trivial-bounds-leak.stderr | 11 + .../projection-as-union-type-error-2.stderr | 5 + .../projection-as-union-type-error.stderr | 6 + tests/ui/unsized/issue-75707.stderr | 5 + tests/ui/wf/hir-wf-canonicalized.stderr | 12 + tests/ui/wf/issue-95665.stderr | 5 + tests/ui/wf/wf-complex-assoc-type.stderr | 5 + tests/ui/wf/wf-foreign-fn-decl-ret.stderr | 11 + ...ked-on-proj-of-type-as-unimpl-trait.stderr | 6 + .../higher-ranked-fn-type.quiet.stderr | 5 + .../higher-ranked-fn-type.verbose.stderr | 5 + .../where-clause-method-substituion.stderr | 5 + 63 files changed, 658 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 6e55e7915c92d..bf9b244936fc6 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -90,6 +90,10 @@ pub struct TraitImpls { } impl TraitImpls { + pub fn is_empty(&self) -> bool { + self.blanket_impls.is_empty() && self.non_blanket_impls.is_empty() + } + pub fn blanket_impls(&self) -> &[DefId] { self.blanket_impls.as_slice() } diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 2a09a7dcd89dc..2db24c43734f8 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -40,5 +40,7 @@ trait_selection_no_value_in_rustc_on_unimplemented = this attribute must have a .label = expected value here .note = eg `#[rustc_on_unimplemented(message="foo")]` +trait_selection_trait_has_no_impls = this trait has no implementations, consider adding one + trait_selection_ty_alias_overflow = in case this is a recursive type alias, consider using a struct, enum, or union instead trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 746a38f956ab3..e4f5c4003c911 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -3009,10 +3009,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Try to report a help message if is_fn_trait && let Ok((implemented_kind, params)) = self.type_implements_fn_trait( - obligation.param_env, - trait_ref.self_ty(), - trait_predicate.skip_binder().polarity, - ) + obligation.param_env, + trait_ref.self_ty(), + trait_predicate.skip_binder().polarity, + ) { self.add_help_message_for_fn_trait(trait_ref, err, implemented_kind, params); } else if !trait_ref.has_non_region_infer() @@ -3031,6 +3031,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { None, obligation.cause.body_id, ); + } else if trait_ref.def_id().is_local() + && self.tcx.trait_impls_of(trait_ref.def_id()).is_empty() + && !self.tcx.trait_is_auto(trait_ref.def_id()) + && !self.tcx.trait_is_alias(trait_ref.def_id()) + { + err.span_help( + self.tcx.def_span(trait_ref.def_id()), + crate::fluent_generated::trait_selection_trait_has_no_impls, + ); } else if !suggested && !unsatisfied_const { // Can't show anything else useful, try to find similar impls. let impl_candidates = self.find_similar_impl_candidates(*trait_predicate); @@ -3041,7 +3050,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err, true, ) { - self.report_similar_impl_candidates_for_root_obligation(&obligation, *trait_predicate, body_def_id, err); + self.report_similar_impl_candidates_for_root_obligation( + &obligation, + *trait_predicate, + body_def_id, + err, + ); } self.suggest_convert_to_slice( diff --git a/tests/ui/associated-consts/associated-const-array-len.stderr b/tests/ui/associated-consts/associated-const-array-len.stderr index 0e0dec35b53ad..e3db45810fdd1 100644 --- a/tests/ui/associated-consts/associated-const-array-len.stderr +++ b/tests/ui/associated-consts/associated-const-array-len.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied | LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2]; | ^^^ the trait `Foo` is not implemented for `i32` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-const-array-len.rs:1:1 + | +LL | trait Foo { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index e9fe3a5e514b4..927422fa8dcaf 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -51,6 +51,11 @@ error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied LL | foo::<Demo>()(); | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-105330.rs:1:1 + | +LL | pub trait TraitWAssocConst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `foo` --> $DIR/issue-105330.rs:11:11 | @@ -87,6 +92,11 @@ error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied LL | foo::<Demo>(); | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-105330.rs:1:1 + | +LL | pub trait TraitWAssocConst { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `foo` --> $DIR/issue-105330.rs:11:11 | diff --git a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr index 8c3463a2832e0..fbc4ccd4cf440 100644 --- a/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr +++ b/tests/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): Add<A>` is not satisfied | LL | r = r + a; | ^ the trait `Add<A>` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:15:1 + | +LL | trait Add<RHS=Self> { + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr index bd3ee2abd2c76..b3f2e16ba0de8 100644 --- a/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr +++ b/tests/ui/associated-types/associated-types-no-suitable-supertrait.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(T, U): Get` is not satisfied | LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-types-no-suitable-supertrait.rs:12:1 + | +LL | trait Get { + | ^^^^^^^^^ error[E0277]: the trait bound `Self: Get` is not satisfied --> $DIR/associated-types-no-suitable-supertrait.rs:17:40 diff --git a/tests/ui/associated-types/defaults-suitability.stderr b/tests/ui/associated-types/defaults-suitability.stderr index 4b2094691f8cc..0a8ad0f89e212 100644 --- a/tests/ui/associated-types/defaults-suitability.stderr +++ b/tests/ui/associated-types/defaults-suitability.stderr @@ -58,6 +58,11 @@ error[E0277]: the trait bound `(): Foo<Self>` is not satisfied LL | type Assoc: Foo<Self> = (); | ^^ the trait `Foo<Self>` is not implemented for `()` | +help: this trait has no implementations, consider adding one + --> $DIR/defaults-suitability.rs:27:1 + | +LL | trait Foo<T> { + | ^^^^^^^^^^^^ note: required by a bound in `Bar::Assoc` --> $DIR/defaults-suitability.rs:34:17 | diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr index a84b599b52b68..266e22d4726d0 100644 --- a/tests/ui/associated-types/issue-59324.stderr +++ b/tests/ui/associated-types/issue-59324.stderr @@ -48,6 +48,12 @@ error[E0277]: the trait bound `(): Foo` is not satisfied | LL | fn with_factory<H>(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-59324.rs:3:1 + | +LL | pub trait Foo: NotFoo { + | ^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Bug: Foo` is not satisfied --> $DIR/issue-59324.rs:19:10 diff --git a/tests/ui/associated-types/issue-64855.stderr b/tests/ui/associated-types/issue-64855.stderr index 6ad795c11176d..f1016f0e3a191 100644 --- a/tests/ui/associated-types/issue-64855.stderr +++ b/tests/ui/associated-types/issue-64855.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `Bar<T>: Foo` is not satisfied | LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ; | ^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar<T>` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-64855.rs:1:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr index 3b4689e08ccfa..056d9201b4abb 100644 --- a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr +++ b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `bool: Bar` is not satisfied LL | type Assoc = bool; | ^^^^ the trait `Bar` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/point-at-type-on-obligation-failure-2.rs:1:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `Foo::Assoc` --> $DIR/point-at-type-on-obligation-failure-2.rs:4:17 | @@ -16,6 +21,11 @@ error[E0277]: the trait bound `bool: Bar` is not satisfied LL | type Assoc = bool; | ^^^^ the trait `Bar` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/point-at-type-on-obligation-failure-2.rs:1:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `Baz::Assoc` --> $DIR/point-at-type-on-obligation-failure-2.rs:13:18 | @@ -31,6 +41,11 @@ error[E0277]: the trait bound `bool: Bar` is not satisfied LL | type Assoc = bool; | ^^^^ the trait `Bar` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/point-at-type-on-obligation-failure-2.rs:1:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `Bat::Assoc` --> $DIR/point-at-type-on-obligation-failure-2.rs:24:27 | diff --git a/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr b/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr index 2e2dac288a1da..a3a37fd277578 100644 --- a/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr +++ b/tests/ui/coherence/coherence-unsafe-trait-object-impl.stderr @@ -6,6 +6,11 @@ LL | takes_t(t); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/coherence-unsafe-trait-object-impl.rs:6:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `takes_t` --> $DIR/coherence-unsafe-trait-object-impl.rs:10:15 | diff --git a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr index cb51d9b1ea594..b3a2756602603 100644 --- a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr +++ b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `[Adt; std::mem::size_of::<Self::Assoc>()]: Foo` i | LL | <[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; std::mem::size_of::<Self::Assoc>()]` + | +help: this trait has no implementations, consider adding one + --> $DIR/dont-evaluate-array-len-on-err-1.rs:9:1 + | +LL | trait Foo { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr index e50ac671eca54..9391b1c1a170a 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-85848.stderr @@ -6,7 +6,11 @@ LL | writes_to_specific_path(&cap); | | | required by a bound introduced by this call | - = help: the trait `Delegates<U>` is implemented for `T` +help: this trait has no implementations, consider adding one + --> $DIR/issue-85848.rs:4:1 + | +LL | trait _Contains<T> { + | ^^^^^^^^^^^^^^^^^^ note: required for `&C` to implement `Contains<(), true>` --> $DIR/issue-85848.rs:21:12 | diff --git a/tests/ui/const-generics/issues/issue-86530.stderr b/tests/ui/const-generics/issues/issue-86530.stderr index 620ed4f0fb2cc..d02808f7c567b 100644 --- a/tests/ui/const-generics/issues/issue-86530.stderr +++ b/tests/ui/const-generics/issues/issue-86530.stderr @@ -6,6 +6,11 @@ LL | z(" "); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/issue-86530.rs:4:1 + | +LL | pub trait X { + | ^^^^^^^^^^^ note: required by a bound in `z` --> $DIR/issue-86530.rs:10:8 | diff --git a/tests/ui/cross/cross-fn-cache-hole.stderr b/tests/ui/cross/cross-fn-cache-hole.stderr index 7e15562b0816b..79d1713934b3c 100644 --- a/tests/ui/cross/cross-fn-cache-hole.stderr +++ b/tests/ui/cross/cross-fn-cache-hole.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `i32: Bar<u32>` is not satisfied LL | where i32: Foo<u32, A> | ^^^^^^^^^^^^^^^^ the trait `Bar<u32>` is not implemented for `i32` | +help: this trait has no implementations, consider adding one + --> $DIR/cross-fn-cache-hole.rs:11:1 + | +LL | trait Bar<X> { } + | ^^^^^^^^^^^^ = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable diff --git a/tests/ui/dst/dst-bad-coerce1.stderr b/tests/ui/dst/dst-bad-coerce1.stderr index 2c75518c298a9..455d15e935fae 100644 --- a/tests/ui/dst/dst-bad-coerce1.stderr +++ b/tests/ui/dst/dst-bad-coerce1.stderr @@ -15,6 +15,11 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &Fat<dyn Bar> = f2; | ^^ the trait `Bar` is not implemented for `Foo` | +help: this trait has no implementations, consider adding one + --> $DIR/dst-bad-coerce1.rs:10:1 + | +LL | trait Bar { fn bar(&self) {} } + | ^^^^^^^^^ = note: required for the cast from `&Fat<Foo>` to `&Fat<dyn Bar>` error[E0308]: mismatched types @@ -34,6 +39,11 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &(dyn Bar,) = f2; | ^^ the trait `Bar` is not implemented for `Foo` | +help: this trait has no implementations, consider adding one + --> $DIR/dst-bad-coerce1.rs:10:1 + | +LL | trait Bar { fn bar(&self) {} } + | ^^^^^^^^^ = note: required for the cast from `&(Foo,)` to `&(dyn Bar,)` error: aborting due to 4 previous errors diff --git a/tests/ui/dyn-star/error.stderr b/tests/ui/dyn-star/error.stderr index ae54b9ca707d0..e039bb6f1c82b 100644 --- a/tests/ui/dyn-star/error.stderr +++ b/tests/ui/dyn-star/error.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `{integer}: Foo` is not satisfied | LL | let dyn_i: dyn* Foo = i; | ^ the trait `Foo` is not implemented for `{integer}` + | +help: this trait has no implementations, consider adding one + --> $DIR/error.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/error-codes/E0277.stderr b/tests/ui/error-codes/E0277.stderr index 440e43dff8188..0b0d2b09720cd 100644 --- a/tests/ui/error-codes/E0277.stderr +++ b/tests/ui/error-codes/E0277.stderr @@ -21,6 +21,11 @@ LL | some_func(5i32); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/E0277.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ note: required by a bound in `some_func` --> $DIR/E0277.rs:7:17 | diff --git a/tests/ui/generic-associated-types/issue-101020.stderr b/tests/ui/generic-associated-types/issue-101020.stderr index 5c8db617c1731..91967fb850976 100644 --- a/tests/ui/generic-associated-types/issue-101020.stderr +++ b/tests/ui/generic-associated-types/issue-101020.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satis LL | (&mut EmptyIter).consume(()); | ^^^^^^^ the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-101020.rs:28:1 + | +LL | trait Foo<T> {} + | ^^^^^^^^^^^^ note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>` --> $DIR/issue-101020.rs:27:20 | diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr index edef6ccd34e61..7fe803550bddf 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied LL | C: StackContext, | ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89118.rs:1:1 + | +LL | trait BufferMut {} + | ^^^^^^^^^^^^^^^ note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` --> $DIR/issue-89118.rs:5:23 | @@ -26,6 +31,11 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied LL | impl<C> EthernetWorker<C> {} | ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89118.rs:1:1 + | +LL | trait BufferMut {} + | ^^^^^^^^^^^^^^^ note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` --> $DIR/issue-89118.rs:5:23 | @@ -48,6 +58,11 @@ error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied LL | type Handler = Ctx<C::Dispatcher>; | ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89118.rs:1:1 + | +LL | trait BufferMut {} + | ^^^^^^^^^^^^^^^ note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` --> $DIR/issue-89118.rs:5:23 | diff --git a/tests/ui/issues/issue-18611.stderr b/tests/ui/issues/issue-18611.stderr index bd18d46223e69..784b9b984e900 100644 --- a/tests/ui/issues/issue-18611.stderr +++ b/tests/ui/issues/issue-18611.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `isize: HasState` is not satisfied | LL | fn add_state(op: <isize as HasState>::State) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-18611.rs:5:1 + | +LL | trait HasState { + | ^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/issues/issue-25076.stderr b/tests/ui/issues/issue-25076.stderr index 159cc484c5d4f..065bf7def42f8 100644 --- a/tests/ui/issues/issue-25076.stderr +++ b/tests/ui/issues/issue-25076.stderr @@ -6,6 +6,11 @@ LL | do_fold(bot(), ()); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/issue-25076.rs:3:1 + | +LL | trait InOut<T> { type Out; } + | ^^^^^^^^^^^^^^ note: required by a bound in `do_fold` --> $DIR/issue-25076.rs:5:18 | diff --git a/tests/ui/issues/issue-35570.stderr b/tests/ui/issues/issue-35570.stderr index 2697d46bdb2f4..197e80ac097c2 100644 --- a/tests/ui/issues/issue-35570.stderr +++ b/tests/ui/issues/issue-35570.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied | LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-35570.rs:4:1 + | +LL | trait Trait2<'a> { + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/issues/issue-60218.stderr b/tests/ui/issues/issue-60218.stderr index 563690c9a5d6d..ae3c4d12025e3 100644 --- a/tests/ui/issues/issue-60218.stderr +++ b/tests/ui/issues/issue-60218.stderr @@ -6,6 +6,11 @@ LL | trigger_error(vec![], |x: &u32| x) | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/issue-60218.rs:7:1 + | +LL | pub trait Foo {} + | ^^^^^^^^^^^^^ note: required by a bound in `trigger_error` --> $DIR/issue-60218.rs:13:72 | diff --git a/tests/ui/issues/issue-66353.stderr b/tests/ui/issues/issue-66353.stderr index 71530f5822013..7ab7547b42dc6 100644 --- a/tests/ui/issues/issue-66353.stderr +++ b/tests/ui/issues/issue-66353.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): _A` is not satisfied | LL | _Func::< <() as _A>::AssocT >::func(()); | ^^ the trait `_A` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-66353.rs:7:1 + | +LL | trait _A { + | ^^^^^^^^ error[E0277]: the trait bound `(): _Func<_>` is not satisfied --> $DIR/issue-66353.rs:12:41 @@ -11,6 +17,12 @@ LL | _Func::< <() as _A>::AssocT >::func(()); | ----------------------------------- ^^ the trait `_Func<_>` is not implemented for `()` | | | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-66353.rs:3:1 + | +LL | trait _Func<T> { + | ^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr index ef1127c59ac4c..421ab3fcf4ebb 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied | LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>` + | +help: this trait has no implementations, consider adding one + --> $DIR/lifetime-elision-return-type-trait.rs:1:1 + | +LL | trait Future { + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/namespace/namespace-mix.stderr b/tests/ui/namespace/namespace-mix.stderr index 3ac5e96c5742b..4eff08ead42ce 100644 --- a/tests/ui/namespace/namespace-mix.stderr +++ b/tests/ui/namespace/namespace-mix.stderr @@ -114,6 +114,11 @@ LL | check(m1::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -128,6 +133,11 @@ LL | check(m2::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -142,6 +152,11 @@ LL | check(m2::S); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -156,6 +171,11 @@ LL | check(xm1::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -170,6 +190,11 @@ LL | check(xm2::S{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -184,6 +209,11 @@ LL | check(xm2::S); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -198,6 +228,11 @@ LL | check(m3::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -212,6 +247,11 @@ LL | check(m3::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -226,6 +266,11 @@ LL | check(m4::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -240,6 +285,11 @@ LL | check(m4::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -254,6 +304,11 @@ LL | check(xm3::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -268,6 +323,11 @@ LL | check(xm3::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -282,6 +342,11 @@ LL | check(xm4::TS{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -296,6 +361,11 @@ LL | check(xm4::TS); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -310,6 +380,11 @@ LL | check(m5::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -324,6 +399,11 @@ LL | check(m5::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -338,6 +418,11 @@ LL | check(m6::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -352,6 +437,11 @@ LL | check(m6::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -366,6 +456,11 @@ LL | check(xm5::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -380,6 +475,11 @@ LL | check(xm5::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -394,6 +494,11 @@ LL | check(xm6::US{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -408,6 +513,11 @@ LL | check(xm6::US); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -422,6 +532,11 @@ LL | check(m7::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -436,6 +551,11 @@ LL | check(m8::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -450,6 +570,11 @@ LL | check(m8::V); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -464,6 +589,11 @@ LL | check(xm7::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -478,6 +608,11 @@ LL | check(xm8::V{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -492,6 +627,11 @@ LL | check(xm8::V); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -506,6 +646,11 @@ LL | check(m9::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -520,6 +665,11 @@ LL | check(m9::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -534,6 +684,11 @@ LL | check(mA::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -548,6 +703,11 @@ LL | check(mA::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -562,6 +722,11 @@ LL | check(xm9::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -576,6 +741,11 @@ LL | check(xm9::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -590,6 +760,11 @@ LL | check(xmA::TV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -604,6 +779,11 @@ LL | check(xmA::TV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -618,6 +798,11 @@ LL | check(mB::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -632,6 +817,11 @@ LL | check(mB::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -646,6 +836,11 @@ LL | check(mC::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -660,6 +855,11 @@ LL | check(mC::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -674,6 +874,11 @@ LL | check(xmB::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -688,6 +893,11 @@ LL | check(xmB::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -702,6 +912,11 @@ LL | check(xmC::UV{}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | @@ -716,6 +931,11 @@ LL | check(xmC::UV); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/namespace-mix.rs:20:1 + | +LL | trait Impossible {} + | ^^^^^^^^^^^^^^^^ note: required by a bound in `check` --> $DIR/namespace-mix.rs:21:13 | diff --git a/tests/ui/never_type/feature-gate-never_type_fallback.stderr b/tests/ui/never_type/feature-gate-never_type_fallback.stderr index 2db1cc4b77690..56aafbb4ce89e 100644 --- a/tests/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/tests/ui/never_type/feature-gate-never_type_fallback.stderr @@ -8,6 +8,11 @@ LL | foo(panic!()) | | this tail expression is of type `()` | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/feature-gate-never_type_fallback.rs:7:1 + | +LL | trait T {} + | ^^^^^^^ note: required by a bound in `foo` --> $DIR/feature-gate-never_type_fallback.rs:13:16 | diff --git a/tests/ui/never_type/impl_trait_fallback3.stderr b/tests/ui/never_type/impl_trait_fallback3.stderr index 5d5d216fb9bcc..821d141569ed9 100644 --- a/tests/ui/never_type/impl_trait_fallback3.stderr +++ b/tests/ui/never_type/impl_trait_fallback3.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/impl_trait_fallback3.rs:5:1 + | +LL | trait T { + | ^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/never_type/impl_trait_fallback4.stderr b/tests/ui/never_type/impl_trait_fallback4.stderr index f2e216e9044c0..67421ba8da757 100644 --- a/tests/ui/never_type/impl_trait_fallback4.stderr +++ b/tests/ui/never_type/impl_trait_fallback4.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn foo() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/impl_trait_fallback4.rs:3:1 + | +LL | trait T { + | ^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/on-trait.stderr b/tests/ui/on-unimplemented/on-trait.stderr index 4b040f1ac5aa9..4847a1a5a6119 100644 --- a/tests/ui/on-unimplemented/on-trait.stderr +++ b/tests/ui/on-unimplemented/on-trait.stderr @@ -5,6 +5,11 @@ LL | let y: Option<Vec<u8>> = collect(x.iter()); // this should give approxi | ^^^^^^^ a collection of type `Option<Vec<u8>>` cannot be built from an iterator over elements of type `&u8` | = help: the trait `MyFromIterator<&u8>` is not implemented for `Option<Vec<u8>>` +help: this trait has no implementations, consider adding one + --> $DIR/on-trait.rs:17:1 + | +LL | trait MyFromIterator<A> { + | ^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `collect` --> $DIR/on-trait.rs:22:39 | @@ -18,6 +23,11 @@ LL | let x: String = foobar(); | ^^^^^^ test error `String` with `u8` `_` `u32` in `Foo` | = help: the trait `Foo<u8, _, u32>` is not implemented for `String` +help: this trait has no implementations, consider adding one + --> $DIR/on-trait.rs:7:3 + | +LL | pub trait Foo<Bar, Baz, Quux> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `foobar` --> $DIR/on-trait.rs:12:24 | diff --git a/tests/ui/on-unimplemented/parent-label.stderr b/tests/ui/on-unimplemented/parent-label.stderr index 8cd7412fd9d3d..101a41512d280 100644 --- a/tests/ui/on-unimplemented/parent-label.stderr +++ b/tests/ui/on-unimplemented/parent-label.stderr @@ -8,6 +8,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | @@ -24,6 +29,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | @@ -41,6 +51,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | @@ -58,6 +73,11 @@ LL | f(Foo {}); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/parent-label.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/parent-label.rs:10:9 | diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr index 8a8246376fe08..8716defa17ae9 100644 --- a/tests/ui/proc-macro/bad-projection.stderr +++ b/tests/ui/proc-macro/bad-projection.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): Project` is not satisfied | LL | pub fn uwu() -> <() as Project>::Assoc {} | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Project` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/bad-projection.rs:9:1 + | +LL | trait Project { + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/span/issue-29595.stderr b/tests/ui/span/issue-29595.stderr index 92445e4073130..7d603cdbfe5ca 100644 --- a/tests/ui/span/issue-29595.stderr +++ b/tests/ui/span/issue-29595.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied | LL | let a: u8 = Tr::C; | ^^^^^ the trait `Tr` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-29595.rs:1:1 + | +LL | trait Tr { + | ^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/specialization/issue-38091.stderr b/tests/ui/specialization/issue-38091.stderr index f2210a40719d3..4d840482b46b5 100644 --- a/tests/ui/specialization/issue-38091.stderr +++ b/tests/ui/specialization/issue-38091.stderr @@ -14,6 +14,11 @@ error[E0277]: the trait bound `(): Valid` is not satisfied LL | default type Ty = (); | ^^ the trait `Valid` is not implemented for `()` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-38091.rs:20:1 + | +LL | trait Valid {} + | ^^^^^^^^^^^ note: required by a bound in `Iterate::Ty` --> $DIR/issue-38091.rs:5:14 | diff --git a/tests/ui/suggestions/issue-89333.stderr b/tests/ui/suggestions/issue-89333.stderr index f73f1147d5d9c..4739f11ddadbf 100644 --- a/tests/ui/suggestions/issue-89333.stderr +++ b/tests/ui/suggestions/issue-89333.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'a> &'a _: Trait` is not satisfied LL | test(&|| 0); | ^^^^ the trait `for<'a> Trait` is not implemented for `&'a _` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-89333.rs:9:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `test` --> $DIR/issue-89333.rs:11:55 | diff --git a/tests/ui/trait-bounds/issue-82038.stderr b/tests/ui/trait-bounds/issue-82038.stderr index f37e3286f4bf8..30bb4a0a8509d 100644 --- a/tests/ui/trait-bounds/issue-82038.stderr +++ b/tests/ui/trait-bounds/issue-82038.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `bool: Foo` is not satisfied | LL | <bool as Foo>::my_method(); | ^^^^ the trait `Foo` is not implemented for `bool` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-82038.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr b/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr index 61237a63e3220..530264b344ab5 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-in-fns.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied LL | fn explode(x: Foo<u32>) {} | ^^^^^^^^ the trait `Trait` is not implemented for `u32` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-in-fns.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-in-fns.rs:3:14 | @@ -16,6 +21,11 @@ error[E0277]: the trait bound `f32: Trait` is not satisfied LL | fn kaboom(y: Bar<f32>) {} | ^^^^^^^^ the trait `Trait` is not implemented for `f32` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-in-fns.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/on-structs-and-enums-in-fns.rs:7:12 | diff --git a/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr b/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr index 8a43742260bb2..372bbabbd8621 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-in-impls.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u16: Trait` is not satisfied LL | impl PolyTrait<Foo<u16>> for Struct { | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u16` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-in-impls.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-in-impls.rs:3:14 | diff --git a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr index 20bbe69c059f8..01cf76c62d540 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-locals.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-locals.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `usize: Trait` is not satisfied LL | let baz: Foo<usize> = loop { }; | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-locals.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-locals.rs:5:14 | @@ -16,6 +21,11 @@ error[E0277]: the trait bound `{integer}: Trait` is not satisfied LL | x: 3 | ^ the trait `Trait` is not implemented for `{integer}` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-locals.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-locals.rs:5:14 | diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.stderr b/tests/ui/traits/bound/on-structs-and-enums-static.stderr index fda734e857113..fa14aff684d53 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-static.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `usize: Trait` is not satisfied LL | static X: Foo<usize> = Foo { | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-static.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums-static.rs:5:14 | diff --git a/tests/ui/traits/bound/on-structs-and-enums.stderr b/tests/ui/traits/bound/on-structs-and-enums.stderr index fe05b86344be3..606f764852fed 100644 --- a/tests/ui/traits/bound/on-structs-and-enums.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums.stderr @@ -20,6 +20,11 @@ error[E0277]: the trait bound `isize: Trait` is not satisfied LL | a: Foo<isize>, | ^^^^^^^^^^ the trait `Trait` is not implemented for `isize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums.rs:3:14 | @@ -32,6 +37,11 @@ error[E0277]: the trait bound `usize: Trait` is not satisfied LL | Quux(Bar<usize>), | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/on-structs-and-enums.rs:7:12 | @@ -76,6 +86,11 @@ error[E0277]: the trait bound `i32: Trait` is not satisfied LL | Foo<i32>, | ^^^^^^^^ the trait `Trait` is not implemented for `i32` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Foo` --> $DIR/on-structs-and-enums.rs:3:14 | @@ -88,6 +103,11 @@ error[E0277]: the trait bound `u8: Trait` is not satisfied LL | DictionaryLike { field: Bar<u8> }, | ^^^^^^^ the trait `Trait` is not implemented for `u8` | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums.rs:1:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/on-structs-and-enums.rs:7:12 | diff --git a/tests/ui/traits/deny-builtin-object-impl.current.stderr b/tests/ui/traits/deny-builtin-object-impl.current.stderr index 5c1987426f71f..8ca3d3a057fa3 100644 --- a/tests/ui/traits/deny-builtin-object-impl.current.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.current.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied LL | test_not_object::<dyn NotObject>(); | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:10:1 + | +LL | trait NotObject {} + | ^^^^^^^^^^^^^^^ note: required by a bound in `test_not_object` --> $DIR/deny-builtin-object-impl.rs:14:23 | diff --git a/tests/ui/traits/deny-builtin-object-impl.next.stderr b/tests/ui/traits/deny-builtin-object-impl.next.stderr index 5c1987426f71f..8ca3d3a057fa3 100644 --- a/tests/ui/traits/deny-builtin-object-impl.next.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.next.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied LL | test_not_object::<dyn NotObject>(); | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:10:1 + | +LL | trait NotObject {} + | ^^^^^^^^^^^^^^^ note: required by a bound in `test_not_object` --> $DIR/deny-builtin-object-impl.rs:14:23 | diff --git a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr index 263c59ee32712..a5d0e6ab09569 100644 --- a/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr +++ b/tests/ui/traits/dont-autoderef-ty-with-escaping-var.stderr @@ -10,6 +10,11 @@ error[E0277]: the trait bound `for<'a> &'a mut Vec<&'a u32>: Foo<'static, i32>` LL | <i32 as RefFoo<i32>>::ref_foo(unknown); | ^^^ the trait `for<'a> Foo<'static, i32>` is not implemented for `&'a mut Vec<&'a u32>` | +help: this trait has no implementations, consider adding one + --> $DIR/dont-autoderef-ty-with-escaping-var.rs:3:1 + | +LL | trait Foo<'x, T> {} + | ^^^^^^^^^^^^^^^^ note: required for `i32` to implement `RefFoo<i32>` --> $DIR/dont-autoderef-ty-with-escaping-var.rs:9:9 | diff --git a/tests/ui/traits/impl-bounds-checking.stderr b/tests/ui/traits/impl-bounds-checking.stderr index 1f969efe1141d..bfa8213abe76f 100644 --- a/tests/ui/traits/impl-bounds-checking.stderr +++ b/tests/ui/traits/impl-bounds-checking.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `isize: Clone2` is not satisfied LL | impl Getter<isize> for isize { | ^^^^^ the trait `Clone2` is not implemented for `isize` | +help: this trait has no implementations, consider adding one + --> $DIR/impl-bounds-checking.rs:1:1 + | +LL | pub trait Clone2 { + | ^^^^^^^^^^^^^^^^ note: required by a bound in `Getter` --> $DIR/impl-bounds-checking.rs:6:17 | diff --git a/tests/ui/traits/new-solver/projection-discr-kind.stderr b/tests/ui/traits/new-solver/projection-discr-kind.stderr index 03e28f993e25d..e14953f19ff37 100644 --- a/tests/ui/traits/new-solver/projection-discr-kind.stderr +++ b/tests/ui/traits/new-solver/projection-discr-kind.stderr @@ -6,6 +6,11 @@ LL | needs_bar(std::mem::discriminant(&x)); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/projection-discr-kind.rs:10:1 + | +LL | trait Bar {} + | ^^^^^^^^^ note: required by a bound in `needs_bar` --> $DIR/projection-discr-kind.rs:11:22 | diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr index 7bd02550fb384..240bcef7df504 100644 --- a/tests/ui/traits/non_lifetime_binders/fail.stderr +++ b/tests/ui/traits/non_lifetime_binders/fail.stderr @@ -13,6 +13,11 @@ error[E0277]: the trait bound `T: Trait` is not satisfied LL | fail(); | ^^^^ the trait `Trait` is not implemented for `T` | +help: this trait has no implementations, consider adding one + --> $DIR/fail.rs:6:1 + | +LL | trait Trait {} + | ^^^^^^^^^^^ note: required by a bound in `fail` --> $DIR/fail.rs:10:15 | diff --git a/tests/ui/traits/object-does-not-impl-trait.stderr b/tests/ui/traits/object-does-not-impl-trait.stderr index f1dd508a46741..81d67255a0bdb 100644 --- a/tests/ui/traits/object-does-not-impl-trait.stderr +++ b/tests/ui/traits/object-does-not-impl-trait.stderr @@ -6,6 +6,11 @@ LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); } | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/object-does-not-impl-trait.rs:4:1 + | +LL | trait Foo {} + | ^^^^^^^^^ note: required by a bound in `take_foo` --> $DIR/object-does-not-impl-trait.rs:5:15 | diff --git a/tests/ui/traits/vtable-res-trait-param.stderr b/tests/ui/traits/vtable-res-trait-param.stderr index 2b3e3de9b1ab4..4cfceefb24cd0 100644 --- a/tests/ui/traits/vtable-res-trait-param.stderr +++ b/tests/ui/traits/vtable-res-trait-param.stderr @@ -6,6 +6,11 @@ LL | b.gimme_an_a(y) | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/vtable-res-trait-param.rs:1:1 + | +LL | trait TraitA { + | ^^^^^^^^^^^^ note: required by a bound in `TraitB::gimme_an_a` --> $DIR/vtable-res-trait-param.rs:6:21 | diff --git a/tests/ui/trivial-bounds/trivial-bounds-leak.stderr b/tests/ui/trivial-bounds/trivial-bounds-leak.stderr index 02c5d5d248403..be472a5076913 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-leak.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-leak.stderr @@ -27,6 +27,12 @@ LL | Foo::test(&4i32); | --------- ^^^^^ the trait `Foo` is not implemented for `i32` | | | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/trivial-bounds-leak.rs:4:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/trivial-bounds-leak.rs:26:22 @@ -36,6 +42,11 @@ LL | generic_function(5i32); | | | required by a bound introduced by this call | +help: this trait has no implementations, consider adding one + --> $DIR/trivial-bounds-leak.rs:4:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ note: required by a bound in `generic_function` --> $DIR/trivial-bounds-leak.rs:29:24 | diff --git a/tests/ui/union/projection-as-union-type-error-2.stderr b/tests/ui/union/projection-as-union-type-error-2.stderr index bab226f271df7..21f4ea103ada3 100644 --- a/tests/ui/union/projection-as-union-type-error-2.stderr +++ b/tests/ui/union/projection-as-union-type-error-2.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u8: NotImplemented` is not satisfied LL | a: <Foo as Identity>::Identity, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotImplemented` is not implemented for `u8` | +help: this trait has no implementations, consider adding one + --> $DIR/projection-as-union-type-error-2.rs:9:1 + | +LL | trait NotImplemented {} + | ^^^^^^^^^^^^^^^^^^^^ note: required for `u8` to implement `Identity` --> $DIR/projection-as-union-type-error-2.rs:11:25 | diff --git a/tests/ui/union/projection-as-union-type-error.stderr b/tests/ui/union/projection-as-union-type-error.stderr index e4fbe9603ad45..2b0241caf98ca 100644 --- a/tests/ui/union/projection-as-union-type-error.stderr +++ b/tests/ui/union/projection-as-union-type-error.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `u8: Identity` is not satisfied | LL | a: <Foo as Identity>::Identity, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Identity` is not implemented for `u8` + | +help: this trait has no implementations, consider adding one + --> $DIR/projection-as-union-type-error.rs:6:1 + | +LL | pub trait Identity { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/unsized/issue-75707.stderr b/tests/ui/unsized/issue-75707.stderr index 97618ed05ed38..aa7f9c78fa84e 100644 --- a/tests/ui/unsized/issue-75707.stderr +++ b/tests/ui/unsized/issue-75707.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `MyCall: Callback` is not satisfied LL | f::<dyn Processing<Call = MyCall>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Callback` is not implemented for `MyCall` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-75707.rs:1:1 + | +LL | pub trait Callback { + | ^^^^^^^^^^^^^^^^^^ note: required by a bound in `f` --> $DIR/issue-75707.rs:9:9 | diff --git a/tests/ui/wf/hir-wf-canonicalized.stderr b/tests/ui/wf/hir-wf-canonicalized.stderr index 9fd0f9c81ebd8..21122e37da53d 100644 --- a/tests/ui/wf/hir-wf-canonicalized.stderr +++ b/tests/ui/wf/hir-wf-canonicalized.stderr @@ -3,12 +3,24 @@ error[E0277]: the trait bound `Bar<'a, T>: Foo` is not satisfied | LL | callback: Box<dyn Callback<dyn Callback<Bar<'a, T>>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar<'a, T>` + | +help: this trait has no implementations, consider adding one + --> $DIR/hir-wf-canonicalized.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ error[E0277]: the trait bound `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static): Foo` is not satisfied --> $DIR/hir-wf-canonicalized.rs:10:15 | LL | callback: Box<dyn Callback<dyn Callback<Bar<'a, T>>>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)` + | +help: this trait has no implementations, consider adding one + --> $DIR/hir-wf-canonicalized.rs:3:1 + | +LL | trait Foo { + | ^^^^^^^^^ error[E0277]: the size for values of type `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)` cannot be known at compilation time --> $DIR/hir-wf-canonicalized.rs:10:15 diff --git a/tests/ui/wf/issue-95665.stderr b/tests/ui/wf/issue-95665.stderr index b1cda59a9165b..f80cd41a4c2d3 100644 --- a/tests/ui/wf/issue-95665.stderr +++ b/tests/ui/wf/issue-95665.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `u8: Trait` is not satisfied LL | static VAR: Struct<u8>; | ^^^^^^^^^^ the trait `Trait` is not implemented for `u8` | +help: this trait has no implementations, consider adding one + --> $DIR/issue-95665.rs:4:1 + | +LL | pub trait Trait: {} + | ^^^^^^^^^^^^^^^ note: required by a bound in `Struct` --> $DIR/issue-95665.rs:6:22 | diff --git a/tests/ui/wf/wf-complex-assoc-type.stderr b/tests/ui/wf/wf-complex-assoc-type.stderr index ef613e3132d03..6a623bec815e4 100644 --- a/tests/ui/wf/wf-complex-assoc-type.stderr +++ b/tests/ui/wf/wf-complex-assoc-type.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `bool: MyTrait` is not satisfied LL | type MyItem = Option<((AssertMyTrait<bool>, u8))>; | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `bool` | +help: this trait has no implementations, consider adding one + --> $DIR/wf-complex-assoc-type.rs:1:1 + | +LL | trait MyTrait {} + | ^^^^^^^^^^^^^ note: required by a bound in `AssertMyTrait` --> $DIR/wf-complex-assoc-type.rs:2:25 | diff --git a/tests/ui/wf/wf-foreign-fn-decl-ret.stderr b/tests/ui/wf/wf-foreign-fn-decl-ret.stderr index b03023b5fd14f..0e93601043a69 100644 --- a/tests/ui/wf/wf-foreign-fn-decl-ret.stderr +++ b/tests/ui/wf/wf-foreign-fn-decl-ret.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `(): Foo` is not satisfied | LL | pub fn lint_me() -> <() as Foo>::Assoc; | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/wf-foreign-fn-decl-ret.rs:6:1 + | +LL | pub trait Foo { + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied --> $DIR/wf-foreign-fn-decl-ret.rs:14:32 @@ -10,6 +16,11 @@ error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied LL | pub fn lint_me_aswell() -> Bar<u32>; | ^^^^^^^^ the trait `Unsatisfied` is not implemented for `u32` | +help: this trait has no implementations, consider adding one + --> $DIR/wf-foreign-fn-decl-ret.rs:1:1 + | +LL | pub trait Unsatisfied {} + | ^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `Bar` --> $DIR/wf-foreign-fn-decl-ret.rs:4:19 | diff --git a/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr b/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr index e460cdcd3f3e5..52f46562c3716 100644 --- a/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr +++ b/tests/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.stderr @@ -3,6 +3,12 @@ error[E0277]: the trait bound `DefaultAllocator: Allocator` is not satisfied | LL | struct Foo(Matrix<<DefaultAllocator as Allocator>::Buffer>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Allocator` is not implemented for `DefaultAllocator` + | +help: this trait has no implementations, consider adding one + --> $DIR/wf-packed-on-proj-of-type-as-unimpl-trait.rs:23:1 + | +LL | pub trait Allocator { type Buffer; } + | ^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr index 191a8ca8ebcf3..29b36f44a4d12 100644 --- a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr +++ b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied LL | called() | ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&'b ())` | +help: this trait has no implementations, consider adding one + --> $DIR/higher-ranked-fn-type.rs:6:1 + | +LL | trait Foo { + | ^^^^^^^^^ note: required by a bound in `called` --> $DIR/higher-ranked-fn-type.rs:12:25 | diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr index ce409f627be20..54afeaa7edabc 100644 --- a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr +++ b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_t LL | called() | ^^^^^^ the trait `for<Region(BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b))> Foo` is not implemented for `fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), 'b) }) ())` | +help: this trait has no implementations, consider adding one + --> $DIR/higher-ranked-fn-type.rs:6:1 + | +LL | trait Foo { + | ^^^^^^^^^ note: required by a bound in `called` --> $DIR/higher-ranked-fn-type.rs:12:25 | diff --git a/tests/ui/where-clauses/where-clause-method-substituion.stderr b/tests/ui/where-clauses/where-clause-method-substituion.stderr index 8c47ed6d4317a..2f3b615a13bdf 100644 --- a/tests/ui/where-clauses/where-clause-method-substituion.stderr +++ b/tests/ui/where-clauses/where-clause-method-substituion.stderr @@ -4,6 +4,11 @@ error[E0277]: the trait bound `X: Foo<X>` is not satisfied LL | 1.method::<X>(); | ^ the trait `Foo<X>` is not implemented for `X` | +help: this trait has no implementations, consider adding one + --> $DIR/where-clause-method-substituion.rs:1:1 + | +LL | trait Foo<T> { + | ^^^^^^^^^^^^ note: required by a bound in `Bar::method` --> $DIR/where-clause-method-substituion.rs:6:34 |