about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs33
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs7
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs102
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs20
-rw-r--r--compiler/rustc_lint/src/builtin.rs5
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs23
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs23
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed14
-rw-r--r--tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs14
-rw-r--r--tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr16
-rw-r--r--tests/ui/consts/effect_param.rs11
-rw-r--r--tests/ui/consts/effect_param.stderr19
-rw-r--r--tests/ui/impl-trait/equality-in-canonical-query.clone.stderr29
-rw-r--r--tests/ui/impl-trait/equality-in-canonical-query.rs23
-rw-r--r--tests/ui/lint/missing-copy-implementations-non-exhaustive.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr13
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs18
21 files changed, 272 insertions, 140 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index ee554370305..fb0e5811c26 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -328,26 +328,19 @@ fn check_opaque_type_well_formed<'tcx>(
 
     // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
     // the bounds that the function supplies.
-    let mut obligations = vec![];
-    infcx
-        .insert_hidden_type(
-            OpaqueTypeKey { def_id, args: identity_args },
-            &ObligationCause::misc(definition_span, def_id),
-            param_env,
-            definition_ty,
-            true,
-            &mut obligations,
-        )
-        .unwrap();
-    infcx.add_item_bounds_for_hidden_type(
-        def_id.to_def_id(),
-        identity_args,
-        ObligationCause::misc(definition_span, def_id),
-        param_env,
-        definition_ty,
-        &mut obligations,
-    );
-    ocx.register_obligations(obligations);
+    let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), identity_args);
+    ocx.eq(&ObligationCause::misc(definition_span, def_id), param_env, opaque_ty, definition_ty)
+        .map_err(|err| {
+            infcx
+                .err_ctxt()
+                .report_mismatched_types(
+                    &ObligationCause::misc(definition_span, def_id),
+                    opaque_ty,
+                    definition_ty,
+                    err,
+                )
+                .emit()
+        })?;
 
     // Require the hidden type to be well-formed with only the generics of the opaque type.
     // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index af1a4e5d99e..b6688e0ce29 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -46,10 +46,11 @@ impl<'tcx> Bounds<'tcx> {
     ) {
         self.push_trait_bound_inner(tcx, trait_ref, span, polarity);
 
-        // if we have a host param, we push an unconst trait bound in addition
-        // to the const one.
-        // FIXME(effects) we should find a better way than name matching
-        if tcx.features().effects && trait_ref.skip_binder().args.host_effect_param().is_some() {
+        // push a non-const (`host = true`) version of the bound if it is `~const`.
+        if tcx.features().effects
+            && let Some(host_effect_idx) = tcx.generics_of(trait_ref.def_id()).host_effect_index
+            && trait_ref.skip_binder().args.const_at(host_effect_idx) != tcx.consts.true_
+        {
             let generics = tcx.generics_of(trait_ref.def_id());
             let Some(host_index) = generics.host_effect_index else { return };
             let trait_ref = trait_ref.map_bound(|mut trait_ref| {
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 1c23ccd1579..78d30f3aa12 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -786,8 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 tcx.consts.false_
             }
             Some(hir::ConstContext::ConstFn) => {
-                let args = ty::GenericArgs::identity_for_item(tcx, context);
-                args.host_effect_param().expect("ConstContext::Maybe must have host effect param")
+                let host_idx = tcx
+                    .generics_of(context)
+                    .host_effect_index
+                    .expect("ConstContext::Maybe must have host effect param");
+                ty::GenericArgs::identity_for_item(tcx, context).const_at(host_idx)
             }
             None => tcx.consts.true_,
         };
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 24767b0bda6..8ecf63ec665 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -341,39 +341,48 @@ impl<T> Trait<T> for X {
         let tcx = self.tcx;
         let assoc = tcx.associated_item(proj_ty.def_id);
         let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx);
-        if let Some(item) = tcx.hir().get_if_local(body_owner_def_id) {
-            if let Some(hir_generics) = item.generics() {
-                // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
-                // This will also work for `impl Trait`.
-                let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
-                    let generics = tcx.generics_of(body_owner_def_id);
-                    generics.type_param(param_ty, tcx).def_id
-                } else {
-                    return false;
-                };
-                let Some(def_id) = def_id.as_local() else {
-                    return false;
-                };
-
-                // First look in the `where` clause, as this might be
-                // `fn foo<T>(x: T) where T: Trait`.
-                for pred in hir_generics.bounds_for_param(def_id) {
-                    if self.constrain_generic_bound_associated_type_structured_suggestion(
-                        diag,
-                        &trait_ref,
-                        pred.bounds,
-                        assoc,
-                        assoc_args,
-                        ty,
-                        &msg,
-                        false,
-                    ) {
-                        return true;
-                    }
-                }
+        let Some(item) = tcx.hir().get_if_local(body_owner_def_id) else {
+            return false;
+        };
+        let Some(hir_generics) = item.generics() else {
+            return false;
+        };
+        // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
+        // This will also work for `impl Trait`.
+        let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
+            let generics = tcx.generics_of(body_owner_def_id);
+            generics.type_param(param_ty, tcx).def_id
+        } else {
+            return false;
+        };
+        let Some(def_id) = def_id.as_local() else {
+            return false;
+        };
+
+        // First look in the `where` clause, as this might be
+        // `fn foo<T>(x: T) where T: Trait`.
+        for pred in hir_generics.bounds_for_param(def_id) {
+            if self.constrain_generic_bound_associated_type_structured_suggestion(
+                diag,
+                &trait_ref,
+                pred.bounds,
+                assoc,
+                assoc_args,
+                ty,
+                &msg,
+                false,
+            ) {
+                return true;
             }
         }
-        false
+        // If associated item, look to constrain the params of the trait/impl.
+        let hir_id = match item {
+            hir::Node::ImplItem(item) => item.hir_id(),
+            hir::Node::TraitItem(item) => item.hir_id(),
+            _ => return false,
+        };
+        let parent = tcx.hir().get_parent_item(hir_id).def_id;
+        self.suggest_constraint(diag, msg, parent.into(), proj_ty, ty)
     }
 
     /// An associated type was expected and a different type was found.
@@ -426,21 +435,26 @@ impl<T> Trait<T> for X {
         let impl_comparison =
             matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
         let assoc = tcx.associated_item(proj_ty.def_id);
-        if !callable_scope || impl_comparison {
+        if impl_comparison {
             // We do not want to suggest calling functions when the reason of the
-            // type error is a comparison of an `impl` with its `trait` or when the
-            // scope is outside of a `Body`.
+            // type error is a comparison of an `impl` with its `trait`.
         } else {
-            // If we find a suitable associated function that returns the expected type, we don't
-            // want the more general suggestion later in this method about "consider constraining
-            // the associated type or calling a method that returns the associated type".
-            let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type(
-                diag,
-                assoc.container_id(tcx),
-                current_method_ident,
-                proj_ty.def_id,
-                values.expected,
-            );
+            let point_at_assoc_fn = if callable_scope
+                && self.point_at_methods_that_satisfy_associated_type(
+                    diag,
+                    assoc.container_id(tcx),
+                    current_method_ident,
+                    proj_ty.def_id,
+                    values.expected,
+                ) {
+                // If we find a suitable associated function that returns the expected type, we
+                // don't want the more general suggestion later in this method about "consider
+                // constraining the associated type or calling a method that returns the associated
+                // type".
+                true
+            } else {
+                false
+            };
             // Possibly suggest constraining the associated type to conform to the
             // found type.
             if self.suggest_constraint(diag, &msg, body_owner_def_id, proj_ty, values.found)
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 09df93fcc2f..1c3a5c36076 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -145,25 +145,7 @@ impl<'tcx> InferCtxt<'tcx> {
                             return None;
                         }
                     }
-                    DefiningAnchor::Bubble => {
-                        if let ty::Alias(ty::Opaque, _) = b.kind() {
-                            // In bubble mode we don't know which of the two opaque types is supposed to have the other
-                            // as a hidden type (both, none or either one of them could be in its defining scope).
-                            let predicate = ty::PredicateKind::AliasRelate(
-                                a.into(),
-                                b.into(),
-                                ty::AliasRelationDirection::Equate,
-                            );
-                            let obligation = traits::Obligation::new(
-                                self.tcx,
-                                cause.clone(),
-                                param_env,
-                                predicate,
-                            );
-                            let obligations = vec![obligation];
-                            return Some(Ok(InferOk { value: (), obligations }));
-                        }
-                    }
+                    DefiningAnchor::Bubble => {}
                     DefiningAnchor::Error => return None,
                 };
                 if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 3e44e168786..f6c7f4071dc 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -677,6 +677,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
         if type_implements_negative_copy_modulo_regions(cx.tcx, ty, param_env) {
             return;
         }
+        if def.is_variant_list_non_exhaustive()
+            || def.variants().iter().any(|variant| variant.is_field_list_non_exhaustive())
+        {
+            return;
+        }
 
         // We shouldn't recommend implementing `Copy` on stateful things,
         // such as iterators.
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 72390e4bbb0..a861af47859 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -11,7 +11,6 @@ use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
 use rustc_hir::def_id::DefId;
 use rustc_macros::HashStable;
 use rustc_serialize::{self, Decodable, Encodable};
-use rustc_span::sym;
 use rustc_type_ir::WithCachedTypeInfo;
 use smallvec::SmallVec;
 
@@ -452,10 +451,6 @@ impl<'tcx> GenericArgs<'tcx> {
         tcx.mk_args_from_iter(self.iter().take(generics.count()))
     }
 
-    pub fn host_effect_param(&'tcx self) -> Option<ty::Const<'tcx>> {
-        self.consts().rfind(|x| matches!(x.kind(), ty::ConstKind::Param(p) if p.name == sym::host))
-    }
-
     pub fn print_as_list(&self) -> String {
         let v = self.iter().map(|arg| arg.to_string()).collect::<Vec<_>>();
         format!("[{}]", v.join(", "))
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index da357dac415..55b5604b16b 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -6,7 +6,6 @@ use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::traits::ProjectionCacheKey;
 use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
 use rustc_middle::mir::interpret::ErrorHandled;
-use rustc_middle::traits::DefiningAnchor;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::GenericArgsRef;
@@ -626,27 +625,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     }
                 }
                 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
-                ty::PredicateKind::AliasRelate(..)
-                    if matches!(self.selcx.infcx.defining_use_anchor, DefiningAnchor::Bubble) =>
-                {
-                    ProcessResult::Unchanged
+                ty::PredicateKind::AliasRelate(..) => {
+                    bug!("AliasRelate is only used for new solver")
                 }
-                ty::PredicateKind::AliasRelate(a, b, relate) => match relate {
-                    ty::AliasRelationDirection::Equate => match self
-                        .selcx
-                        .infcx
-                        .at(&obligation.cause, obligation.param_env)
-                        .eq(DefineOpaqueTypes::Yes, a, b)
-                    {
-                        Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
-                        Err(_) => ProcessResult::Error(FulfillmentErrorCode::CodeSelectionError(
-                            SelectionError::Unimplemented,
-                        )),
-                    },
-                    ty::AliasRelationDirection::Subtype => {
-                        bug!("AliasRelate with subtyping is only used for new solver")
-                    }
-                },
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
                     match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
                         DefineOpaqueTypes::No,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 97366a93e31..940ceca50d2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -38,7 +38,6 @@ use rustc_infer::traits::TraitObligation;
 use rustc_middle::dep_graph::dep_kinds;
 use rustc_middle::dep_graph::DepNodeIndex;
 use rustc_middle::mir::interpret::ErrorHandled;
-use rustc_middle::traits::DefiningAnchor;
 use rustc_middle::ty::_match::MatchAgainstFreshVars;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::fold::BottomUpFolder;
@@ -1005,27 +1004,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         }
                     }
                 }
-                ty::PredicateKind::AliasRelate(..)
-                    if matches!(self.infcx.defining_use_anchor, DefiningAnchor::Bubble) =>
-                {
-                    Ok(EvaluatedToAmbig)
+                ty::PredicateKind::AliasRelate(..) => {
+                    bug!("AliasRelate is only used for new solver")
                 }
-                ty::PredicateKind::AliasRelate(a, b, relate) => match relate {
-                    ty::AliasRelationDirection::Equate => match self
-                        .infcx
-                        .at(&obligation.cause, obligation.param_env)
-                        .eq(DefineOpaqueTypes::Yes, a, b)
-                    {
-                        Ok(inf_ok) => self.evaluate_predicates_recursively(
-                            previous_stack,
-                            inf_ok.into_obligations(),
-                        ),
-                        Err(_) => Ok(EvaluatedToErr),
-                    },
-                    ty::AliasRelationDirection::Subtype => {
-                        bug!("AliasRelate subtyping is only used for new solver")
-                    }
-                },
                 ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
                     match self.infcx.at(&obligation.cause, obligation.param_env).eq(
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 963545a2eb2..03243e31348 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -219,7 +219,6 @@
 #![feature(doc_cfg)]
 #![feature(doc_cfg_hide)]
 #![feature(doc_notable_trait)]
-#![feature(effects)]
 #![feature(exhaustive_patterns)]
 #![feature(extern_types)]
 #![feature(fundamental)]
diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed
new file mode 100644
index 00000000000..b9f26a40219
--- /dev/null
+++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+trait O {
+    type M;
+}
+trait U<A: O> {
+    const N: A::M;
+}
+impl<D> O for D {
+    type M = u8;
+}
+impl<C: O<M = u8>> U<C> for u16 {
+    const N: C::M = 4u8; //~ ERROR mismatched types
+}
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs
new file mode 100644
index 00000000000..abff6af73e2
--- /dev/null
+++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+trait O {
+    type M;
+}
+trait U<A: O> {
+    const N: A::M;
+}
+impl<D> O for D {
+    type M = u8;
+}
+impl<C: O> U<C> for u16 {
+    const N: C::M = 4u8; //~ ERROR mismatched types
+}
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr
new file mode 100644
index 00000000000..b104f38ce90
--- /dev/null
+++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/suggest-contraining-assoc-type-because-of-assoc-const.rs:12:21
+   |
+LL |     const N: C::M = 4u8;
+   |                     ^^^ expected associated type, found `u8`
+   |
+   = note: expected associated type `<C as O>::M`
+                         found type `u8`
+help: consider constraining the associated type `<C as O>::M` to `u8`
+   |
+LL | impl<C: O<M = u8>> U<C> for u16 {
+   |          ++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/effect_param.rs b/tests/ui/consts/effect_param.rs
new file mode 100644
index 00000000000..f11ec739fce
--- /dev/null
+++ b/tests/ui/consts/effect_param.rs
@@ -0,0 +1,11 @@
+//! Ensure we don't allow accessing const effect parameters from stable Rust.
+
+fn main() {
+    i8::checked_sub::<true>(42, 43);
+    //~^ ERROR: method takes 0 generic arguments but 1 generic argument was supplied
+}
+
+const FOO: () = {
+    i8::checked_sub::<false>(42, 43);
+    //~^ ERROR: method takes 0 generic arguments but 1 generic argument was supplied
+};
diff --git a/tests/ui/consts/effect_param.stderr b/tests/ui/consts/effect_param.stderr
new file mode 100644
index 00000000000..f8c4bfc02e5
--- /dev/null
+++ b/tests/ui/consts/effect_param.stderr
@@ -0,0 +1,19 @@
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/effect_param.rs:9:9
+   |
+LL |     i8::checked_sub::<false>(42, 43);
+   |         ^^^^^^^^^^^--------- help: remove these generics
+   |         |
+   |         expected 0 generic arguments
+
+error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/effect_param.rs:4:9
+   |
+LL |     i8::checked_sub::<true>(42, 43);
+   |         ^^^^^^^^^^^-------- help: remove these generics
+   |         |
+   |         expected 0 generic arguments
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
new file mode 100644
index 00000000000..83791f0d3af
--- /dev/null
+++ b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
@@ -0,0 +1,29 @@
+error: internal compiler error: no errors encountered even though `delay_span_bug` issued
+
+error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }) } }}
+   |
+   = 
+           
+
+error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }))), bound_vars: [] } } }
+  --> $DIR/equality-in-canonical-query.rs:19:5
+   |
+LL |     same_output(foo, rpit);
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+
+  --> $DIR/equality-in-canonical-query.rs:19:5
+   |
+LL |     same_output(foo, rpit);
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+
+
+
+
+
+
+query stack during panic:
+end of query stack
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/impl-trait/equality-in-canonical-query.rs b/tests/ui/impl-trait/equality-in-canonical-query.rs
new file mode 100644
index 00000000000..672b1eeeab6
--- /dev/null
+++ b/tests/ui/impl-trait/equality-in-canonical-query.rs
@@ -0,0 +1,23 @@
+// issue: #116877
+// revisions: sized clone
+//[sized] check-pass
+
+//[clone] known-bug: #108498
+//[clone] failure-status: 101
+//[clone] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
+//[clone] normalize-stderr-test: "(?m)note: .*$" -> ""
+//[clone] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
+//[clone] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
+
+#[cfg(sized)] fn rpit() -> impl Sized {}
+#[cfg(clone)] fn rpit() -> impl Clone {}
+
+fn same_output<Out>(_: impl Fn() -> Out, _: impl Fn() -> Out) {}
+
+pub fn foo() -> impl Sized {
+    same_output(rpit, foo);
+    same_output(foo, rpit);
+    rpit()
+}
+
+fn main () {}
diff --git a/tests/ui/lint/missing-copy-implementations-non-exhaustive.rs b/tests/ui/lint/missing-copy-implementations-non-exhaustive.rs
new file mode 100644
index 00000000000..2d5e90720ef
--- /dev/null
+++ b/tests/ui/lint/missing-copy-implementations-non-exhaustive.rs
@@ -0,0 +1,25 @@
+// Test for issue #116766.
+// Ensure that we don't suggest impl'ing `Copy` for a type if it or at least one
+// of it's variants are marked as `non_exhaustive`.
+
+// check-pass
+
+#![deny(missing_copy_implementations)]
+
+#[non_exhaustive]
+pub enum MyEnum {
+    A,
+}
+
+#[non_exhaustive]
+pub struct MyStruct {
+    foo: usize,
+}
+
+pub enum MyEnum2 {
+    #[non_exhaustive]
+    A,
+    B,
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
index 4b09a9e743b..844103d77a8 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
@@ -1,11 +1,17 @@
 error: internal compiler error: no errors encountered even though `delay_span_bug` issued
 
-error: internal compiler error: ambiguity performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(get_rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }))), bound_vars: [] } } }
+error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }) } }}
+   |
+   = 
+           
+
+error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(get_rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }))), bound_vars: [] } } }
   --> $DIR/rpit_tait_equality_in_canonical_query.rs:28:5
    |
 LL |     query(get_rpit);
    |     ^^^^^^^^^^^^^^^
    |
+
   --> $DIR/rpit_tait_equality_in_canonical_query.rs:28:5
    |
 LL |     query(get_rpit);
@@ -14,7 +20,10 @@ LL |     query(get_rpit);
 
 
 
+
+
+
 query stack during panic:
 end of query stack
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
index 8dccd2ed46f..0f0002f7797 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs
@@ -12,7 +12,7 @@
 //[current] known-bug: #108498
 //[current] failure-status: 101
 //[current] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
-//[current] normalize-stderr-test: "(?m)^note: .*\n" -> ""
+//[current] normalize-stderr-test: "(?m)note: .*$" -> ""
 //[current] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
 //[current] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
 
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs
new file mode 100644
index 00000000000..9d7e647dd94
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs
@@ -0,0 +1,18 @@
+// The canonical query `Projection(<get_rpit as FnOnce>::Output = Opaque)`
+// is the *only* site that defines `Opaque` in MIR typeck.
+//
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type Opaque = impl Sized;
+
+fn get_rpit() -> impl Sized {}
+
+fn query(_: impl FnOnce() -> Opaque) {}
+
+fn test(_: Opaque) {
+    query(get_rpit);
+}
+
+fn main() {}