Auto merge of #67850 - GuillaumeGomez:err-codes-checkup, r=Mark-Simulacrum

Error codes checkup and rustdoc test fix

This PR does a few things:

 * fix how rustdoc checks that an error code has been thrown (it only checked for "E0XXX" so if it appeared in the output because the file has it in its name or wherever, it passed the test, which was incorrect)
 * fix the failing code examples that weren't throwing the expected error code
diff --git a/src/librustc_error_codes/error_codes/E0445.md b/src/librustc_error_codes/error_codes/E0445.md
index 9cc62b2..e6a28a9 100644
--- a/src/librustc_error_codes/error_codes/E0445.md
+++ b/src/librustc_error_codes/error_codes/E0445.md
@@ -12,6 +12,8 @@
 pub trait Bar : Foo {} // error: private trait in public interface
 pub struct Bar2<T: Foo>(pub T); // same error
 pub fn foo<T: Foo> (t: T) {} // same error
+
+fn main() {}
 ```
 
 To solve this error, please ensure that the trait is also public. The trait
@@ -26,4 +28,6 @@
 pub trait Bar : Foo {} // ok!
 pub struct Bar2<T: Foo>(pub T); // ok!
 pub fn foo<T: Foo> (t: T) {} // ok!
+
+fn main() {}
 ```
diff --git a/src/librustc_error_codes/error_codes/E0446.md b/src/librustc_error_codes/error_codes/E0446.md
index d014447..77a1834 100644
--- a/src/librustc_error_codes/error_codes/E0446.md
+++ b/src/librustc_error_codes/error_codes/E0446.md
@@ -12,6 +12,8 @@
         Bar(0)
     }
 }
+
+fn main() {}
 ```
 
 To solve this error, please ensure that the type is also public. The type
@@ -27,4 +29,6 @@
         Bar(0)
     }
 }
+
+fn main() {}
 ```
diff --git a/src/librustc_error_codes/error_codes/E0491.md b/src/librustc_error_codes/error_codes/E0491.md
index 1ccaf71..d45663f 100644
--- a/src/librustc_error_codes/error_codes/E0491.md
+++ b/src/librustc_error_codes/error_codes/E0491.md
@@ -3,30 +3,34 @@
 Erroneous code example:
 
 ```compile_fail,E0491
-trait SomeTrait<'a> {
-    type Output;
+struct Foo<'a> {
+    x: fn(&'a i32),
 }
 
-impl<'a, T> SomeTrait<'a> for T {
-    type Output = &'a T; // compile error E0491
+trait Trait<'a, 'b> {
+    type Out;
+}
+
+impl<'a, 'b> Trait<'a, 'b> for usize {
+    type Out = &'a Foo<'b>; // error!
 }
 ```
 
-Here, the problem is that a reference type like `&'a T` is only valid
-if all the data in T outlives the lifetime `'a`. But this impl as written
-is applicable to any lifetime `'a` and any type `T` -- we have no guarantee
-that `T` outlives `'a`. To fix this, you can add a where clause like
-`where T: 'a`.
+Here, the problem is that the compiler cannot be sure that the `'b` lifetime
+will live longer than `'a`, which should be mandatory in order to be sure that
+`Trait::Out` will always have a reference pointing to an existing type. So in
+this case, we just need to tell the compiler than `'b` must outlive `'a`:
 
 ```
-trait SomeTrait<'a> {
-    type Output;
+struct Foo<'a> {
+    x: fn(&'a i32),
 }
 
-impl<'a, T> SomeTrait<'a> for T
-where
-    T: 'a,
-{
-    type Output = &'a T; // compile error E0491
+trait Trait<'a, 'b> {
+    type Out;
+}
+
+impl<'a, 'b: 'a> Trait<'a, 'b> for usize { // we added the lifetime enforcement
+    type Out = &'a Foo<'b>; // it now works!
 }
 ```
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index cc5359b..b5731ff 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -300,7 +300,6 @@
             eprint!("{}", self.0);
         }
     }
-
     let out = str::from_utf8(&output.stderr).unwrap();
     let _bomb = Bomb(&out);
     match (output.status.success(), compile_fail) {
@@ -310,7 +309,7 @@
         (true, false) => {}
         (false, true) => {
             if !error_codes.is_empty() {
-                error_codes.retain(|err| !out.contains(err));
+                error_codes.retain(|err| !out.contains(&format!("error[{}]: ", err)));
 
                 if !error_codes.is_empty() {
                     return Err(TestFailure::MissingErrorCodes(error_codes));