about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch13
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs7
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/bounds.rs44
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs29
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs10
-rw-r--r--compiler/rustc_interface/src/interface.rs4
-rw-r--r--compiler/rustc_lint/src/if_let_rescope.rs32
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs105
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs16
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs18
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs10
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs4
-rw-r--r--compiler/rustc_mir_transform/src/single_use_consts.rs5
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs8
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs6
-rw-r--r--compiler/rustc_type_ir/src/elaborate.rs65
-rw-r--r--compiler/rustc_type_ir/src/lang_items.rs2
23 files changed, 246 insertions, 166 deletions
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index de198115fa0..cf1d5c68ead 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -43,7 +43,7 @@ fn parse_cfg<'a>(cx: &ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a,
         return Err(cx.dcx().create_err(errors::RequiresCfgPattern { span }));
     }
 
-    let cfg = p.parse_meta_item(AllowLeadingUnsafe::Yes)?;
+    let cfg = p.parse_meta_item(AllowLeadingUnsafe::No)?;
 
     let _ = p.eat(&token::Comma);
 
diff --git a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch
index a3f370af916..646928893e9 100644
--- a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch
@@ -82,19 +82,6 @@ index d9de37e..8293fce 100644
  #[cfg(target_has_atomic_load_store = "ptr")]
  macro_rules! atomic_int_ptr_sized {
      ( $($target_pointer_width:literal $align:literal)* ) => { $(
-diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
-index 58b9ba4..91bbd0a 100644
---- a/library/core/src/cell.rs
-+++ b/library/core/src/cell.rs
-@@ -2246,8 +2246,6 @@ unsafe_cell_primitive_into_inner! {
-     u32 "32"
-     i64 "64"
-     u64 "64"
--    i128 "128"
--    u128 "128"
-     isize "ptr"
-     usize "ptr"
- }
 --
 2.26.2.7.g19db9cfb68
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index a2a5499597c..201cfbb1918 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -536,6 +536,11 @@ pub(crate) fn global_llvm_features(
     // -Ctarget-cpu=native
     match sess.opts.cg.target_cpu {
         Some(ref s) if s == "native" => {
+            // We have already figured out the actual CPU name with `LLVMRustGetHostCPUName` and set
+            // that for LLVM, so the features implied by that CPU name will be available everywhere.
+            // However, that is not sufficient: e.g. `skylake` alone is not sufficient to tell if
+            // some of the instructions are available or not. So we have to also explicitly ask for
+            // the exact set of features available on the host, and enable all of them.
             let features_string = unsafe {
                 let ptr = llvm::LLVMGetHostCPUFeatures();
                 let features_string = if !ptr.is_null() {
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index e1fd8bea1f3..4c34ffc5d4e 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -396,11 +396,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
                 for i in 0..dest_len {
                     let place = self.project_index(&dest, i)?;
-                    let value = if i == index {
-                        elem.clone()
-                    } else {
-                        self.project_index(&input, i)?.into()
-                    };
+                    let value =
+                        if i == index { elem.clone() } else { self.project_index(&input, i)? };
                     self.copy_op(&value, &place)?;
                 }
             }
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index a7b251ab252..0dc35618ff8 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -627,8 +627,7 @@ impl server::TokenStream for Rustc<'_, '_> {
         base: Option<Self::TokenStream>,
         trees: Vec<TokenTree<Self::TokenStream, Self::Span, Self::Symbol>>,
     ) -> Self::TokenStream {
-        let mut stream =
-            if let Some(base) = base { base } else { tokenstream::TokenStream::default() };
+        let mut stream = base.unwrap_or_default();
         for tree in trees {
             for tt in (tree, &mut *self).to_internal() {
                 stream.push_tree(tt);
@@ -642,8 +641,7 @@ impl server::TokenStream for Rustc<'_, '_> {
         base: Option<Self::TokenStream>,
         streams: Vec<Self::TokenStream>,
     ) -> Self::TokenStream {
-        let mut stream =
-            if let Some(base) = base { base } else { tokenstream::TokenStream::default() };
+        let mut stream = base.unwrap_or_default();
         for s in streams {
             stream.push_stream(s);
         }
diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs
index caf9960741d..8947e7a2216 100644
--- a/compiler/rustc_hir_analysis/src/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/bounds.rs
@@ -91,12 +91,46 @@ impl<'tcx> Bounds<'tcx> {
                 }
                 tcx.consts.true_
             }
+            (DefKind::Trait, ty::BoundConstness::ConstIfConst) => {
+                // we are in a trait, where `bound_trait_ref` could be:
+                // (1) a super trait `trait Foo: ~const Bar`.
+                //     - This generates `<Self as Foo>::Effects: TyCompat<<Self as Bar>::Effects>`
+                //
+                // (2) a where clause `where for<..> Something: ~const Bar`.
+                //     - This generates `for<..> <Self as Foo>::Effects: TyCompat<<Something as Bar>::Effects>`
+                let Some(own_fx) = tcx.associated_type_for_effects(defining_def_id) else {
+                    tcx.dcx().span_delayed_bug(span, "should not have allowed `~const` on a trait that doesn't have `#[const_trait]`");
+                    return;
+                };
+                let own_fx_ty = Ty::new_projection(
+                    tcx,
+                    own_fx,
+                    ty::GenericArgs::identity_for_item(tcx, own_fx),
+                );
+                let Some(their_fx) = tcx.associated_type_for_effects(bound_trait_ref.def_id())
+                else {
+                    tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc");
+                    return;
+                };
+                let their_fx_ty =
+                    Ty::new_projection(tcx, their_fx, bound_trait_ref.skip_binder().args);
+                let compat = tcx.require_lang_item(LangItem::EffectsTyCompat, Some(span));
+                let clause = bound_trait_ref
+                    .map_bound(|_| {
+                        let trait_ref = ty::TraitRef::new(tcx, compat, [own_fx_ty, their_fx_ty]);
+                        ty::ClauseKind::Trait(ty::TraitPredicate {
+                            trait_ref,
+                            polarity: ty::PredicatePolarity::Positive,
+                        })
+                    })
+                    .upcast(tcx);
+
+                self.clauses.push((clause, span));
+                return;
+            }
 
-            (
-                DefKind::Trait | DefKind::Impl { of_trait: true },
-                ty::BoundConstness::ConstIfConst,
-            ) => {
-                // this is either a where clause on an impl/trait header or on a trait.
+            (DefKind::Impl { of_trait: true }, ty::BoundConstness::ConstIfConst) => {
+                // this is a where clause on an impl header.
                 // push `<T as Tr>::Effects` into the set for the `Min` bound.
                 let Some(assoc) = tcx.associated_type_for_effects(bound_trait_ref.def_id()) else {
                     tcx.dcx().span_delayed_bug(span, "`~const` on trait without Effects assoc");
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index a71e14ce463..70b0b3f5788 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -961,13 +961,20 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                         hir_ty.span,
                         "using raw pointers as const generic parameters is forbidden",
                     ),
-                    _ => tcx.dcx().struct_span_err(
-                        hir_ty.span,
-                        format!("`{}` is forbidden as the type of a const generic parameter", ty),
-                    ),
+                    _ => {
+                        // Avoid showing "{type error}" to users. See #118179.
+                        ty.error_reported()?;
+
+                        tcx.dcx().struct_span_err(
+                            hir_ty.span,
+                            format!(
+                                "`{ty}` is forbidden as the type of a const generic parameter",
+                            ),
+                        )
+                    }
                 };
 
-                diag.note("the only supported types are integers, `bool` and `char`");
+                diag.note("the only supported types are integers, `bool`, and `char`");
 
                 let cause = ObligationCause::misc(hir_ty.span, param.def_id);
                 let adt_const_params_feature_string =
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 7557219aaa6..f44b4728ad5 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -360,33 +360,10 @@ pub(super) fn explicit_item_bounds_with_filter(
         None => {}
     }
 
-    if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) {
-        let mut predicates = Vec::new();
-
-        let parent = tcx.local_parent(def_id);
-
-        let preds = tcx.explicit_predicates_of(parent);
-
-        if let ty::AssocItemContainer::TraitContainer = tcx.associated_item(def_id).container {
-            // for traits, emit `type Effects: TyCompat<<(T1::Effects, ..) as Min>::Output>`
-            let tup = Ty::new(tcx, ty::Tuple(preds.effects_min_tys));
-            // FIXME(effects) span
-            let span = tcx.def_span(def_id);
-            let assoc = tcx.require_lang_item(hir::LangItem::EffectsIntersectionOutput, Some(span));
-            let proj = Ty::new_projection(tcx, assoc, [tup]);
-            let self_proj = Ty::new_projection(
-                tcx,
-                def_id.to_def_id(),
-                ty::GenericArgs::identity_for_item(tcx, def_id),
-            );
-            let trait_ = tcx.require_lang_item(hir::LangItem::EffectsTyCompat, Some(span));
-            let trait_ref = ty::TraitRef::new(tcx, trait_, [self_proj, proj]);
-            predicates.push((ty::Binder::dummy(trait_ref).upcast(tcx), span));
-        }
-        return ty::EarlyBinder::bind(tcx.arena.alloc_from_iter(predicates));
-    }
-
     let bounds = match tcx.hir_node_by_def_id(def_id) {
+        _ if tcx.is_effects_desugared_assoc_ty(def_id.to_def_id()) => {
+            associated_type_bounds(tcx, def_id, &[], tcx.def_span(def_id), filter)
+        }
         hir::Node::TraitItem(hir::TraitItem {
             kind: hir::TraitItemKind::Type(bounds, _),
             span,
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index c5843b883a1..63cf483aa22 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -1369,13 +1369,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         for (&var_hir_id, _) in upvars.iter() {
             let mut diagnostics_info = Vec::new();
 
-            let auto_trait_diagnostic = if let Some(diagnostics_info) =
-                self.compute_2229_migrations_for_trait(min_captures, var_hir_id, closure_clause)
-            {
-                diagnostics_info
-            } else {
-                FxIndexMap::default()
-            };
+            let auto_trait_diagnostic = self
+                .compute_2229_migrations_for_trait(min_captures, var_hir_id, closure_clause)
+                .unwrap_or_default();
 
             let drop_reorder_diagnostic = if let Some(diagnostics_info) = self
                 .compute_2229_migrations_for_drop(
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index c2241773c8c..bd38b3c109a 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -174,7 +174,7 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch
             }
         };
 
-        let meta_item = match parser.parse_meta_item(AllowLeadingUnsafe::Yes) {
+        let meta_item = match parser.parse_meta_item(AllowLeadingUnsafe::No) {
             Ok(meta_item) if parser.token == token::Eof => meta_item,
             Ok(..) => expected_error(),
             Err(err) => {
@@ -427,7 +427,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
                 Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")),
             };
 
-            let mut locale_resources = Vec::from(config.locale_resources);
+            let mut locale_resources = config.locale_resources;
             locale_resources.push(codegen_backend.locale_resource());
 
             let mut sess = rustc_session::build_session(
diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs
index 229d0c36421..cdd0e80c458 100644
--- a/compiler/rustc_lint/src/if_let_rescope.rs
+++ b/compiler/rustc_lint/src/if_let_rescope.rs
@@ -122,7 +122,11 @@ impl IfLetRescope {
         }
         let tcx = cx.tcx;
         let source_map = tcx.sess.source_map();
-        let expr_end = expr.span.shrink_to_hi();
+        let expr_end = match expr.kind {
+            hir::ExprKind::If(_cond, conseq, None) => conseq.span.shrink_to_hi(),
+            hir::ExprKind::If(_cond, _conseq, Some(alt)) => alt.span.shrink_to_hi(),
+            _ => return,
+        };
         let mut add_bracket_to_match_head = match_head_needs_bracket(tcx, expr);
         let mut significant_droppers = vec![];
         let mut lifetime_ends = vec![];
@@ -145,7 +149,10 @@ impl IfLetRescope {
                 recovered: Recovered::No,
             }) = cond.kind
             {
-                let if_let_pat = expr.span.shrink_to_lo().between(init.span);
+                // Peel off round braces
+                let if_let_pat = source_map
+                    .span_take_while(expr.span, |&ch| ch == '(' || ch.is_whitespace())
+                    .between(init.span);
                 // The consequent fragment is always a block.
                 let before_conseq = conseq.span.shrink_to_lo();
                 let lifetime_end = source_map.end_point(conseq.span);
@@ -159,6 +166,8 @@ impl IfLetRescope {
                     if ty_ascription.is_some()
                         || !expr.span.can_be_used_for_suggestions()
                         || !pat.span.can_be_used_for_suggestions()
+                        || !if_let_pat.can_be_used_for_suggestions()
+                        || !before_conseq.can_be_used_for_suggestions()
                     {
                         // Our `match` rewrites does not support type ascription,
                         // so we just bail.
@@ -240,6 +249,23 @@ impl<'tcx> LateLintPass<'tcx> for IfLetRescope {
         if let (Level::Allow, _) = cx.tcx.lint_level_at_node(IF_LET_RESCOPE, expr.hir_id) {
             return;
         }
+        if let hir::ExprKind::Loop(block, _label, hir::LoopSource::While, _span) = expr.kind
+            && let Some(value) = block.expr
+            && let hir::ExprKind::If(cond, _conseq, _alt) = value.kind
+            && let hir::ExprKind::Let(..) = cond.kind
+        {
+            // Recall that `while let` is lowered into this:
+            // ```
+            // loop {
+            //     if let .. { body } else { break; }
+            // }
+            // ```
+            // There is no observable change in drop order on the overall `if let` expression
+            // given that the `{ break; }` block is trivial so the edition change
+            // means nothing substantial to this `while` statement.
+            self.skip.insert(value.hir_id);
+            return;
+        }
         if expr_parent_is_stmt(cx.tcx, expr.hir_id)
             && matches!(expr.kind, hir::ExprKind::If(_cond, _conseq, None))
         {
@@ -304,7 +330,7 @@ impl Subdiagnostic for IfLetRescopeRewrite {
                 .chain(repeat('}').take(closing_brackets.count))
                 .collect(),
         ));
-        let msg = f(diag, crate::fluent_generated::lint_suggestion.into());
+        let msg = f(diag, crate::fluent_generated::lint_suggestion);
         diag.multipart_suggestion_with_style(
             msg,
             suggestions,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 4425c93211a..2157324d5cc 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1622,56 +1622,63 @@ impl<'a> CrateMetadataRef<'a> {
             );
 
             for virtual_dir in virtual_rust_source_base_dir.iter().flatten() {
-                if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
-                    if let rustc_span::FileName::Real(old_name) = name {
-                        if let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
-                            old_name
-                        {
-                            if let Ok(rest) = virtual_name.strip_prefix(virtual_dir) {
-                                let virtual_name = virtual_name.clone();
-
-                                // The std library crates are in
-                                // `$sysroot/lib/rustlib/src/rust/library`, whereas other crates
-                                // may be in `$sysroot/lib/rustlib/src/rust/` directly. So we
-                                // detect crates from the std libs and handle them specially.
-                                const STD_LIBS: &[&str] = &[
-                                    "core",
-                                    "alloc",
-                                    "std",
-                                    "test",
-                                    "term",
-                                    "unwind",
-                                    "proc_macro",
-                                    "panic_abort",
-                                    "panic_unwind",
-                                    "profiler_builtins",
-                                    "rtstartup",
-                                    "rustc-std-workspace-core",
-                                    "rustc-std-workspace-alloc",
-                                    "rustc-std-workspace-std",
-                                    "backtrace",
-                                ];
-                                let is_std_lib = STD_LIBS.iter().any(|l| rest.starts_with(l));
-
-                                let new_path = if is_std_lib {
-                                    real_dir.join("library").join(rest)
-                                } else {
-                                    real_dir.join(rest)
-                                };
-
-                                debug!(
-                                    "try_to_translate_virtual_to_real: `{}` -> `{}`",
-                                    virtual_name.display(),
-                                    new_path.display(),
-                                );
-                                let new_name = rustc_span::RealFileName::Remapped {
-                                    local_path: Some(new_path),
-                                    virtual_name,
-                                };
-                                *old_name = new_name;
-                            }
+                if let Some(real_dir) = &sess.opts.real_rust_source_base_dir
+                    && let rustc_span::FileName::Real(old_name) = name
+                    && let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
+                        old_name
+                    && let Ok(rest) = virtual_name.strip_prefix(virtual_dir)
+                {
+                    // The std library crates are in
+                    // `$sysroot/lib/rustlib/src/rust/library`, whereas other crates
+                    // may be in `$sysroot/lib/rustlib/src/rust/` directly. So we
+                    // detect crates from the std libs and handle them specially.
+                    const STD_LIBS: &[&str] = &[
+                        "core",
+                        "alloc",
+                        "std",
+                        "test",
+                        "term",
+                        "unwind",
+                        "proc_macro",
+                        "panic_abort",
+                        "panic_unwind",
+                        "profiler_builtins",
+                        "rtstartup",
+                        "rustc-std-workspace-core",
+                        "rustc-std-workspace-alloc",
+                        "rustc-std-workspace-std",
+                        "backtrace",
+                    ];
+                    let is_std_lib = STD_LIBS.iter().any(|l| rest.starts_with(l));
+
+                    let new_path = if is_std_lib {
+                        real_dir.join("library").join(rest)
+                    } else {
+                        real_dir.join(rest)
+                    };
+
+                    debug!(
+                        "try_to_translate_virtual_to_real: `{}` -> `{}`",
+                        virtual_name.display(),
+                        new_path.display(),
+                    );
+
+                    // Check if the translated real path is affected by any user-requested
+                    // remaps via --remap-path-prefix. Apply them if so.
+                    // Note that this is a special case for imported rust-src paths specified by
+                    // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths.
+                    // Other imported paths are not currently remapped (see #66251).
+                    let (user_remapped, applied) =
+                        sess.source_map().path_mapping().map_prefix(&new_path);
+                    let new_name = if applied {
+                        rustc_span::RealFileName::Remapped {
+                            local_path: Some(new_path.clone()),
+                            virtual_name: user_remapped.to_path_buf(),
                         }
-                    }
+                    } else {
+                        rustc_span::RealFileName::LocalPath(new_path)
+                    };
+                    *old_name = new_name;
                 }
             }
         };
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 54cfd995832..ee34ccd889f 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -217,7 +217,7 @@ pub fn early_report_macro_deprecation(
         suggestion_span: span,
         note: depr.note,
         path,
-        since_kind: deprecated_since_kind(is_in_effect, depr.since.clone()),
+        since_kind: deprecated_since_kind(is_in_effect, depr.since),
     };
     lint_buffer.buffer_lint(deprecation_lint(is_in_effect), node_id, span, diag);
 }
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 89d4c460160..b34f5b48b78 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -221,7 +221,9 @@ pub enum Const<'tcx> {
 }
 
 impl<'tcx> Const<'tcx> {
-    pub fn identity_unevaluated(
+    /// Creates an unevaluated const from a `DefId` for a const item.
+    /// The binders of the const item still need to be instantiated.
+    pub fn from_unevaluated(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
     ) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
@@ -329,18 +331,6 @@ impl<'tcx> Const<'tcx> {
         }
     }
 
-    /// Normalizes the constant to a value or an error if possible.
-    #[inline]
-    pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
-        match self.eval(tcx, param_env, DUMMY_SP) {
-            Ok(val) => Self::Val(val, self.ty()),
-            Err(ErrorHandled::Reported(guar, _span)) => {
-                Self::Ty(Ty::new_error(tcx, guar.into()), ty::Const::new_error(tcx, guar.into()))
-            }
-            Err(ErrorHandled::TooGeneric(_span)) => self,
-        }
-    }
-
     #[inline]
     pub fn try_eval_scalar(
         self,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index df60950a6b2..2ffb273cb6f 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -622,11 +622,13 @@ bidirectional_lang_item_map! {
     Destruct,
     DiscriminantKind,
     DynMetadata,
+    EffectsCompat,
     EffectsIntersection,
     EffectsIntersectionOutput,
     EffectsMaybe,
     EffectsNoRuntime,
     EffectsRuntime,
+    EffectsTyCompat,
     Fn,
     FnMut,
     FnOnce,
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index fbd45f59a4f..2ffad0b4834 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -699,23 +699,17 @@ impl<'tcx> Cx<'tcx> {
                             }
                         }
                         hir::InlineAsmOperand::Const { ref anon_const } => {
-                            let value = mir::Const::identity_unevaluated(
-                                tcx,
-                                anon_const.def_id.to_def_id(),
-                            )
-                            .instantiate_identity()
-                            .normalize(tcx, self.param_env);
+                            let value =
+                                mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id())
+                                    .instantiate_identity();
                             let span = tcx.def_span(anon_const.def_id);
 
                             InlineAsmOperand::Const { value, span }
                         }
                         hir::InlineAsmOperand::SymFn { ref anon_const } => {
-                            let value = mir::Const::identity_unevaluated(
-                                tcx,
-                                anon_const.def_id.to_def_id(),
-                            )
-                            .instantiate_identity()
-                            .normalize(tcx, self.param_env);
+                            let value =
+                                mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id())
+                                    .instantiate_identity();
                             let span = tcx.def_span(anon_const.def_id);
 
                             InlineAsmOperand::SymFn { value, span }
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 65442877d2d..cc4b7689d40 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -223,14 +223,14 @@ pub(crate) fn coroutine_by_move_body_def_id<'tcx>(
 
     // Inherited from the by-ref coroutine.
     body_def.codegen_fn_attrs(tcx.codegen_fn_attrs(coroutine_def_id).clone());
-    body_def.constness(tcx.constness(coroutine_def_id).clone());
-    body_def.coroutine_kind(tcx.coroutine_kind(coroutine_def_id).clone());
+    body_def.constness(tcx.constness(coroutine_def_id));
+    body_def.coroutine_kind(tcx.coroutine_kind(coroutine_def_id));
     body_def.def_ident_span(tcx.def_ident_span(coroutine_def_id));
     body_def.def_span(tcx.def_span(coroutine_def_id));
-    body_def.explicit_predicates_of(tcx.explicit_predicates_of(coroutine_def_id).clone());
+    body_def.explicit_predicates_of(tcx.explicit_predicates_of(coroutine_def_id));
     body_def.generics_of(tcx.generics_of(coroutine_def_id).clone());
-    body_def.param_env(tcx.param_env(coroutine_def_id).clone());
-    body_def.predicates_of(tcx.predicates_of(coroutine_def_id).clone());
+    body_def.param_env(tcx.param_env(coroutine_def_id));
+    body_def.predicates_of(tcx.predicates_of(coroutine_def_id));
 
     // The type of the coroutine is the `by_move_coroutine_ty`.
     body_def.type_of(ty::EarlyBinder::bind(by_move_coroutine_ty));
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index 9d85b5ba5a7..91fbc91e1e7 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -516,9 +516,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> {
                     // Avoid handling them, though this could be extended in the future.
                     return;
                 }
-                let Some(value) =
-                    value.const_.normalize(self.tcx, self.param_env).try_to_scalar_int()
-                else {
+                let Some(value) = value.const_.try_eval_scalar_int(self.tcx, self.param_env) else {
                     return;
                 };
                 let conds = conditions.map(self.arena, |c| Condition {
diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs
index 9884b6dd1c3..277a33c0311 100644
--- a/compiler/rustc_mir_transform/src/single_use_consts.rs
+++ b/compiler/rustc_mir_transform/src/single_use_consts.rs
@@ -185,15 +185,14 @@ impl<'tcx> MutVisitor<'tcx> for LocalReplacer<'tcx> {
             && let Some(local) = place.as_local()
             && local == self.local
         {
-            let const_op = self
+            let const_op = *self
                 .operand
                 .as_ref()
                 .unwrap_or_else(|| {
                     bug!("the operand was already stolen");
                 })
                 .constant()
-                .unwrap()
-                .clone();
+                .unwrap();
             var_debug_info.value = VarDebugInfoContents::Const(const_op);
         }
     }
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 3cb7576154f..8fce4266345 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -735,10 +735,10 @@ impl<Cx: PatCx> Clone for Constructor<Cx> {
             Constructor::UnionField => Constructor::UnionField,
             Constructor::Bool(b) => Constructor::Bool(*b),
             Constructor::IntRange(range) => Constructor::IntRange(*range),
-            Constructor::F16Range(lo, hi, end) => Constructor::F16Range(lo.clone(), *hi, *end),
-            Constructor::F32Range(lo, hi, end) => Constructor::F32Range(lo.clone(), *hi, *end),
-            Constructor::F64Range(lo, hi, end) => Constructor::F64Range(lo.clone(), *hi, *end),
-            Constructor::F128Range(lo, hi, end) => Constructor::F128Range(lo.clone(), *hi, *end),
+            Constructor::F16Range(lo, hi, end) => Constructor::F16Range(*lo, *hi, *end),
+            Constructor::F32Range(lo, hi, end) => Constructor::F32Range(*lo, *hi, *end),
+            Constructor::F64Range(lo, hi, end) => Constructor::F64Range(*lo, *hi, *end),
+            Constructor::F128Range(lo, hi, end) => Constructor::F128Range(*lo, *hi, *end),
             Constructor::Str(value) => Constructor::Str(value.clone()),
             Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
             Constructor::Or => Constructor::Or,
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 46e30c614ab..582db97e1ce 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1469,11 +1469,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         }
 
         let unused_macro = self.unused_macros.iter().find_map(|(def_id, (_, unused_ident))| {
-            if unused_ident.name == ident.name {
-                Some((def_id.clone(), unused_ident.clone()))
-            } else {
-                None
-            }
+            if unused_ident.name == ident.name { Some((def_id, unused_ident)) } else { None }
         });
 
         if let Some((def_id, unused_ident)) = unused_macro {
diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs
index 3db9b8b0661..61736633cfa 100644
--- a/compiler/rustc_type_ir/src/elaborate.rs
+++ b/compiler/rustc_type_ir/src/elaborate.rs
@@ -4,6 +4,7 @@ use smallvec::smallvec;
 
 use crate::data_structures::HashSet;
 use crate::inherent::*;
+use crate::lang_items::TraitSolverLangItem;
 use crate::outlives::{Component, push_outlives_components};
 use crate::{self as ty, Interner, Upcast as _};
 
@@ -89,6 +90,70 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
                     return;
                 }
 
+                // HACK(effects): The following code is required to get implied bounds for effects associated
+                // types to work with super traits.
+                //
+                // Suppose `data` is a trait predicate with the form `<T as Tr>::Fx: EffectsCompat<somebool>`
+                // and we know that `trait Tr: ~const SuperTr`, we need to elaborate this predicate into
+                // `<T as SuperTr>::Fx: EffectsCompat<somebool>`.
+                //
+                // Since the semantics for elaborating bounds about effects is equivalent to elaborating
+                // bounds about super traits (elaborate `T: Tr` into `T: SuperTr`), we place effects elaboration
+                // next to super trait elaboration.
+                if cx.is_lang_item(data.def_id(), TraitSolverLangItem::EffectsCompat)
+                    && matches!(self.mode, Filter::All)
+                {
+                    // first, ensure that the predicate we've got looks like a `<T as Tr>::Fx: EffectsCompat<somebool>`.
+                    if let ty::Alias(ty::AliasTyKind::Projection, alias_ty) = data.self_ty().kind()
+                    {
+                        // look for effects-level bounds that look like `<Self as Tr>::Fx: TyCompat<<Self as SuperTr>::Fx>`
+                        // on the trait, which is proof to us that `Tr: ~const SuperTr`. We're looking for bounds on the
+                        // associated trait, so we use `explicit_implied_predicates_of` since it gives us more than just
+                        // `Self: SuperTr` bounds.
+                        let bounds = cx.explicit_implied_predicates_of(cx.parent(alias_ty.def_id));
+
+                        // instantiate the implied bounds, so we get `<T as Tr>::Fx` and not `<Self as Tr>::Fx`.
+                        let elaborated = bounds.iter_instantiated(cx, alias_ty.args).filter_map(
+                            |(clause, _)| {
+                                let ty::ClauseKind::Trait(tycompat_bound) =
+                                    clause.kind().skip_binder()
+                                else {
+                                    return None;
+                                };
+                                if !cx.is_lang_item(
+                                    tycompat_bound.def_id(),
+                                    TraitSolverLangItem::EffectsTyCompat,
+                                ) {
+                                    return None;
+                                }
+
+                                // extract `<T as SuperTr>::Fx` from the `TyCompat` bound.
+                                let supertrait_effects_ty =
+                                    tycompat_bound.trait_ref.args.type_at(1);
+                                let ty::Alias(ty::AliasTyKind::Projection, supertrait_alias_ty) =
+                                    supertrait_effects_ty.kind()
+                                else {
+                                    return None;
+                                };
+
+                                // The self types (`T`) must be equal for `<T as Tr>::Fx` and `<T as SuperTr>::Fx`.
+                                if supertrait_alias_ty.self_ty() != alias_ty.self_ty() {
+                                    return None;
+                                };
+
+                                // replace the self type in the original bound `<T as Tr>::Fx: EffectsCompat<somebool>`
+                                // to the effects type of the super trait. (`<T as SuperTr>::Fx`)
+                                let elaborated_bound = data.with_self_ty(cx, supertrait_effects_ty);
+                                Some(
+                                    elaboratable
+                                        .child(bound_clause.rebind(elaborated_bound).upcast(cx)),
+                                )
+                            },
+                        );
+                        self.extend_deduped(elaborated);
+                    }
+                }
+
                 let map_to_child_clause =
                     |(index, (clause, span)): (usize, (I::Clause, I::Span))| {
                         elaboratable.child_with_derived_cause(
diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs
index 265a4118827..c680c844746 100644
--- a/compiler/rustc_type_ir/src/lang_items.rs
+++ b/compiler/rustc_type_ir/src/lang_items.rs
@@ -20,11 +20,13 @@ pub enum TraitSolverLangItem {
     Destruct,
     DiscriminantKind,
     DynMetadata,
+    EffectsCompat,
     EffectsIntersection,
     EffectsIntersectionOutput,
     EffectsMaybe,
     EffectsNoRuntime,
     EffectsRuntime,
+    EffectsTyCompat,
     Fn,
     FnMut,
     FnOnce,