diff options
Diffstat (limited to 'compiler')
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, |
