about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-07-08 10:46:29 +0000
committerbors <bors@rust-lang.org>2023-07-08 10:46:29 +0000
commitce519c5945c90596cf429dc2a91c846daeb75cd1 (patch)
tree0973cdb39243f1c1f624b362a5a68d210ab6fdb4
parentd4096e0412ac5de785d739a0aa2b1c1c7b9d3b7d (diff)
parent7a22c7e6f4a18e0dd3427ce2c3c8bf4cda882ad3 (diff)
downloadrust-ce519c5945c90596cf429dc2a91c846daeb75cd1.tar.gz
rust-ce519c5945c90596cf429dc2a91c846daeb75cd1.zip
Auto merge of #113474 - compiler-errors:rollup-07x1up7, r=compiler-errors
Rollup of 8 pull requests

Successful merges:

 - #113413 (Add needs-triage to all new issues)
 - #113426 (Don't ICE in `resolve_bound_vars` when associated return-type bounds are in bad positions)
 - #113427 (Remove `variances_of` on RPITIT GATs, remove its one use-case)
 - #113441 (miri: check that assignments do not self-overlap)
 - #113453 (Remove unused from_method from rustc_on_unimplemented)
 - #113456 (Avoid calling report_forbidden_specialization for RPITITs)
 - #113466 (Update cargo)
 - #113467 (Fix comment of `fn_can_unwind`)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs7
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs12
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs11
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs16
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs20
m---------src/tools/cargo0
-rw-r--r--src/tools/miri/tests/fail/overlapping_assignment.rs23
-rw-r--r--src/tools/miri/tests/fail/overlapping_assignment.stderr20
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.current.stderr30
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.next.stderr30
-rw-r--r--tests/ui/async-await/in-trait/missing-feature-flag.rs23
-rw-r--r--tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs13
-rw-r--r--tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr18
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs19
-rw-r--r--triagebot.toml4
20 files changed, 250 insertions, 56 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 24c1fe43d0c..ca1106384fd 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -700,8 +700,13 @@ where
             assert_eq!(src.layout.size, dest.layout.size);
         }
 
+        // Setting `nonoverlapping` here only has an effect when we don't hit the fast-path above,
+        // but that should at least match what LLVM does where `memcpy` is also only used when the
+        // type does not have Scalar/ScalarPair layout.
+        // (Or as the `Assign` docs put it, assignments "not producing primitives" must be
+        // non-overlapping.)
         self.mem_copy(
-            src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ false,
+            src.ptr, src.align, dest.ptr, dest.align, dest_size, /*nonoverlapping*/ true,
         )
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 270b90fa6b2..120545c8e5d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -722,7 +722,14 @@ pub(super) fn check_specialization_validity<'tcx>(
     let result = opt_result.unwrap_or(Ok(()));
 
     if let Err(parent_impl) = result {
-        report_forbidden_specialization(tcx, impl_item, parent_impl);
+        if !tcx.is_impl_trait_in_trait(impl_item) {
+            report_forbidden_specialization(tcx, impl_item, parent_impl);
+        } else {
+            tcx.sess.delay_span_bug(
+                DUMMY_SP,
+                format!("parent item: {:?} not marked as default", parent_impl),
+            );
+        }
     }
 }
 
@@ -1485,7 +1492,9 @@ fn opaque_type_cycle_error(
                 }
 
                 for closure_def_id in visitor.closures {
-                    let Some(closure_local_did) = closure_def_id.as_local() else { continue; };
+                    let Some(closure_local_did) = closure_def_id.as_local() else {
+                        continue;
+                    };
                     let typeck_results = tcx.typeck(closure_local_did);
 
                     let mut label_match = |ty: Ty<'_>, span| {
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 97a3e01c52a..acd0bcd8e5c 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor};
 use rustc_session::lint;
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::{sym, Ident};
-use rustc_span::Span;
+use rustc_span::{Span, DUMMY_SP};
 use std::fmt;
 
 use crate::errors;
@@ -338,7 +338,17 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
 
                 Scope::TraitRefBoundary { .. } => {
                     // We should only see super trait lifetimes if there is a `Binder` above
-                    assert!(supertrait_bound_vars.is_empty());
+                    // though this may happen when we call `poly_trait_ref_binder_info` with
+                    // an (erroneous, #113423) associated return type bound in an impl header.
+                    if !supertrait_bound_vars.is_empty() {
+                        self.tcx.sess.delay_span_bug(
+                            DUMMY_SP,
+                            format!(
+                                "found supertrait lifetimes without a binder to append \
+                                them to: {supertrait_bound_vars:?}"
+                            ),
+                        );
+                    }
                     break (vec![], BinderScopeType::Normal);
                 }
 
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 49aee6b59a2..066e7449189 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -7,7 +7,7 @@ use rustc_arena::DroplessArena;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, CrateVariancesMap, ImplTraitInTraitData, SubstsRef, Ty, TyCtxt};
+use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt};
 use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
 use std::ops::ControlFlow;
 
@@ -59,13 +59,6 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
         DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
             return variance_of_opaque(tcx, item_def_id);
         }
-        DefKind::AssocTy => {
-            if let Some(ImplTraitInTraitData::Trait { .. }) =
-                tcx.opt_rpitit_info(item_def_id.to_def_id())
-            {
-                return variance_of_opaque(tcx, item_def_id);
-            }
-        }
         _ => {}
     }
 
@@ -125,7 +118,8 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
                 // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
                 // at all for RPITITs.
                 ty::Alias(_, ty::AliasTy { def_id, substs, .. })
-                    if self.tcx.is_impl_trait_in_trait(*def_id) =>
+                    if self.tcx.is_impl_trait_in_trait(*def_id)
+                        && !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() =>
                 {
                     self.visit_opaque(*def_id, substs)
                 }
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 3098b8bc2f9..5927f79a183 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -473,17 +473,6 @@ where
                 }
             }
 
-            ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => {
-                // Skip lifetime parameters that are not captures.
-                let variances = self.tcx.variances_of(proj.def_id);
-
-                for (v, s) in std::iter::zip(variances, proj.substs.iter()) {
-                    if *v != ty::Variance::Bivariant {
-                        s.visit_with(self);
-                    }
-                }
-            }
-
             _ => {
                 ty.super_visit_with(self);
             }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 0fe801ad2ed..d95b05ef754 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1110,12 +1110,11 @@ where
 ///
 /// This takes two primary parameters:
 ///
-/// * `codegen_fn_attr_flags` - these are flags calculated as part of the
-///   codegen attrs for a defined function. For function pointers this set of
-///   flags is the empty set. This is only applicable for Rust-defined
-///   functions, and generally isn't needed except for small optimizations where
-///   we try to say a function which otherwise might look like it could unwind
-///   doesn't actually unwind (such as for intrinsics and such).
+/// * `fn_def_id` - the `DefId` of the function. If this is provided then we can
+///   determine more precisely if the function can unwind. If this is not provided
+///   then we will only infer whether the function can unwind or not based on the
+///   ABI of the function. For example, a function marked with `#[rustc_nounwind]`
+///   is known to not unwind even if it's using Rust ABI.
 ///
 /// * `abi` - this is the ABI that the function is defined with. This is the
 ///   primary factor for determining whether a function can unwind or not.
@@ -1147,11 +1146,6 @@ where
 ///   aborts the process.
 /// * This affects whether functions have the LLVM `nounwind` attribute, which
 ///   affects various optimizations and codegen.
-///
-/// FIXME: this is actually buggy with respect to Rust functions. Rust functions
-/// compiled with `-Cpanic=unwind` and referenced from another crate compiled
-/// with `-Cpanic=abort` will look like they can't unwind when in fact they
-/// might (from a foreign exception or similar).
 #[inline]
 #[tracing::instrument(level = "debug", skip(tcx))]
 pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 66a627d5aac..5c6d43e50ea 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -759,7 +759,6 @@ symbols! {
         from_desugaring,
         from_fn,
         from_iter,
-        from_method,
         from_output,
         from_residual,
         from_size_align_unchecked,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index 1e4d30f48b2..b16d2eb5fc1 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -41,7 +41,6 @@ pub trait TypeErrCtxtExt<'tcx> {
 static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
     kw::SelfUpper,
     sym::ItemContext,
-    sym::from_method,
     sym::from_desugaring,
     sym::direct,
     sym::cause,
@@ -172,23 +171,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         }
 
-        if let ObligationCauseCode::ItemObligation(item)
-        | ObligationCauseCode::BindingObligation(item, _)
-        | ObligationCauseCode::ExprItemObligation(item, ..)
-        | ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code()
-        {
-            // FIXME: maybe also have some way of handling methods
-            // from other traits? That would require name resolution,
-            // which we might want to be some sort of hygienic.
-            //
-            // Currently I'm leaving it for what I need for `try`.
-            if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
-                let method = self.tcx.item_name(item);
-                flags.push((sym::from_method, None));
-                flags.push((sym::from_method, Some(method.to_string())));
-            }
-        }
-
         if let Some(k) = obligation.cause.span.desugaring_kind() {
             flags.push((sym::from_desugaring, None));
             flags.push((sym::from_desugaring, Some(format!("{:?}", k))));
@@ -672,7 +654,7 @@ impl<'tcx> OnUnimplementedFormatString {
                             None => {
                                 if let Some(val) = options.get(&s) {
                                     val
-                                } else if s == sym::from_desugaring || s == sym::from_method {
+                                } else if s == sym::from_desugaring {
                                     // don't break messages using these two arguments incorrectly
                                     &empty_string
                                 } else if s == sym::ItemContext {
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 5b377cece0e0dd0af686cf53ce4637d5d85c2a1
+Subproject 45782b6b8afd1da042d45c2daeec9c0744f72cc
diff --git a/src/tools/miri/tests/fail/overlapping_assignment.rs b/src/tools/miri/tests/fail/overlapping_assignment.rs
new file mode 100644
index 00000000000..84994c179f9
--- /dev/null
+++ b/src/tools/miri/tests/fail/overlapping_assignment.rs
@@ -0,0 +1,23 @@
+#![feature(core_intrinsics)]
+#![feature(custom_mir)]
+
+use std::intrinsics::mir::*;
+
+// It's not that easy to fool the MIR validity check
+// which wants to prevent overlapping assignments...
+// So we use two separate pointer arguments, and then arrange for them to alias.
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub fn self_copy(ptr1: *mut [i32; 4], ptr2: *mut [i32; 4]) {
+    mir! {
+        {
+            *ptr1 = *ptr2; //~ERROR: overlapping ranges
+            Return()
+        }
+    }
+}
+
+pub fn main() {
+    let mut x = [0; 4];
+    let ptr = std::ptr::addr_of_mut!(x);
+    self_copy(ptr, ptr);
+}
diff --git a/src/tools/miri/tests/fail/overlapping_assignment.stderr b/src/tools/miri/tests/fail/overlapping_assignment.stderr
new file mode 100644
index 00000000000..42a000dfcc6
--- /dev/null
+++ b/src/tools/miri/tests/fail/overlapping_assignment.stderr
@@ -0,0 +1,20 @@
+error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges
+  --> $DIR/overlapping_assignment.rs:LL:CC
+   |
+LL |             *ptr1 = *ptr2;
+   |             ^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `self_copy` at $DIR/overlapping_assignment.rs:LL:CC
+note: inside `main`
+  --> $DIR/overlapping_assignment.rs:LL:CC
+   |
+LL |     self_copy(ptr, ptr);
+   |     ^^^^^^^^^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr
new file mode 100644
index 00000000000..e6ac9bc2277
--- /dev/null
+++ b/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr
@@ -0,0 +1,30 @@
+error[E0046]: not all trait items implemented, missing: `foo`
+  --> $DIR/missing-feature-flag.rs:14:1
+   |
+LL |     async fn foo(_: T) -> &'static str;
+   |     ----------------------------------- `foo` from trait
+...
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+  --> $DIR/missing-feature-flag.rs:18:5
+   |
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ------------------------------- parent `impl` is here
+...
+LL |     async fn foo(_: i32) -> &'static str {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+   |
+   = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error[E0308]: mismatched types
+  --> $DIR/missing-feature-flag.rs:18:42
+   |
+LL |     async fn foo(_: i32) -> &'static str {}
+   |                                          ^^ expected `&str`, found `()`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0046, E0308, E0520.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr
new file mode 100644
index 00000000000..e6ac9bc2277
--- /dev/null
+++ b/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr
@@ -0,0 +1,30 @@
+error[E0046]: not all trait items implemented, missing: `foo`
+  --> $DIR/missing-feature-flag.rs:14:1
+   |
+LL |     async fn foo(_: T) -> &'static str;
+   |     ----------------------------------- `foo` from trait
+...
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
+
+error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
+  --> $DIR/missing-feature-flag.rs:18:5
+   |
+LL | impl<T> MyTrait<T> for MyStruct {}
+   | ------------------------------- parent `impl` is here
+...
+LL |     async fn foo(_: i32) -> &'static str {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo`
+   |
+   = note: to specialize, `foo` in the parent `impl` must be marked `default`
+
+error[E0308]: mismatched types
+  --> $DIR/missing-feature-flag.rs:18:42
+   |
+LL |     async fn foo(_: i32) -> &'static str {}
+   |                                          ^^ expected `&str`, found `()`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0046, E0308, E0520.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.rs b/tests/ui/async-await/in-trait/missing-feature-flag.rs
new file mode 100644
index 00000000000..6481f4a7059
--- /dev/null
+++ b/tests/ui/async-await/in-trait/missing-feature-flag.rs
@@ -0,0 +1,23 @@
+// edition:2018
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
+#![feature(async_fn_in_trait)]
+#![feature(min_specialization)]
+
+struct MyStruct;
+
+trait MyTrait<T> {
+    async fn foo(_: T) -> &'static str;
+}
+
+impl<T> MyTrait<T> for MyStruct {}
+//~^ ERROR: not all trait items implemented, missing: `foo` [E0046]
+
+impl MyTrait<i32> for MyStruct {
+    async fn foo(_: i32) -> &'static str {}
+    //~^ ERROR: `foo` specializes an item from a parent `impl`, but that item is not marked `default` [E0520]
+    //~| ERROR: mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs
new file mode 100644
index 00000000000..1b16a492a7a
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.rs
@@ -0,0 +1,13 @@
+#![feature(return_type_notation)]
+//~^ WARN the feature `return_type_notation` is incomplete
+
+// Shouldn't ICE when we have a (bad) RTN in an impl header
+
+trait Super1<'a> {
+    fn bar<'b>() -> bool;
+}
+
+impl Super1<'_, bar(): Send> for () {}
+//~^ ERROR associated type bindings are not allowed here
+
+fn main() {}
diff --git a/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr
new file mode 100644
index 00000000000..52d8168c9d8
--- /dev/null
+++ b/tests/ui/async-await/return-type-notation/rtn-in-impl-signature.stderr
@@ -0,0 +1,18 @@
+warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/rtn-in-impl-signature.rs:1:12
+   |
+LL | #![feature(return_type_notation)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/rtn-in-impl-signature.rs:10:17
+   |
+LL | impl Super1<'_, bar(): Send> for () {}
+   |                 ^^^^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr
new file mode 100644
index 00000000000..ff30103b771
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
+  --> $DIR/return-dont-satisfy-bounds.rs:13:34
+   |
+LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+   |                                  ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
+   |
+   = help: the trait `Foo<char>` is implemented for `Bar`
+note: required by a bound in `Foo::foo::{opaque#0}`
+  --> $DIR/return-dont-satisfy-bounds.rs:7:30
+   |
+LL |     fn foo<F2>(self) -> impl Foo<T>;
+   |                              ^^^^^^ required by this bound in `Foo::foo::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr
new file mode 100644
index 00000000000..7c7f7feaa55
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied
+  --> $DIR/return-dont-satisfy-bounds.rs:13:34
+   |
+LL |     fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+   |                                  ^^^^^^^^^^^^ the trait `Foo<char>` is not implemented for `impl Foo<u8>`
+   |
+   = help: the trait `Foo<char>` is implemented for `Bar`
+note: required by a bound in `Foo::{opaque#0}`
+  --> $DIR/return-dont-satisfy-bounds.rs:7:30
+   |
+LL |     fn foo<F2>(self) -> impl Foo<T>;
+   |                              ^^^^^^ required by this bound in `Foo::{opaque#0}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
new file mode 100644
index 00000000000..65528f212e2
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs
@@ -0,0 +1,19 @@
+// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty
+// revisions: current next
+
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Foo<T> {
+    fn foo<F2>(self) -> impl Foo<T>;
+}
+
+struct Bar;
+
+impl Foo<char> for Bar {
+    fn foo<F2: Foo<u8>>(self) -> impl Foo<u8> {
+        //~^ ERROR: the trait bound `impl Foo<u8>: Foo<char>` is not satisfied [E0277]
+        self
+    }
+}
+
+fn main() {}
diff --git a/triagebot.toml b/triagebot.toml
index 4bab8facc85..e6c593204ca 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -20,6 +20,7 @@ allow-unauthenticated = [
     "regression-*",
     "perf-*",
     "AsyncAwait-OnDeck",
+    "needs-triage",
 ]
 
 [glacier]
@@ -254,6 +255,9 @@ trigger_files = [
 [autolabel."S-waiting-on-review"]
 new_pr = true
 
+[autolabel."needs-triage"]
+new_issue = true
+
 [autolabel."WG-trait-system-refactor"]
 trigger_files = [
     "compiler/rustc_trait_selection/src/solve",