about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml1
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs56
-rw-r--r--compiler/rustc_middle/messages.ftl2
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs2
-rw-r--r--compiler/rustc_parse/messages.ftl4
-rw-r--r--compiler/rustc_parse/src/errors.rs4
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs1
-rw-r--r--compiler/rustc_ty_utils/src/sig_types.rs39
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh29
-rw-r--r--src/ci/github-actions/ci.yml1
-rw-r--r--tests/ui/coroutine/gen_block_panic.rs26
-rw-r--r--tests/ui/coroutine/gen_block_panic.stderr12
-rw-r--r--tests/ui/coroutine/gen_fn.e2024.stderr4
-rw-r--r--tests/ui/coroutine/gen_fn.rs2
-rw-r--r--tests/ui/or-patterns/exhaustiveness-pass.rs6
-rw-r--r--tests/ui/traits/item-privacy.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs44
20 files changed, 191 insertions, 70 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ddeb489c647..5f14cd36ce4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -382,6 +382,7 @@ jobs:
           - name: x86_64-msvc-ext
             env:
               SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
+              HOST_TARGET: x86_64-pc-windows-msvc
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json"
               DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
             os: windows-2019-8core-32gb
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 3ed22e095e8..12cc5ed2f1a 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -35,6 +35,7 @@ use rustc_span::def_id::DefIdSet;
 use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Symbol;
 use rustc_span::{edit_distance, source_map, ExpnKind, FileName, MacroKind, Span};
+use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote;
 use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -192,7 +193,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .span_if_local(def_id)
                     .unwrap_or_else(|| self.tcx.def_span(def_id));
                 err.span_label(sp, format!("private {kind} defined here"));
-                self.suggest_valid_traits(&mut err, out_of_scope_traits);
+                self.suggest_valid_traits(&mut err, out_of_scope_traits, true);
                 err.emit();
             }
 
@@ -2464,6 +2465,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut Diagnostic,
         valid_out_of_scope_traits: Vec<DefId>,
+        explain: bool,
     ) -> bool {
         if !valid_out_of_scope_traits.is_empty() {
             let mut candidates = valid_out_of_scope_traits;
@@ -2476,7 +2478,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .find(|did| self.tcx.is_diagnostic_item(sym::TryInto, **did))
                 .copied();
 
-            err.help("items from traits can only be used if the trait is in scope");
+            if explain {
+                err.help("items from traits can only be used if the trait is in scope");
+            }
             let msg = format!(
                 "the following {traits_are} implemented but not in scope; \
                  perhaps add a `use` for {one_of_them}:",
@@ -2693,7 +2697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
         }
-        if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
+        if self.suggest_valid_traits(err, valid_out_of_scope_traits, true) {
             return;
         }
 
@@ -2970,22 +2974,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (candidates, Vec::new())
             };
 
+            let impls_trait = |def_id: DefId| {
+                let args = ty::GenericArgs::for_item(self.tcx, def_id, |param, _| {
+                    if param.index == 0 {
+                        rcvr_ty.into()
+                    } else {
+                        self.infcx.var_for_def(span, param)
+                    }
+                });
+                self.infcx
+                    .type_implements_trait(def_id, args, self.param_env)
+                    .must_apply_modulo_regions()
+                    && param_type.is_none()
+            };
             match &potential_candidates[..] {
                 [] => {}
                 [trait_info] if trait_info.def_id.is_local() => {
-                    err.subdiagnostic(CandidateTraitNote {
-                        span: self.tcx.def_span(trait_info.def_id),
-                        trait_name: self.tcx.def_path_str(trait_info.def_id),
-                        item_name,
-                        action_or_ty: if trait_missing_method {
-                            "NONE".to_string()
-                        } else {
-                            param_type.map_or_else(
-                                || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented.
-                                ToString::to_string,
-                            )
-                        },
-                    });
+                    if impls_trait(trait_info.def_id) {
+                        self.suggest_valid_traits(err, vec![trait_info.def_id], false);
+                    } else {
+                        err.subdiagnostic(CandidateTraitNote {
+                            span: self.tcx.def_span(trait_info.def_id),
+                            trait_name: self.tcx.def_path_str(trait_info.def_id),
+                            item_name,
+                            action_or_ty: if trait_missing_method {
+                                "NONE".to_string()
+                            } else {
+                                param_type.map_or_else(
+                                    || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented.
+                                    ToString::to_string,
+                                )
+                            },
+                        });
+                    }
                 }
                 trait_infos => {
                     let mut msg = message(param_type.map_or_else(
@@ -2993,6 +3014,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         |param| format!("restrict type parameter `{param}` with"),
                     ));
                     for (i, trait_info) in trait_infos.iter().enumerate() {
+                        if impls_trait(trait_info.def_id) {
+                            self.suggest_valid_traits(err, vec![trait_info.def_id], false);
+                        }
                         msg.push_str(&format!(
                             "\ncandidate #{}: `{}`",
                             i + 1,
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index 37ff5bcf1e2..27d555d7e26 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -12,6 +12,8 @@ middle_assert_coroutine_resume_after_return = coroutine resumed after completion
 middle_assert_divide_by_zero =
     attempt to divide `{$val}` by zero
 
+middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked
+
 middle_assert_misaligned_ptr_deref =
     misaligned pointer dereference: address must be a multiple of {$required} but is {$found}
 
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index c2aa015f4b7..9dfbe1733cc 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -250,8 +250,7 @@ impl<O> AssertKind<O> {
                 middle_assert_coroutine_resume_after_return
             }
             ResumedAfterPanic(CoroutineKind::Async(_)) => middle_assert_async_resume_after_panic,
-            // FIXME(gen_blocks): custom error message for `gen` blocks
-            ResumedAfterPanic(CoroutineKind::Gen(_)) => middle_assert_async_resume_after_panic,
+            ResumedAfterPanic(CoroutineKind::Gen(_)) => middle_assert_gen_resume_after_panic,
             ResumedAfterPanic(CoroutineKind::Coroutine) => {
                 middle_assert_coroutine_resume_after_panic
             }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 25e0f3ceaa4..59f0849d08b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -931,7 +931,7 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
             let specialized = pat.specialize(pcx, &ctor);
             for (subpat, column) in specialized.iter().zip(&mut specialized_columns) {
                 if subpat.is_or_pat() {
-                    column.patterns.extend(subpat.iter_fields())
+                    column.patterns.extend(subpat.flatten_or_pat())
                 } else {
                     column.patterns.push(subpat)
                 }
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 9bedd7b8a33..9ba1f0a5df9 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -278,8 +278,8 @@ parse_found_expr_would_be_stmt = expected expression, found `{$token}`
 parse_function_body_equals_expr = function body cannot be `= expression;`
     .suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`
 
-parse_gen_block = `gen` blocks are not yet implemented
-    .help = only the keyword is reserved for now
+parse_gen_fn = `gen` functions are not yet implemented
+    .help = for now you can use `gen {"{}"}` blocks and return `impl Iterator` instead
 
 parse_generic_args_in_pat_require_turbofish_syntax = generic args in patterns require the turbofish syntax
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index c0e94d15da0..e5cd91a32a7 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -521,9 +521,9 @@ pub(crate) struct CatchAfterTry {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_gen_block)]
+#[diag(parse_gen_fn)]
 #[help]
-pub(crate) struct GenBlock {
+pub(crate) struct GenFn {
     #[primary_span]
     pub span: Span,
 }
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index a9f456d64cd..55ad3f42938 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2372,7 +2372,7 @@ impl<'a> Parser<'a> {
         }
 
         if let Gen::Yes { span, .. } = genness {
-            self.sess.emit_err(errors::GenBlock { span });
+            self.sess.emit_err(errors::GenFn { span });
         }
 
         if !self.eat_keyword_case(kw::Fn, case) {
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index f7d54566cb7..9242a1a751b 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -121,6 +121,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
 }
 
 impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
+    #[instrument(skip(self), ret, level = "trace")]
     fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> {
         self.visit_spanned(span, value);
         ControlFlow::Continue(())
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
index 1ab39974e0f..ccdc6120196 100644
--- a/compiler/rustc_ty_utils/src/sig_types.rs
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -4,7 +4,7 @@
 use std::ops::ControlFlow;
 
 use rustc_hir::{def::DefKind, def_id::LocalDefId};
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 use rustc_type_ir::visit::TypeVisitable;
 
@@ -25,24 +25,9 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
     let kind = tcx.def_kind(item);
     trace!(?kind);
     match kind {
-        DefKind::Coroutine => {
-            match tcx.type_of(item).instantiate_identity().kind() {
-                ty::Coroutine(_, args, _) => visitor.visit(tcx.def_span(item), args.as_coroutine().sig())?,
-                _ => bug!(),
-            }
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
-                visitor.visit(span, pred)?;
-            }
-        }
-        // Walk over the signature of the function-like
-        DefKind::Closure | DefKind::AssocFn | DefKind::Fn => {
-            let ty_sig = match kind {
-                DefKind::Closure => match tcx.type_of(item).instantiate_identity().kind() {
-                    ty::Closure(_, args) => args.as_closure().sig(),
-                    _ => bug!(),
-                },
-                _ => tcx.fn_sig(item).instantiate_identity(),
-            };
+        // Walk over the signature of the function
+        DefKind::AssocFn | DefKind::Fn => {
+            let ty_sig = tcx.fn_sig(item).instantiate_identity();
             let hir_sig = tcx.hir().get_by_def_id(item).fn_decl().unwrap();
             // Walk over the inputs and outputs manually in order to get good spans for them.
             visitor.visit(hir_sig.output.span(), ty_sig.output());
@@ -61,7 +46,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
                 Some(ty) => ty.span,
                 _ => tcx.def_span(item),
             };
-            visitor.visit(span,  tcx.type_of(item).instantiate_identity());
+            visitor.visit(span, tcx.type_of(item).instantiate_identity());
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
@@ -74,13 +59,15 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         // Look at field types
         DefKind::Struct | DefKind::Union | DefKind::Enum => {
             let span = tcx.def_ident_span(item).unwrap();
-            visitor.visit(span,  tcx.type_of(item).instantiate_identity());
+            visitor.visit(span, tcx.type_of(item).instantiate_identity());
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
         }
-        // Does not have a syntactical signature
-        DefKind::InlineConst => {}
+        // These are not part of a public API, they can only appear as hidden types, and there
+        // the interesting parts are solely in the signature of the containing item's opaque type
+        // or dyn type.
+        DefKind::InlineConst | DefKind::Closure | DefKind::Coroutine => {}
         DefKind::Impl { of_trait } => {
             if of_trait {
                 let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
@@ -94,13 +81,9 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
             visitor.visit(span, tcx.type_of(item).instantiate_identity());
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
-            }}
-        DefKind::Trait => {
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
-                visitor.visit(span, pred)?;
             }
         }
-        DefKind::TraitAlias => {
+        DefKind::TraitAlias | DefKind::Trait => {
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
index 85f2f84a44c..b0eeff0c576 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
@@ -83,6 +83,8 @@ ENV RUST_CONFIGURE_ARGS \
   --build=x86_64-unknown-linux-gnu \
   --save-toolstates=/tmp/toolstate/toolstates.json
 
+ENV HOST_TARGET x86_64-unknown-linux-gnu
+
 ENV SCRIPT /tmp/checktools.sh ../x.py && \
   NODE_PATH=`npm root -g` python3 ../x.py test tests/rustdoc-gui --stage 2 \
     --test-args "'--no-sandbox --jobs 1'"
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index 7dde6370904..821a09feb2d 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -1,4 +1,5 @@
 #!/bin/sh
+# ignore-tidy-linelength
 
 set -eu
 
@@ -26,8 +27,30 @@ python3 "$X_PY" test --stage 2 src/tools/clippy
 python3 "$X_PY" test --stage 2 src/tools/rustfmt
 python3 "$X_PY" test --stage 2 src/tools/miri
 # We natively run this script on x86_64-unknown-linux-gnu and x86_64-pc-windows-msvc.
-# Also cover some other targets (on both of these hosts) via cross-testing.
+# Also cover some other targets via cross-testing, in particular all tier 1 targets.
 export BOOTSTRAP_SKIP_TARGET_SANITY=1 # we don't need `cc` for these targets
-python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc
-python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin
+case $HOST_TARGET in
+  x86_64-unknown-linux-gnu)
+    # Only this branch runs in PR CI.
+    # Fully test all main OSes, including a 32bit target.
+    python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-apple-darwin
+    python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-msvc
+    # Only run "pass" tests for the remaining targets, which is quite a bit faster.
+    python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass
+    python3 "$X_PY" test --stage 2 src/tools/miri --target i686-unknown-linux-gnu --test-args pass
+    python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-unknown-linux-gnu --test-args pass
+    python3 "$X_PY" test --stage 2 src/tools/miri --target s390x-unknown-linux-gnu --test-args pass
+    ;;
+  x86_64-pc-windows-msvc)
+    # Strangely, Linux targets do not work here. cargo always says
+    # "error: cannot produce cdylib for ... as the target ... does not support these crate types".
+    # Only run "pass" tests, which is quite a bit faster.
+    python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass
+    python3 "$X_PY" test --stage 2 src/tools/miri --target i686-pc-windows-gnu --test-args pass
+    ;;
+  *)
+    echo "FATAL: unexpected host $HOST_TARGET"
+    exit 1
+    ;;
+esac
 unset BOOTSTRAP_SKIP_TARGET_SANITY
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index bbba6600581..2feb51920df 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -582,6 +582,7 @@ jobs:
           - name: x86_64-msvc-ext
             env:
               SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows
+              HOST_TARGET: x86_64-pc-windows-msvc
               RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json
               DEPLOY_TOOLSTATES_JSON: toolstates-windows.json
             <<: *job-windows-8c
diff --git a/tests/ui/coroutine/gen_block_panic.rs b/tests/ui/coroutine/gen_block_panic.rs
new file mode 100644
index 00000000000..2da0eb512cc
--- /dev/null
+++ b/tests/ui/coroutine/gen_block_panic.rs
@@ -0,0 +1,26 @@
+//compile-flags: --edition 2024 -Zunstable-options
+// run-pass
+// needs-unwind
+#![feature(gen_blocks)]
+
+fn main() {
+    let mut iter = gen {
+        yield 42;
+        panic!("foo");
+        yield 69; //~ WARN: unreachable statement
+    };
+    assert_eq!(iter.next(), Some(42));
+    let mut tmp = std::panic::AssertUnwindSafe(&mut iter);
+    match std::panic::catch_unwind(move || tmp.next()) {
+        Ok(_) => unreachable!(),
+        Err(err) => assert_eq!(*err.downcast::<&'static str>().unwrap(), "foo"),
+    }
+
+    match std::panic::catch_unwind(move || iter.next()) {
+        Ok(_) => unreachable!(),
+        Err(err) => assert_eq!(
+            *err.downcast::<&'static str>().unwrap(),
+            "`gen fn` should just keep returning `None` after panicking",
+        ),
+    }
+}
diff --git a/tests/ui/coroutine/gen_block_panic.stderr b/tests/ui/coroutine/gen_block_panic.stderr
new file mode 100644
index 00000000000..a0a6d1063c4
--- /dev/null
+++ b/tests/ui/coroutine/gen_block_panic.stderr
@@ -0,0 +1,12 @@
+warning: unreachable statement
+  --> $DIR/gen_block_panic.rs:10:9
+   |
+LL |         panic!("foo");
+   |         ------------- any code following this expression is unreachable
+LL |         yield 69;
+   |         ^^^^^^^^^ unreachable statement
+   |
+   = note: `#[warn(unreachable_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/coroutine/gen_fn.e2024.stderr b/tests/ui/coroutine/gen_fn.e2024.stderr
index 41bd04d9769..388e10fd65e 100644
--- a/tests/ui/coroutine/gen_fn.e2024.stderr
+++ b/tests/ui/coroutine/gen_fn.e2024.stderr
@@ -1,10 +1,10 @@
-error: `gen` blocks are not yet implemented
+error: `gen` functions are not yet implemented
   --> $DIR/gen_fn.rs:4:1
    |
 LL | gen fn foo() {}
    | ^^^
    |
-   = help: only the keyword is reserved for now
+   = help: for now you can use `gen {}` blocks and return `impl Iterator` instead
 
 error: aborting due to previous error
 
diff --git a/tests/ui/coroutine/gen_fn.rs b/tests/ui/coroutine/gen_fn.rs
index 9566660dfb5..da515f263b0 100644
--- a/tests/ui/coroutine/gen_fn.rs
+++ b/tests/ui/coroutine/gen_fn.rs
@@ -3,6 +3,6 @@
 
 gen fn foo() {}
 //[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `unsafe`, or `use`, found `gen`
-//[e2024]~^^ ERROR: `gen` blocks are not yet implemented
+//[e2024]~^^ ERROR: `gen` functions are not yet implemented
 
 fn main() {}
diff --git a/tests/ui/or-patterns/exhaustiveness-pass.rs b/tests/ui/or-patterns/exhaustiveness-pass.rs
index e8c8a0e7ba5..428b9a19fe6 100644
--- a/tests/ui/or-patterns/exhaustiveness-pass.rs
+++ b/tests/ui/or-patterns/exhaustiveness-pass.rs
@@ -35,4 +35,10 @@ fn main() {
         ((0, 0) | (1, 0),) => {}
         _ => {}
     }
+
+    // This one caused ICE https://github.com/rust-lang/rust/issues/117378
+    match (0u8, 0) {
+        (x @ 0 | x @ (1 | 2), _) => {}
+        (3.., _) => {}
+    }
 }
diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr
index af2e0763212..9382673afe0 100644
--- a/tests/ui/traits/item-privacy.stderr
+++ b/tests/ui/traits/item-privacy.stderr
@@ -8,11 +8,10 @@ LL |     S.a();
    |       ^ method not found in `S`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
-note: `method::A` defines an item `a`, perhaps you need to implement it
-  --> $DIR/item-privacy.rs:6:5
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL + use method::A;
    |
-LL |     trait A {
-   |     ^^^^^^^
 
 error[E0599]: no method named `b` found for struct `S` in the current scope
   --> $DIR/item-privacy.rs:68:7
@@ -51,11 +50,10 @@ LL |     S::a(&S);
    |        ^ function or associated item not found in `S`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
-note: `method::A` defines an item `a`, perhaps you need to implement it
-  --> $DIR/item-privacy.rs:6:5
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL + use method::A;
    |
-LL |     trait A {
-   |     ^^^^^^^
 
 error[E0599]: no function or associated item named `b` found for struct `S` in the current scope
   --> $DIR/item-privacy.rs:80:8
@@ -91,11 +89,10 @@ LL |     S::A;
    |        ^ associated item not found in `S`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
-note: `assoc_const::A` defines an item `A`, perhaps you need to implement it
-  --> $DIR/item-privacy.rs:24:5
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL + use assoc_const::A;
    |
-LL |     trait A {
-   |     ^^^^^^^
 
 error[E0599]: no associated item named `B` found for struct `S` in the current scope
   --> $DIR/item-privacy.rs:98:8
diff --git a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs
new file mode 100644
index 00000000000..5f3dbaa1798
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs
@@ -0,0 +1,44 @@
+//! This test checks that we do not walk types in async blocks for
+//! determining the opaque types that appear in a signature. async blocks,
+//! all other coroutines and closures are always private and not part of
+//! a signature. They become part of a signature via `dyn Trait` or `impl Trait`,
+//! which is something that we process abstractly without looking at its hidden
+//! types.
+// edition: 2021
+// check-pass
+
+#![feature(impl_trait_in_assoc_type)]
+
+use std::future::Future;
+
+pub struct MemtableLocalStateStore {
+    mem_table: MemTable,
+}
+
+impl LocalStateStore for MemtableLocalStateStore {
+    type IterStream<'a> = impl Sized + 'a where Self: 'a;
+
+    fn iter(&self) -> impl Future<Output = Self::IterStream<'_>> + '_ {
+        async move { merge_stream(self.mem_table.iter()) }
+    }
+}
+
+trait LocalStateStore {
+    type IterStream<'a>
+    where
+        Self: 'a;
+
+    fn iter(&self) -> impl Future<Output = Self::IterStream<'_>> + '_;
+}
+
+struct MemTable;
+
+impl MemTable {
+    fn iter<'a>(&'a self) -> impl Iterator<Item = &'a ()> {
+        std::iter::empty()
+    }
+}
+
+pub(crate) async fn merge_stream<'a>(mem_table_iter: impl Iterator<Item = &'a ()>) {}
+
+fn main() {}