From 207bc77e15acc9444bf6c3e74fa46607490a8e8a Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 11 Sep 2024 13:57:12 +0100 Subject: codegen_ssa: consolidate tied feature checking `rustc_codegen_llvm` and `rustc_codegen_gcc` duplicated logic for checking if tied target features were partially enabled. This commit consolidates these checks into `rustc_codegen_ssa` in the `codegen_fn_attrs` query, which also is run pre-monomorphisation for each function, which ensures that this check is run for unused functions, as would be expected. --- compiler/rustc_codegen_gcc/messages.ftl | 3 -- compiler/rustc_codegen_gcc/src/attributes.rs | 22 ++---------- compiler/rustc_codegen_gcc/src/errors.rs | 36 -------------------- compiler/rustc_codegen_gcc/src/gcc_util.rs | 24 ++----------- compiler/rustc_codegen_llvm/messages.ftl | 6 ---- compiler/rustc_codegen_llvm/src/attributes.rs | 23 +------------ compiler/rustc_codegen_llvm/src/errors.rs | 24 ------------- compiler/rustc_codegen_llvm/src/llvm_util.rs | 26 +++----------- compiler/rustc_codegen_ssa/messages.ftl | 5 +++ compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 45 +++++++++++++++++++++++-- compiler/rustc_codegen_ssa/src/errors.rs | 26 +++++++++++++- 11 files changed, 83 insertions(+), 157 deletions(-) (limited to 'compiler') diff --git a/compiler/rustc_codegen_gcc/messages.ftl b/compiler/rustc_codegen_gcc/messages.ftl index 0235384445e..bbae59ea7a5 100644 --- a/compiler/rustc_codegen_gcc/messages.ftl +++ b/compiler/rustc_codegen_gcc/messages.ftl @@ -8,9 +8,6 @@ codegen_gcc_invalid_minimum_alignment = codegen_gcc_lto_not_supported = LTO is not supported. You may get a linker error. -codegen_gcc_tied_target_features = the target features {$features} must all be either enabled or disabled together - .help = add the missing features in a `target_feature` attribute - codegen_gcc_unwinding_inline_asm = GCC backend does not support unwinding from inline asm diff --git a/compiler/rustc_codegen_gcc/src/attributes.rs b/compiler/rustc_codegen_gcc/src/attributes.rs index 5fdf2680aac..d20e13e15b9 100644 --- a/compiler/rustc_codegen_gcc/src/attributes.rs +++ b/compiler/rustc_codegen_gcc/src/attributes.rs @@ -7,11 +7,9 @@ use rustc_attr::InstructionSetAttr; #[cfg(feature = "master")] use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty; -use rustc_span::symbol::sym; use crate::context::CodegenCx; -use crate::errors::TiedTargetFeatures; -use crate::gcc_util::{check_tied_features, to_gcc_features}; +use crate::gcc_util::to_gcc_features; /// Get GCC attribute for the provided inline heuristic. #[cfg(feature = "master")] @@ -72,26 +70,10 @@ pub fn from_fn_attrs<'gcc, 'tcx>( } } - let function_features = codegen_fn_attrs + let mut function_features = codegen_fn_attrs .target_features .iter() .map(|features| features.name.as_str()) - .collect::>(); - - if let Some(features) = check_tied_features( - cx.tcx.sess, - &function_features.iter().map(|features| (*features, true)).collect(), - ) { - let span = cx - .tcx - .get_attr(instance.def_id(), sym::target_feature) - .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span); - cx.tcx.dcx().create_err(TiedTargetFeatures { features: features.join(", "), span }).emit(); - return; - } - - let mut function_features = function_features - .iter() .flat_map(|feat| to_gcc_features(cx.tcx.sess, feat).into_iter()) .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match *x { InstructionSetAttr::ArmA32 => "-thumb-mode", // TODO(antoyo): support removing feature. diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs index 6bada3d334c..dc1895f437b 100644 --- a/compiler/rustc_codegen_gcc/src/errors.rs +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -1,9 +1,6 @@ -use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; -use crate::fluent_generated as fluent; - #[derive(Diagnostic)] #[diag(codegen_gcc_unknown_ctarget_feature_prefix)] #[note] @@ -45,15 +42,6 @@ pub(crate) struct InvalidMinimumAlignment { pub err: String, } -#[derive(Diagnostic)] -#[diag(codegen_gcc_tied_target_features)] -#[help] -pub(crate) struct TiedTargetFeatures { - #[primary_span] - pub span: Span, - pub features: String, -} - #[derive(Diagnostic)] #[diag(codegen_gcc_copy_bitcode)] pub(crate) struct CopyBitcode { @@ -78,27 +66,3 @@ pub(crate) struct LtoDylib; pub(crate) struct LtoBitcodeFromRlib { pub gcc_err: String, } - -pub(crate) struct TargetFeatureDisableOrEnable<'a> { - pub features: &'a [&'a str], - pub span: Option, - pub missing_features: Option, -} - -#[derive(Subdiagnostic)] -#[help(codegen_gcc_missing_features)] -pub(crate) struct MissingFeatures; - -impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { - fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::codegen_gcc_target_feature_disable_or_enable); - if let Some(span) = self.span { - diag.span(span); - }; - if let Some(missing_features) = self.missing_features { - diag.subdiagnostic(missing_features); - } - diag.arg("features", self.features.join(", ")); - diag - } -} diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 01dd1a8856a..3104088e0d5 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -1,15 +1,14 @@ #[cfg(feature = "master")] use gccjit::Context; +use rustc_codegen_ssa::codegen_attrs::check_tied_features; +use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable; use rustc_data_structures::fx::FxHashMap; use rustc_middle::bug; use rustc_session::Session; use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; use smallvec::{SmallVec, smallvec}; -use crate::errors::{ - PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature, - UnknownCTargetFeaturePrefix, -}; +use crate::errors::{PossibleFeature, UnknownCTargetFeature, UnknownCTargetFeaturePrefix}; /// The list of GCC features computed from CLI flags (`-Ctarget-cpu`, `-Ctarget-feature`, /// `--target` and similar). @@ -185,23 +184,6 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]> } } -// Given a map from target_features to whether they are enabled or disabled, -// ensure only valid combinations are allowed. -pub fn check_tied_features( - sess: &Session, - features: &FxHashMap<&str, bool>, -) -> Option<&'static [&'static str]> { - for tied in sess.target.tied_target_features() { - // Tied features must be set to the same value, or not set at all - let mut tied_iter = tied.iter(); - let enabled = features.get(tied_iter.next().unwrap()); - if tied_iter.any(|feature| enabled != features.get(feature)) { - return Some(tied); - } - } - None -} - fn arch_to_gcc(name: &str) -> &str { match name { "M68020" => "68020", diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index df2198df14b..0950e4bb26b 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -33,9 +33,6 @@ codegen_llvm_lto_proc_macro = lto cannot be used for `proc-macro` crate type wit codegen_llvm_mismatch_data_layout = data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}` -codegen_llvm_missing_features = - add the missing features in a `target_feature` attribute - codegen_llvm_multiple_source_dicompileunit = multiple source DICompileUnits found codegen_llvm_multiple_source_dicompileunit_with_llvm_err = multiple source DICompileUnits found: {$llvm_err} @@ -63,9 +60,6 @@ codegen_llvm_serialize_module_with_llvm_err = failed to serialize module {$name} codegen_llvm_symbol_already_defined = symbol `{$symbol_name}` is already defined -codegen_llvm_target_feature_disable_or_enable = - the target features {$features} must all be either enabled or disabled together - codegen_llvm_target_machine = could not create LLVM TargetMachine for triple: {$triple} codegen_llvm_target_machine_with_llvm_err = could not create LLVM TargetMachine for triple: {$triple}: {$llvm_err} diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 489259da856..2c5ec9dad59 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -6,12 +6,11 @@ use rustc_hir::def_id::DefId; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; -use rustc_span::symbol::sym; use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector}; use smallvec::SmallVec; use crate::context::CodegenCx; -use crate::errors::{MissingFeatures, SanitizerMemtagRequiresMte, TargetFeatureDisableOrEnable}; +use crate::errors::SanitizerMemtagRequiresMte; use crate::llvm::AttributePlace::Function; use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects}; use crate::value::Value; @@ -502,26 +501,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( let function_features = codegen_fn_attrs.target_features.iter().map(|f| f.name.as_str()).collect::>(); - if let Some(f) = llvm_util::check_tied_features( - cx.tcx.sess, - &function_features.iter().map(|f| (*f, true)).collect(), - ) { - let span = cx - .tcx - .get_attrs(instance.def_id(), sym::target_feature) - .next() - .map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span); - cx.tcx - .dcx() - .create_err(TargetFeatureDisableOrEnable { - features: f, - span: Some(span), - missing_features: Some(MissingFeatures), - }) - .emit(); - return; - } - let function_features = function_features .iter() // Convert to LLVMFeatures and filter out unavailable ones diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index bb481d2a308..0d436e1891e 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -80,30 +80,6 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { } } -pub(crate) struct TargetFeatureDisableOrEnable<'a> { - pub features: &'a [&'a str], - pub span: Option, - pub missing_features: Option, -} - -#[derive(Subdiagnostic)] -#[help(codegen_llvm_missing_features)] -pub(crate) struct MissingFeatures; - -impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { - fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::codegen_llvm_target_feature_disable_or_enable); - if let Some(span) = self.span { - diag.span(span); - }; - if let Some(missing_features) = self.missing_features { - diag.subdiagnostic(missing_features); - } - diag.arg("features", self.features.join(", ")); - diag - } -} - #[derive(Diagnostic)] #[diag(codegen_llvm_lto_disallowed)] pub(crate) struct LtoDisallowed; diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 71fd7afb148..79820ee0cdb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -6,6 +6,7 @@ use std::{ptr, slice, str}; use libc::c_int; use rustc_codegen_ssa::base::wants_wasm_eh; +use rustc_codegen_ssa::codegen_attrs::check_tied_features; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::small_c_str::SmallCStr; use rustc_data_structures::unord::UnordSet; @@ -19,8 +20,8 @@ use rustc_target::target_features::{RUSTC_SPECIAL_FEATURES, RUSTC_SPECIFIC_FEATU use crate::back::write::create_informational_target_machine; use crate::errors::{ - FixedX18InvalidArch, InvalidTargetFeaturePrefix, PossibleFeature, TargetFeatureDisableOrEnable, - UnknownCTargetFeature, UnknownCTargetFeaturePrefix, UnstableCTargetFeature, + FixedX18InvalidArch, InvalidTargetFeaturePrefix, PossibleFeature, UnknownCTargetFeature, + UnknownCTargetFeaturePrefix, UnstableCTargetFeature, }; use crate::llvm; @@ -272,25 +273,6 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option, -) -> Option<&'static [&'static str]> { - if !features.is_empty() { - for tied in sess.target.tied_target_features() { - // Tied features must be set to the same value, or not set at all - let mut tied_iter = tied.iter(); - let enabled = features.get(tied_iter.next().unwrap()); - if tied_iter.any(|f| enabled != features.get(f)) { - return Some(tied); - } - } - } - None -} - /// Used to generate cfg variables and apply features /// Must express features in the way Rust understands them pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec { @@ -676,7 +658,7 @@ pub(crate) fn global_llvm_features( features.extend(feats); if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) { - sess.dcx().emit_err(TargetFeatureDisableOrEnable { + sess.dcx().emit_err(rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable { features: f, span: None, missing_features: None, diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 9091602d75b..cce5e8b1398 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -183,6 +183,8 @@ codegen_ssa_metadata_object_file_write = error writing metadata object file: {$e codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload +codegen_ssa_missing_features = add the missing features in a `target_feature` attribute + codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering codegen_ssa_missing_query_depgraph = @@ -238,6 +240,9 @@ codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` fa codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error} +codegen_ssa_target_feature_disable_or_enable = + the target features {$features} must all be either enabled or disabled together + codegen_ssa_target_feature_safe_trait = `#[target_feature(..)]` cannot be applied to safe trait method .label = cannot be applied to safe trait method .label_def = not an `unsafe` function diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index e99c3a46271..a27f983c99a 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,5 +1,6 @@ use rustc_ast::{MetaItemKind, NestedMetaItem, ast, attr}; use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_name}; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::codes::*; use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; use rustc_hir as hir; @@ -13,13 +14,13 @@ use rustc_middle::middle::codegen_fn_attrs::{ use rustc_middle::mir::mono::Linkage; use rustc_middle::query::Providers; use rustc_middle::ty::{self as ty, TyCtxt}; -use rustc_session::lint; use rustc_session::parse::feature_err; +use rustc_session::{Session, lint}; use rustc_span::symbol::Ident; use rustc_span::{Span, sym}; use rustc_target::spec::{SanitizerSet, abi}; -use crate::errors; +use crate::errors::{self, MissingFeatures, TargetFeatureDisableOrEnable}; use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature}; fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage { @@ -662,9 +663,49 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } } + if let Some(features) = check_tied_features( + tcx.sess, + &codegen_fn_attrs + .target_features + .iter() + .map(|features| (features.name.as_str(), true)) + .collect(), + ) { + let span = tcx + .get_attrs(did, sym::target_feature) + .next() + .map_or_else(|| tcx.def_span(did), |a| a.span); + tcx.dcx() + .create_err(TargetFeatureDisableOrEnable { + features, + span: Some(span), + missing_features: Some(MissingFeatures), + }) + .emit(); + } + codegen_fn_attrs } +/// Given a map from target_features to whether they are enabled or disabled, ensure only valid +/// combinations are allowed. +pub fn check_tied_features( + sess: &Session, + features: &FxHashMap<&str, bool>, +) -> Option<&'static [&'static str]> { + if !features.is_empty() { + for tied in sess.target.tied_target_features() { + // Tied features must be set to the same value, or not set at all + let mut tied_iter = tied.iter(); + let enabled = features.get(tied_iter.next().unwrap()); + if tied_iter.any(|f| enabled != features.get(f)) { + return Some(tied); + } + } + } + None +} + /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller /// applied to the method prototype. fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 08b326e3ac3..bc80f51f31c 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -9,7 +9,7 @@ use rustc_errors::codes::*; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, }; -use rustc_macros::Diagnostic; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutError; use rustc_span::{Span, Symbol}; @@ -1068,3 +1068,27 @@ pub(crate) struct ErrorCreatingImportLibrary<'a> { pub lib_name: &'a str, pub error: String, } + +pub struct TargetFeatureDisableOrEnable<'a> { + pub features: &'a [&'a str], + pub span: Option, + pub missing_features: Option, +} + +#[derive(Subdiagnostic)] +#[help(codegen_ssa_missing_features)] +pub struct MissingFeatures; + +impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { + fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { + let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_target_feature_disable_or_enable); + if let Some(span) = self.span { + diag.span(span); + }; + if let Some(missing_features) = self.missing_features { + diag.subdiagnostic(missing_features); + } + diag.arg("features", self.features.join(", ")); + diag + } +} -- cgit 1.4.1-3-g733a5 From 62b24ea7c53aec6f8176fed05d0acee926b76bdb Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Wed, 9 Oct 2024 20:19:36 +0200 Subject: Compiler: Replace remaining occurrences of "object safe" with "dyn compatible" --- .../src/traits/dyn_compatibility.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'compiler') diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index d5d7681a8d6..191eda4d347 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -1,12 +1,8 @@ -//! "Object safety" refers to the ability for a trait to be converted -//! to an object. In general, traits may only be converted to an -//! object if all of their methods meet certain criteria. In particular, -//! they must: +//! "Dyn-compatibility"[^1] refers to the ability for a trait to be converted +//! to a trait object. In general, traits may only be converted to a trait +//! object if certain criteria are met. //! -//! - have a suitable receiver from which we can extract a vtable and coerce to a "thin" version -//! that doesn't contain the vtable; -//! - not reference the erased type `Self` except for in this receiver; -//! - not have generic type parameters. +//! [^1]: Formerly known as "object safety". use std::iter; use std::ops::ControlFlow; @@ -506,8 +502,8 @@ fn virtual_call_violations_for_method<'tcx>( /// This code checks that `receiver_is_dispatchable` is correctly implemented. /// -/// This check is outlined from the object safety check to avoid cycles with -/// layout computation, which relies on knowing whether methods are object safe. +/// This check is outlined from the dyn-compatibility check to avoid cycles with +/// layout computation, which relies on knowing whether methods are dyn-compatible. fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: ty::AssocItem) { if !is_vtable_safe_method(tcx, trait_def_id, method) { return; @@ -644,7 +640,7 @@ fn object_ty_for_trait<'tcx>( /// a pointer. /// /// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result -/// in a new check that `Trait` is object safe, creating a cycle (until object_safe_for_dispatch +/// in a new check that `Trait` is dyn-compatible, creating a cycle (until object_safe_for_dispatch /// is stabilized, see tracking issue ). /// Instead, we fudge a little by introducing a new type parameter `U` such that /// `Self: Unsize` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`. @@ -865,7 +861,7 @@ impl<'tcx> TypeVisitor> for IllegalSelfTypeVisitor<'tcx> { } fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result { - // Constants can only influence object safety if they are generic and reference `Self`. + // Constants can only influence dyn-compatibility if they are generic and reference `Self`. // This is only possible for unevaluated constants, so we walk these here. self.tcx.expand_abstract_consts(ct).super_visit_with(self) } -- cgit 1.4.1-3-g733a5 From 2e7a52b22fe222316a48093547f6312252c20f0f Mon Sep 17 00:00:00 2001 From: León Orell Valerian Liehr Date: Wed, 9 Oct 2024 18:37:30 +0200 Subject: Rename feature object_safe_for_dispatch to dyn_compatible_for_dispatch --- compiler/rustc_feature/src/removed.rs | 4 ++ compiler/rustc_feature/src/unstable.rs | 15 ++-- compiler/rustc_hir_analysis/src/coherence/mod.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + .../src/traits/dyn_compatibility.rs | 6 +- .../src/traits/select/candidate_assembly.rs | 2 +- compiler/rustc_trait_selection/src/traits/wf.rs | 2 +- tests/crashes/120241-2.rs | 2 +- tests/crashes/120241.rs | 2 +- tests/crashes/120482.rs | 2 +- tests/crashes/125512.rs | 2 +- tests/crashes/128176.rs | 2 +- tests/crashes/130521.rs | 2 +- .../coherence-unsafe-trait-object-impl.rs | 2 +- .../feature-gate-dyn_compatible_for_dispatch.rs | 41 +++++++++++ ...feature-gate-dyn_compatible_for_dispatch.stderr | 83 ++++++++++++++++++++++ .../feature-gate-object_safe_for_dispatch.rs | 41 ----------- .../feature-gate-object_safe_for_dispatch.stderr | 83 ---------------------- ...d-copy-bound.dyn_compatible_for_dispatch.stderr | 40 +++++++++++ ...ited-copy-bound.object_safe_for_dispatch.stderr | 40 ----------- tests/ui/kindck/kindck-inherited-copy-bound.rs | 8 +-- ...iated-consts.dyn_compatible_for_dispatch.stderr | 19 +++++ ...sociated-consts.object_safe_for_dispatch.stderr | 19 ----- .../object-safety-associated-consts.rs | 4 +- ...ety-generics.dyn_compatible_for_dispatch.stderr | 35 +++++++++ ...safety-generics.object_safe_for_dispatch.stderr | 35 --------- tests/ui/object-safety/object-safety-generics.rs | 8 +-- ...entions-Self.dyn_compatible_for_dispatch.stderr | 35 +++++++++ ...y-mentions-Self.object_safe_for_dispatch.stderr | 35 --------- .../object-safety/object-safety-mentions-Self.rs | 4 +- ...ty-no-static.dyn_compatible_for_dispatch.stderr | 27 +++++++ ...afety-no-static.object_safe_for_dispatch.stderr | 27 ------- tests/ui/object-safety/object-safety-no-static.rs | 4 +- ...fety-sized-2.dyn_compatible_for_dispatch.stderr | 18 +++++ ...-safety-sized-2.object_safe_for_dispatch.stderr | 18 ----- tests/ui/object-safety/object-safety-sized-2.rs | 4 +- ...safety-sized.dyn_compatible_for_dispatch.stderr | 18 +++++ ...ct-safety-sized.object_safe_for_dispatch.stderr | 18 ----- tests/ui/object-safety/object-safety-sized.rs | 4 +- .../downcast-unsafe-trait-objects.rs | 23 ++++++ .../manual-self-impl-for-unsafe-obj.current.stderr | 15 ++++ .../manual-self-impl-for-unsafe-obj.next.stderr | 15 ++++ .../manual-self-impl-for-unsafe-obj.rs | 69 ++++++++++++++++++ .../static-dispatch-unsafe-object.rs | 37 ++++++++++ .../downcast-unsafe-trait-objects.rs | 23 ------ .../manual-self-impl-for-unsafe-obj.current.stderr | 15 ---- .../manual-self-impl-for-unsafe-obj.next.stderr | 15 ---- .../manual-self-impl-for-unsafe-obj.rs | 69 ------------------ .../static-dispatch-unsafe-object.rs | 37 ---------- ...-object-safe.dyn_compatible_for_dispatch.stderr | 22 ++++++ ...not-object-safe.object_safe_for_dispatch.stderr | 22 ------ .../self/arbitrary-self-types-not-object-safe.rs | 6 +- tests/ui/suggestions/issue-104328.rs | 2 +- tests/ui/wf/wf-convert-unsafe-trait-obj-box.rs | 2 +- tests/ui/wf/wf-convert-unsafe-trait-obj.rs | 2 +- tests/ui/wf/wf-unsafe-trait-obj-match.rs | 2 +- 56 files changed, 548 insertions(+), 542 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs create mode 100644 tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs delete mode 100644 tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr create mode 100644 tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-associated-consts.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-generics.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-mentions-Self.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-no-static.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-sized-2.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-sized.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr create mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs create mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr create mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr create mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs create mode 100644 tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs delete mode 100644 tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs delete mode 100644 tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr delete mode 100644 tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr delete mode 100644 tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs delete mode 100644 tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs create mode 100644 tests/ui/self/arbitrary-self-types-not-object-safe.dyn_compatible_for_dispatch.stderr delete mode 100644 tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr (limited to 'compiler') diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 0cd0963d4e3..c275ad31b87 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -154,6 +154,10 @@ declare_features! ( /// then removed. But there was no utility storing it separately, so now /// it's in this list. (removed, no_stack_check, "1.0.0", None, None), + /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn-compatible (object safe). + /// Renamed to `dyn_compatible_for_dispatch`. + (removed, object_safe_for_dispatch, "CURRENT_RUSTC_VERSION", Some(43561), + Some("renamed to `dyn_compatible_for_dispatch`")), /// Allows using `#[on_unimplemented(..)]` on traits. /// (Moved to `rustc_attrs`.) (removed, on_unimplemented, "1.40.0", None, None), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index c5530097e96..110ffa75b05 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -259,6 +259,14 @@ declare_features! ( (unstable, doc_notable_trait, "1.52.0", Some(45040)), /// Allows using the `may_dangle` attribute (RFC 1327). (unstable, dropck_eyepatch, "1.10.0", Some(34761)), + /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn-compatible[^1]. + /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and + /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. + /// + /// Renamed from `object_safe_for_dispatch`. + /// + /// [^1]: Formerly known as "object safe". + (unstable, dyn_compatible_for_dispatch, "CURRENT_RUSTC_VERSION", Some(43561)), /// Allows using the `#[fundamental]` attribute. (unstable, fundamental, "1.0.0", Some(29635)), /// Allows using `#[link_name="llvm.*"]`. @@ -544,13 +552,6 @@ declare_features! ( (unstable, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554)), /// Allows `for` binders in where-clauses (incomplete, non_lifetime_binders, "1.69.0", Some(108185)), - /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn-compatible[^1]. - /// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and - /// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden. - /// - /// [^1]: Formerly known as "object safe". - // FIXME(dyn_compat_renaming): Rename feature. - (unstable, object_safe_for_dispatch, "1.40.0", Some(43561)), /// Allows using enums in offset_of! (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using fields with slice type in offset_of! diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 69d36426447..eea5a16ac6f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -199,7 +199,7 @@ fn check_object_overlap<'tcx>( for component_def_id in component_def_ids { if !tcx.is_dyn_compatible(component_def_id) { // FIXME(dyn_compat_renaming): Rename test and update comment. - // Without the 'object_safe_for_dispatch' feature this is an error + // Without the 'dyn_compatible_for_dispatch' feature this is an error // which will be reported by wfcheck. Ignore it here. // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`. // With the feature enabled, the trait is not implemented automatically, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index e8aa129c6cd..9e2df848309 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -776,6 +776,7 @@ symbols! { dropck_eyepatch, dropck_parametricity, dylib, + dyn_compatible_for_dispatch, dyn_metadata, dyn_star, dyn_trait, diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 191eda4d347..45e7de942fb 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -639,8 +639,8 @@ fn object_ty_for_trait<'tcx>( /// contained by the trait object, because the object that needs to be coerced is behind /// a pointer. /// -/// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result -/// in a new check that `Trait` is dyn-compatible, creating a cycle (until object_safe_for_dispatch +/// In practice, we cannot use `dyn Trait` explicitly in the obligation because it would result in +/// a new check that `Trait` is dyn-compatible, creating a cycle (until dyn_compatible_for_dispatch /// is stabilized, see tracking issue ). /// Instead, we fudge a little by introducing a new type parameter `U` such that /// `Self: Unsize` and `U: Trait + ?Sized`, and use `U` in place of `dyn Trait`. @@ -674,7 +674,7 @@ fn receiver_is_dispatchable<'tcx>( // the type `U` in the query // use a bogus type parameter to mimic a forall(U) query using u32::MAX for now. - // FIXME(mikeyhew) this is a total hack. Once object_safe_for_dispatch is stabilized, we can + // FIXME(mikeyhew) this is a total hack. Once dyn_compatible_for_dispatch is stabilized, we can // replace this with `dyn Trait` let unsized_self_ty: Ty<'tcx> = Ty::new_param(tcx, u32::MAX, Symbol::intern("RustaceansAreAwesome")); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 084b61115db..20adda6f0de 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -881,7 +881,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } if let Some(principal) = data.principal() { - if !self.infcx.tcx.features().object_safe_for_dispatch { + if !self.infcx.tcx.features().dyn_compatible_for_dispatch { principal.with_self_ty(self.tcx(), self_ty) } else if self.tcx().is_dyn_compatible(principal.def_id()) { principal.with_self_ty(self.tcx(), self_ty) diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 7e140ecfee0..a849cdfe125 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -829,7 +829,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { // obligations that don't refer to Self and // checking those - let defer_to_coercion = tcx.features().object_safe_for_dispatch; + let defer_to_coercion = tcx.features().dyn_compatible_for_dispatch; if !defer_to_coercion { if let Some(principal) = data.principal_def_id() { diff --git a/tests/crashes/120241-2.rs b/tests/crashes/120241-2.rs index 9c4a3a50293..91ec3362090 100644 --- a/tests/crashes/120241-2.rs +++ b/tests/crashes/120241-2.rs @@ -1,6 +1,6 @@ //@ known-bug: #120241 //@ edition:2021 -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] #![feature(unsized_fn_params)] fn guard(_s: Copy) -> bool { diff --git a/tests/crashes/120241.rs b/tests/crashes/120241.rs index f18347a006c..b4fcb903714 100644 --- a/tests/crashes/120241.rs +++ b/tests/crashes/120241.rs @@ -1,6 +1,6 @@ //@ known-bug: #120241 //@ edition:2021 -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait B { fn f(a: A) -> A; diff --git a/tests/crashes/120482.rs b/tests/crashes/120482.rs index 6cbc2009c5f..a395855d796 100644 --- a/tests/crashes/120482.rs +++ b/tests/crashes/120482.rs @@ -1,6 +1,6 @@ //@ known-bug: #120482 //@ edition:2021 -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait B { fn bar(&self, x: &Self); diff --git a/tests/crashes/125512.rs b/tests/crashes/125512.rs index 1672b24a114..37dbdf2f32f 100644 --- a/tests/crashes/125512.rs +++ b/tests/crashes/125512.rs @@ -1,6 +1,6 @@ //@ known-bug: rust-lang/rust#125512 //@ edition:2021 -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait B { fn f(a: A) -> A; } diff --git a/tests/crashes/128176.rs b/tests/crashes/128176.rs index 70fada4f0fe..970ad9ff2cd 100644 --- a/tests/crashes/128176.rs +++ b/tests/crashes/128176.rs @@ -1,7 +1,7 @@ //@ known-bug: rust-lang/rust#128176 #![feature(generic_const_exprs)] -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait X { type Y; } diff --git a/tests/crashes/130521.rs b/tests/crashes/130521.rs index 2d30b658024..7c078ab5790 100644 --- a/tests/crashes/130521.rs +++ b/tests/crashes/130521.rs @@ -1,6 +1,6 @@ //@ known-bug: #130521 -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] struct Vtable(dyn Cap); trait Cap<'a> {} diff --git a/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs b/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs index 9859a226efd..16baf0958a6 100644 --- a/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs +++ b/tests/ui/coherence/coherence-unsafe-trait-object-impl.rs @@ -1,7 +1,7 @@ // Check that unsafe trait object do not implement themselves // automatically -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait Trait: Sized { fn call(&self); diff --git a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs new file mode 100644 index 00000000000..2dbba370a51 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.rs @@ -0,0 +1,41 @@ +// Test that the use of the dyn-incompatible trait objects +// are gated by the `dyn_compatible_for_dispatch` feature gate. + +trait DynIncompatible1: Sized {} + +trait DynIncompatible2 { + fn static_fn() {} +} + +trait DynIncompatible3 { + fn foo(&self); +} + +trait DynIncompatible4 { + fn foo(&self, s: &Self); +} + +fn takes_non_object_safe_ref(obj: &dyn DynIncompatible1) { + //~^ ERROR E0038 +} + +fn return_non_object_safe_ref() -> &'static dyn DynIncompatible2 { + //~^ ERROR E0038 + loop {} +} + +fn takes_non_object_safe_box(obj: Box) { + //~^ ERROR E0038 +} + +fn return_non_object_safe_rc() -> std::rc::Rc { + //~^ ERROR E0038 + loop {} +} + +trait Trait {} + +impl Trait for dyn DynIncompatible1 {} +//~^ ERROR E0038 + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..3cb73dfd52c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-dyn_compatible_for_dispatch.stderr @@ -0,0 +1,83 @@ +error[E0038]: the trait `DynIncompatible1` cannot be made into an object + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:18:39 + | +LL | fn takes_non_object_safe_ref(obj: &dyn DynIncompatible1) { + | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25 + | +LL | trait DynIncompatible1: Sized {} + | ---------------- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + +error[E0038]: the trait `DynIncompatible2` cannot be made into an object + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:22:45 + | +LL | fn return_non_object_safe_ref() -> &'static dyn DynIncompatible2 { + | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible2` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:7:8 + | +LL | trait DynIncompatible2 { + | ---------------- this trait cannot be made into an object... +LL | fn static_fn() {} + | ^^^^^^^^^ ...because associated function `static_fn` has no `self` parameter +help: consider turning `static_fn` into a method by giving it a `&self` argument + | +LL | fn static_fn(&self) {} + | +++++ +help: alternatively, consider constraining `static_fn` so it does not apply to trait objects + | +LL | fn static_fn() where Self: Sized {} + | +++++++++++++++++ + +error[E0038]: the trait `DynIncompatible3` cannot be made into an object + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:27:39 + | +LL | fn takes_non_object_safe_box(obj: Box) { + | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible3` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:11:8 + | +LL | trait DynIncompatible3 { + | ---------------- this trait cannot be made into an object... +LL | fn foo(&self); + | ^^^ ...because method `foo` has generic type parameters + = help: consider moving `foo` to another trait + +error[E0038]: the trait `DynIncompatible4` cannot be made into an object + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:31:47 + | +LL | fn return_non_object_safe_rc() -> std::rc::Rc { + | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible4` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:15:22 + | +LL | trait DynIncompatible4 { + | ---------------- this trait cannot be made into an object... +LL | fn foo(&self, s: &Self); + | ^^^^^ ...because method `foo` references the `Self` type in this parameter + = help: consider moving `foo` to another trait + +error[E0038]: the trait `DynIncompatible1` cannot be made into an object + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:38:16 + | +LL | impl Trait for dyn DynIncompatible1 {} + | ^^^^^^^^^^^^^^^^^^^^ `DynIncompatible1` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/feature-gate-dyn_compatible_for_dispatch.rs:4:25 + | +LL | trait DynIncompatible1: Sized {} + | ---------------- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs b/tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs deleted file mode 100644 index 37348e476d4..00000000000 --- a/tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Test that the use of the non object-safe trait objects -// are gated by `object_safe_for_dispatch` feature gate. - -trait NonObjectSafe1: Sized {} - -trait NonObjectSafe2 { - fn static_fn() {} -} - -trait NonObjectSafe3 { - fn foo(&self); -} - -trait NonObjectSafe4 { - fn foo(&self, s: &Self); -} - -fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { - //~^ ERROR E0038 -} - -fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { - //~^ ERROR E0038 - loop {} -} - -fn takes_non_object_safe_box(obj: Box) { - //~^ ERROR E0038 -} - -fn return_non_object_safe_rc() -> std::rc::Rc { - //~^ ERROR E0038 - loop {} -} - -trait Trait {} - -impl Trait for dyn NonObjectSafe1 {} -//~^ ERROR E0038 - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr deleted file mode 100644 index fd5ed9c40f7..00000000000 --- a/tests/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ /dev/null @@ -1,83 +0,0 @@ -error[E0038]: the trait `NonObjectSafe1` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:39 - | -LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { - | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/feature-gate-object_safe_for_dispatch.rs:4:23 - | -LL | trait NonObjectSafe1: Sized {} - | -------------- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait cannot be made into an object... - -error[E0038]: the trait `NonObjectSafe2` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:45 - | -LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { - | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe2` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/feature-gate-object_safe_for_dispatch.rs:7:8 - | -LL | trait NonObjectSafe2 { - | -------------- this trait cannot be made into an object... -LL | fn static_fn() {} - | ^^^^^^^^^ ...because associated function `static_fn` has no `self` parameter -help: consider turning `static_fn` into a method by giving it a `&self` argument - | -LL | fn static_fn(&self) {} - | +++++ -help: alternatively, consider constraining `static_fn` so it does not apply to trait objects - | -LL | fn static_fn() where Self: Sized {} - | +++++++++++++++++ - -error[E0038]: the trait `NonObjectSafe3` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:39 - | -LL | fn takes_non_object_safe_box(obj: Box) { - | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/feature-gate-object_safe_for_dispatch.rs:11:8 - | -LL | trait NonObjectSafe3 { - | -------------- this trait cannot be made into an object... -LL | fn foo(&self); - | ^^^ ...because method `foo` has generic type parameters - = help: consider moving `foo` to another trait - -error[E0038]: the trait `NonObjectSafe4` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:47 - | -LL | fn return_non_object_safe_rc() -> std::rc::Rc { - | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/feature-gate-object_safe_for_dispatch.rs:15:22 - | -LL | trait NonObjectSafe4 { - | -------------- this trait cannot be made into an object... -LL | fn foo(&self, s: &Self); - | ^^^^^ ...because method `foo` references the `Self` type in this parameter - = help: consider moving `foo` to another trait - -error[E0038]: the trait `NonObjectSafe1` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16 - | -LL | impl Trait for dyn NonObjectSafe1 {} - | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/feature-gate-object_safe_for_dispatch.rs:4:23 - | -LL | trait NonObjectSafe1: Sized {} - | -------------- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait cannot be made into an object... - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..b4424f4750e --- /dev/null +++ b/tests/ui/kindck/kindck-inherited-copy-bound.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,40 @@ +error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied + --> $DIR/kindck-inherited-copy-bound.rs:21:16 + | +LL | take_param(&x); + | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>`, which is required by `Box<{integer}>: Foo` + | | + | required by a bound introduced by this call + | +note: required for `Box<{integer}>` to implement `Foo` + --> $DIR/kindck-inherited-copy-bound.rs:14:14 + | +LL | impl Foo for T { + | ---- ^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `take_param` + --> $DIR/kindck-inherited-copy-bound.rs:17:17 + | +LL | fn take_param(foo: &T) { } + | ^^^ required by this bound in `take_param` + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/kindck-inherited-copy-bound.rs:28:13 + | +LL | let z = &x as &dyn Foo; + | ^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/kindck-inherited-copy-bound.rs:10:13 + | +LL | trait Foo : Copy { + | --- ^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + = note: required for the cast from `&Box` to `&dyn Foo` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr deleted file mode 100644 index b4424f4750e..00000000000 --- a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,40 +0,0 @@ -error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied - --> $DIR/kindck-inherited-copy-bound.rs:21:16 - | -LL | take_param(&x); - | ---------- ^^ the trait `Copy` is not implemented for `Box<{integer}>`, which is required by `Box<{integer}>: Foo` - | | - | required by a bound introduced by this call - | -note: required for `Box<{integer}>` to implement `Foo` - --> $DIR/kindck-inherited-copy-bound.rs:14:14 - | -LL | impl Foo for T { - | ---- ^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `take_param` - --> $DIR/kindck-inherited-copy-bound.rs:17:17 - | -LL | fn take_param(foo: &T) { } - | ^^^ required by this bound in `take_param` - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/kindck-inherited-copy-bound.rs:28:13 - | -LL | let z = &x as &dyn Foo; - | ^^ `Foo` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/kindck-inherited-copy-bound.rs:10:13 - | -LL | trait Foo : Copy { - | --- ^^^^ ...because it requires `Self: Sized` - | | - | this trait cannot be made into an object... - = note: required for the cast from `&Box` to `&dyn Foo` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0038, E0277. -For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.rs b/tests/ui/kindck/kindck-inherited-copy-bound.rs index c785736f42e..dda95229ddf 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.rs +++ b/tests/ui/kindck/kindck-inherited-copy-bound.rs @@ -1,8 +1,8 @@ // Test that Copy bounds inherited by trait are checked. // -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] use std::any::Any; @@ -19,7 +19,7 @@ fn take_param(foo: &T) { } fn a() { let x: Box<_> = Box::new(3); take_param(&x); //[curr]~ ERROR E0277 - //[object_safe_for_dispatch]~^ ERROR E0277 + //[dyn_compatible_for_dispatch]~^ ERROR E0277 } fn b() { @@ -28,7 +28,7 @@ fn b() { let z = &x as &dyn Foo; //[curr]~^ ERROR E0038 //[curr]~| ERROR E0038 - //[object_safe_for_dispatch]~^^^ ERROR E0038 + //[dyn_compatible_for_dispatch]~^^^ ERROR E0038 } fn main() { } diff --git a/tests/ui/object-safety/object-safety-associated-consts.dyn_compatible_for_dispatch.stderr b/tests/ui/object-safety/object-safety-associated-consts.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..5b98cc35505 --- /dev/null +++ b/tests/ui/object-safety/object-safety-associated-consts.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,19 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-associated-consts.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-associated-consts.rs:9:11 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr deleted file mode 100644 index 5b98cc35505..00000000000 --- a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-associated-consts.rs:14:5 - | -LL | t - | ^ `Bar` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-associated-consts.rs:9:11 - | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | const X: usize; - | ^ ...because it contains this associated `const` - = help: consider moving `X` to another trait - = note: required for the cast from `&T` to `&dyn Bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-associated-consts.rs b/tests/ui/object-safety/object-safety-associated-consts.rs index a090214bbb4..fc7b372b782 100644 --- a/tests/ui/object-safety/object-safety-associated-consts.rs +++ b/tests/ui/object-safety/object-safety-associated-consts.rs @@ -1,9 +1,9 @@ // Check that we correctly prevent users from making trait objects // from traits with associated consts. // -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar { const X: usize; diff --git a/tests/ui/object-safety/object-safety-generics.dyn_compatible_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..4686b994b33 --- /dev/null +++ b/tests/ui/object-safety/object-safety-generics.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,35 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:20:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:27:5 + | +LL | t as &dyn Bar + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr deleted file mode 100644 index 4686b994b33..00000000000 --- a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:20:5 - | -LL | t - | ^ `Bar` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-generics.rs:10:8 - | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | fn bar(&self, t: T); - | ^^^ ...because method `bar` has generic type parameters - = help: consider moving `bar` to another trait - = note: required for the cast from `&T` to `&dyn Bar` - -error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-generics.rs:27:5 - | -LL | t as &dyn Bar - | ^ `Bar` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-generics.rs:10:8 - | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | fn bar(&self, t: T); - | ^^^ ...because method `bar` has generic type parameters - = help: consider moving `bar` to another trait - = note: required for the cast from `&T` to `&dyn Bar` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-generics.rs b/tests/ui/object-safety/object-safety-generics.rs index f005a689ac4..b51555aa500 100644 --- a/tests/ui/object-safety/object-safety-generics.rs +++ b/tests/ui/object-safety/object-safety-generics.rs @@ -1,9 +1,9 @@ // Check that we correctly prevent users from making trait objects // from traits with generic methods, unless `where Self : Sized` is // present. -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar { @@ -18,14 +18,14 @@ trait Quux { fn make_bar(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t - //[object_safe_for_dispatch]~^ ERROR E0038 + //[dyn_compatible_for_dispatch]~^ ERROR E0038 //[curr]~^^ ERROR E0038 } fn make_bar_explicit(t: &T) -> &dyn Bar { //[curr]~^ ERROR E0038 t as &dyn Bar - //[object_safe_for_dispatch]~^ ERROR E0038 + //[dyn_compatible_for_dispatch]~^ ERROR E0038 //[curr]~^^ ERROR E0038 //[curr]~| ERROR E0038 } diff --git a/tests/ui/object-safety/object-safety-mentions-Self.dyn_compatible_for_dispatch.stderr b/tests/ui/object-safety/object-safety-mentions-Self.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..d0efb9c587e --- /dev/null +++ b/tests/ui/object-safety/object-safety-mentions-Self.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,35 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:24:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-mentions-Self.rs:11:22 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, x: &Self); + | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait + = note: required for the cast from `&T` to `&dyn Bar` + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:30:5 + | +LL | t + | ^ `Baz` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-mentions-Self.rs:15:22 + | +LL | trait Baz { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> Self; + | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait + = note: required for the cast from `&T` to `&dyn Baz` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr deleted file mode 100644 index d0efb9c587e..00000000000 --- a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:24:5 - | -LL | t - | ^ `Bar` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-mentions-Self.rs:11:22 - | -LL | trait Bar { - | --- this trait cannot be made into an object... -LL | fn bar(&self, x: &Self); - | ^^^^^ ...because method `bar` references the `Self` type in this parameter - = help: consider moving `bar` to another trait - = note: required for the cast from `&T` to `&dyn Bar` - -error[E0038]: the trait `Baz` cannot be made into an object - --> $DIR/object-safety-mentions-Self.rs:30:5 - | -LL | t - | ^ `Baz` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-mentions-Self.rs:15:22 - | -LL | trait Baz { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> Self; - | ^^^^ ...because method `baz` references the `Self` type in its return type - = help: consider moving `baz` to another trait - = note: required for the cast from `&T` to `&dyn Baz` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-mentions-Self.rs b/tests/ui/object-safety/object-safety-mentions-Self.rs index 1311faf97bc..84c229e252d 100644 --- a/tests/ui/object-safety/object-safety-mentions-Self.rs +++ b/tests/ui/object-safety/object-safety-mentions-Self.rs @@ -2,9 +2,9 @@ // form traits that make use of `Self` in an argument or return // position, unless `where Self : Sized` is present.. // -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar { diff --git a/tests/ui/object-safety/object-safety-no-static.dyn_compatible_for_dispatch.stderr b/tests/ui/object-safety/object-safety-no-static.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..52f6865b6f3 --- /dev/null +++ b/tests/ui/object-safety/object-safety-no-static.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,27 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-no-static.rs:22:27 + | +LL | let b: Box = Box::new(Bar); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead + = note: required for the cast from `Box` to `Box` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr deleted file mode 100644 index 52f6865b6f3..00000000000 --- a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety-no-static.rs:22:27 - | -LL | let b: Box = Box::new(Bar); - | ^^^^^^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-no-static.rs:9:8 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn foo() {} - | ^^^ ...because associated function `foo` has no `self` parameter - = help: only type `Bar` implements the trait, consider using it directly instead - = note: required for the cast from `Box` to `Box` -help: consider turning `foo` into a method by giving it a `&self` argument - | -LL | fn foo(&self) {} - | +++++ -help: alternatively, consider constraining `foo` so it does not apply to trait objects - | -LL | fn foo() where Self: Sized {} - | +++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-no-static.rs b/tests/ui/object-safety/object-safety-no-static.rs index 4f4e03d734e..54af16fe18e 100644 --- a/tests/ui/object-safety/object-safety-no-static.rs +++ b/tests/ui/object-safety/object-safety-no-static.rs @@ -1,9 +1,9 @@ // Check that we correctly prevent users from making trait objects // from traits with static methods. // -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Foo { fn foo() {} diff --git a/tests/ui/object-safety/object-safety-sized-2.dyn_compatible_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized-2.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..99066c104b7 --- /dev/null +++ b/tests/ui/object-safety/object-safety-sized-2.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized-2.rs:16:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-sized-2.rs:9:18 + | +LL | trait Bar + | --- this trait cannot be made into an object... +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr deleted file mode 100644 index 99066c104b7..00000000000 --- a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized-2.rs:16:5 - | -LL | t - | ^ `Bar` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-sized-2.rs:9:18 - | -LL | trait Bar - | --- this trait cannot be made into an object... -LL | where Self : Sized - | ^^^^^ ...because it requires `Self: Sized` - = note: required for the cast from `&T` to `&dyn Bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-sized-2.rs b/tests/ui/object-safety/object-safety-sized-2.rs index cfb5d588d70..f5edd287f24 100644 --- a/tests/ui/object-safety/object-safety-sized-2.rs +++ b/tests/ui/object-safety/object-safety-sized-2.rs @@ -1,9 +1,9 @@ // Check that we correctly prevent users from making trait objects // from traits where `Self : Sized`. // -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar where Self : Sized diff --git a/tests/ui/object-safety/object-safety-sized.dyn_compatible_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..5ce713375a4 --- /dev/null +++ b/tests/ui/object-safety/object-safety-sized.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-sized.rs:8:12 + | +LL | trait Bar: Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + = note: required for the cast from `&T` to `&dyn Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr deleted file mode 100644 index 5ce713375a4..00000000000 --- a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/object-safety-sized.rs:14:5 - | -LL | t - | ^ `Bar` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety-sized.rs:8:12 - | -LL | trait Bar: Sized { - | --- ^^^^^ ...because it requires `Self: Sized` - | | - | this trait cannot be made into an object... - = note: required for the cast from `&T` to `&dyn Bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-sized.rs b/tests/ui/object-safety/object-safety-sized.rs index f4d6c945b33..4c4fe3f8f25 100644 --- a/tests/ui/object-safety/object-safety-sized.rs +++ b/tests/ui/object-safety/object-safety-sized.rs @@ -1,9 +1,9 @@ // Check that we correctly prevent users from making trait objects // from traits where `Self : Sized`. // -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] trait Bar: Sized { fn bar(&self, t: T); diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs new file mode 100644 index 00000000000..e9206789756 --- /dev/null +++ b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/downcast-unsafe-trait-objects.rs @@ -0,0 +1,23 @@ +// Check that we if we get ahold of an object unsafe trait +// object with auto traits and lifetimes, we can downcast it +// +//@ check-pass + +#![feature(dyn_compatible_for_dispatch)] + +trait Trait: Sized {} + +fn downcast_auto(t: &(dyn Trait + Send)) -> &dyn Trait { + t +} + +fn downcast_lifetime<'a, 'b, 't>(t: &'a (dyn Trait + 't)) + -> &'b (dyn Trait + 't) +where + 'a: 'b, + 't: 'a + 'b, +{ + t +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr new file mode 100644 index 00000000000..1489791b20d --- /dev/null +++ b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr @@ -0,0 +1,15 @@ +warning: methods `good_virt` and `good_indirect` are never used + --> $DIR/manual-self-impl-for-unsafe-obj.rs:23:8 + | +LL | trait Good { + | ---- methods in this trait +LL | fn good_virt(&self) -> char { + | ^^^^^^^^^ +... +LL | fn good_indirect(&self) -> char { + | ^^^^^^^^^^^^^ + | + = note: `#[warn(dead_code)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr new file mode 100644 index 00000000000..1489791b20d --- /dev/null +++ b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr @@ -0,0 +1,15 @@ +warning: methods `good_virt` and `good_indirect` are never used + --> $DIR/manual-self-impl-for-unsafe-obj.rs:23:8 + | +LL | trait Good { + | ---- methods in this trait +LL | fn good_virt(&self) -> char { + | ^^^^^^^^^ +... +LL | fn good_indirect(&self) -> char { + | ^^^^^^^^^^^^^ + | + = note: `#[warn(dead_code)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs new file mode 100644 index 00000000000..37e6f948ad1 --- /dev/null +++ b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/manual-self-impl-for-unsafe-obj.rs @@ -0,0 +1,69 @@ +// Check that we can manually implement an object-unsafe trait for its trait object. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ run-pass + +#![feature(dyn_compatible_for_dispatch)] + +trait Bad { + fn stat() -> char { + 'A' + } + fn virt(&self) -> char { + 'B' + } + fn indirect(&self) -> char { + Self::stat() + } +} + +trait Good { + fn good_virt(&self) -> char { //~ WARN methods `good_virt` and `good_indirect` are never used + panic!() + } + fn good_indirect(&self) -> char { + panic!() + } +} + +impl<'a> Bad for dyn Bad + 'a { + fn stat() -> char { + 'C' + } + fn virt(&self) -> char { + 'D' + } +} + +struct Struct {} + +impl Bad for Struct {} + +impl Good for Struct {} + +fn main() { + let s = Struct {}; + + let mut res = String::new(); + + // Directly call static. + res.push(Struct::stat()); // "A" + res.push(::stat()); // "AC" + + let good: &dyn Good = &s; + + // These look similar enough... + let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) }; + + // Call virtual. + res.push(s.virt()); // "ACB" + res.push(bad.virt()); // "ACBD" + + // Indirectly call static. + res.push(s.indirect()); // "ACBDA" + res.push(bad.indirect()); // "ACBDAC" + + assert_eq!(&res, "ACBDAC"); +} diff --git a/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs new file mode 100644 index 00000000000..c38928a9f44 --- /dev/null +++ b/tests/ui/rfcs/rfc-2027-dyn-compatible-for-dispatch/static-dispatch-unsafe-object.rs @@ -0,0 +1,37 @@ +// Check that we can statically dispatch methods for object +// unsafe trait objects, directly and indirectly +// +//@ check-pass + +#![feature(dyn_compatible_for_dispatch)] + +trait Statics { + fn plain() {} + fn generic() {} +} + +trait Trait: Sized {} + +impl<'a> Statics for dyn Trait + 'a {} + +fn static_poly() { + T::plain(); + T::generic::(); +} + +fn inferred_poly(t: &T) { + static_poly::(); + T::plain(); + T::generic::(); +} + +fn call(t: &dyn Trait) { + static_poly::(); + inferred_poly(t); +} + +fn main() { + static_poly::(); + ::plain(); + ::generic::() +} diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs deleted file mode 100644 index d4337dcb165..00000000000 --- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Check that we if we get ahold of an object unsafe trait -// object with auto traits and lifetimes, we can downcast it -// -//@ check-pass - -#![feature(object_safe_for_dispatch)] - -trait Trait: Sized {} - -fn downcast_auto(t: &(dyn Trait + Send)) -> &dyn Trait { - t -} - -fn downcast_lifetime<'a, 'b, 't>(t: &'a (dyn Trait + 't)) - -> &'b (dyn Trait + 't) -where - 'a: 'b, - 't: 'a + 'b, -{ - t -} - -fn main() {} diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr deleted file mode 100644 index 1489791b20d..00000000000 --- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: methods `good_virt` and `good_indirect` are never used - --> $DIR/manual-self-impl-for-unsafe-obj.rs:23:8 - | -LL | trait Good { - | ---- methods in this trait -LL | fn good_virt(&self) -> char { - | ^^^^^^^^^ -... -LL | fn good_indirect(&self) -> char { - | ^^^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr deleted file mode 100644 index 1489791b20d..00000000000 --- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: methods `good_virt` and `good_indirect` are never used - --> $DIR/manual-self-impl-for-unsafe-obj.rs:23:8 - | -LL | trait Good { - | ---- methods in this trait -LL | fn good_virt(&self) -> char { - | ^^^^^^^^^ -... -LL | fn good_indirect(&self) -> char { - | ^^^^^^^^^^^^^ - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs deleted file mode 100644 index a020d91fb14..00000000000 --- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Check that we can manually implement an object-unsafe trait for its trait object. - -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@ run-pass - -#![feature(object_safe_for_dispatch)] - -trait Bad { - fn stat() -> char { - 'A' - } - fn virt(&self) -> char { - 'B' - } - fn indirect(&self) -> char { - Self::stat() - } -} - -trait Good { - fn good_virt(&self) -> char { //~ WARN methods `good_virt` and `good_indirect` are never used - panic!() - } - fn good_indirect(&self) -> char { - panic!() - } -} - -impl<'a> Bad for dyn Bad + 'a { - fn stat() -> char { - 'C' - } - fn virt(&self) -> char { - 'D' - } -} - -struct Struct {} - -impl Bad for Struct {} - -impl Good for Struct {} - -fn main() { - let s = Struct {}; - - let mut res = String::new(); - - // Directly call static. - res.push(Struct::stat()); // "A" - res.push(::stat()); // "AC" - - let good: &dyn Good = &s; - - // These look similar enough... - let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) }; - - // Call virtual. - res.push(s.virt()); // "ACB" - res.push(bad.virt()); // "ACBD" - - // Indirectly call static. - res.push(s.indirect()); // "ACBDA" - res.push(bad.indirect()); // "ACBDAC" - - assert_eq!(&res, "ACBDAC"); -} diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs deleted file mode 100644 index cbf76a6830b..00000000000 --- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Check that we can statically dispatch methods for object -// unsafe trait objects, directly and indirectly -// -//@ check-pass - -#![feature(object_safe_for_dispatch)] - -trait Statics { - fn plain() {} - fn generic() {} -} - -trait Trait: Sized {} - -impl<'a> Statics for dyn Trait + 'a {} - -fn static_poly() { - T::plain(); - T::generic::(); -} - -fn inferred_poly(t: &T) { - static_poly::(); - T::plain(); - T::generic::(); -} - -fn call(t: &dyn Trait) { - static_poly::(); - inferred_poly(t); -} - -fn main() { - static_poly::(); - ::plain(); - ::generic::() -} diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.dyn_compatible_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.dyn_compatible_for_dispatch.stderr new file mode 100644 index 00000000000..fda07765c66 --- /dev/null +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.dyn_compatible_for_dispatch.stderr @@ -0,0 +1,22 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 + | +LL | fn foo(self: &Rc) -> usize; + | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` +... +LL | let x = Rc::new(5usize) as Rc; + | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/arbitrary-self-types-not-object-safe.rs:8:18 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo(self: &Rc) -> usize; + | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on + = help: only type `usize` implements the trait, consider using it directly instead + = note: required for the cast from `Rc` to `Rc` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr deleted file mode 100644 index fda07765c66..00000000000 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 - | -LL | fn foo(self: &Rc) -> usize; - | --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` -... -LL | let x = Rc::new(5usize) as Rc; - | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/arbitrary-self-types-not-object-safe.rs:8:18 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn foo(self: &Rc) -> usize; - | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - = help: only type `usize` implements the trait, consider using it directly instead - = note: required for the cast from `Rc` to `Rc` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.rs b/tests/ui/self/arbitrary-self-types-not-object-safe.rs index 0053eb5f739..940b2f1e8e2 100644 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.rs +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.rs @@ -1,6 +1,6 @@ -//@ revisions: curr object_safe_for_dispatch +//@ revisions: curr dyn_compatible_for_dispatch -#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![cfg_attr(dyn_compatible_for_dispatch, feature(dyn_compatible_for_dispatch))] use std::rc::Rc; @@ -33,7 +33,7 @@ fn make_foo() { let x = Rc::new(5usize) as Rc; //[curr]~^ ERROR E0038 //[curr]~| ERROR E0038 - //[object_safe_for_dispatch]~^^^ ERROR E0038 + //[dyn_compatible_for_dispatch]~^^^ ERROR E0038 } fn make_bar() { diff --git a/tests/ui/suggestions/issue-104328.rs b/tests/ui/suggestions/issue-104328.rs index c3707baf79f..2b0fbdb8d35 100644 --- a/tests/ui/suggestions/issue-104328.rs +++ b/tests/ui/suggestions/issue-104328.rs @@ -1,4 +1,4 @@ -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait Foo { fn f() {} diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.rs b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.rs index ffdb49a3be5..e32b04c4715 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.rs +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.rs @@ -1,7 +1,7 @@ // Check that we do not allow casts or coercions // to object unsafe trait objects inside a Box -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait Trait: Sized {} diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj.rs b/tests/ui/wf/wf-convert-unsafe-trait-obj.rs index 143b854ed6b..6f386352819 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj.rs +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj.rs @@ -1,7 +1,7 @@ // Check that we do not allow casts or coercions // to object unsafe trait objects by ref -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait Trait: Sized {} diff --git a/tests/ui/wf/wf-unsafe-trait-obj-match.rs b/tests/ui/wf/wf-unsafe-trait-obj-match.rs index c8731a8ecaf..07e90538b85 100644 --- a/tests/ui/wf/wf-unsafe-trait-obj-match.rs +++ b/tests/ui/wf/wf-unsafe-trait-obj-match.rs @@ -1,7 +1,7 @@ // Check that we do not allow coercions to object // unsafe trait objects in match arms -#![feature(object_safe_for_dispatch)] +#![feature(dyn_compatible_for_dispatch)] trait Trait: Sized {} -- cgit 1.4.1-3-g733a5 From 1edff466e19c4e2e2f8035de5a25d8a2dc2fef96 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 10 Oct 2024 11:46:11 +0200 Subject: Avoid redundant additions to PATH when linking --- compiler/rustc_session/src/session.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'compiler') diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index d67e69fe0fb..27879d817b2 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -454,6 +454,8 @@ impl Session { let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_triple()); let fallback_sysroot_paths = filesearch::sysroot_candidates() .into_iter() + // Ignore sysroot candidate if it was the same as the sysroot path we just used. + .filter(|sysroot| *sysroot != self.sysroot) .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_triple())); let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths); -- cgit 1.4.1-3-g733a5 From 335f67b6527cbeb576151dab1dadec161eaede45 Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Tue, 3 Sep 2024 13:51:54 +0100 Subject: rustc_target: Add sme-b16b16 as an explicit aarch64 target feature LLVM 20 split out what used to be called b16b16 and correspond to aarch64 FEAT_SVE_B16B16 into sve-b16b16 and sme-b16b16. Add sme-b16b16 as an explicit feature and update the codegen accordingly. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 4 +++- compiler/rustc_target/src/target_features.rs | 4 +++- library/std/tests/run-time-detect.rs | 1 + tests/ui/check-cfg/mix.stderr | 2 +- tests/ui/check-cfg/well-known-values.stderr | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) (limited to 'compiler') diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index bd847cd0068..8290e1a9544 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -247,7 +247,9 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("perfmon")), ("aarch64", "paca") => Some(LLVMFeature::new("pauth")), ("aarch64", "pacg") => Some(LLVMFeature::new("pauth")), - ("aarch64", "sve-b16b16") => Some(LLVMFeature::new("b16b16")), + // Before LLVM 20 those two features were packaged together as b16b16 + ("aarch64", "sve-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")), + ("aarch64", "sme-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")), ("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")), // Rust ties fp and neon together. ("aarch64", "neon") => { diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 0a98b363b1a..e92366d5c5c 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -191,6 +191,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("sm4", Stable, &["neon"]), // FEAT_SME ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]), + // FEAT_SME_B16B16 + ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]), // FEAT_SME_F16F16 ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]), // FEAT_SME_F64F64 @@ -227,7 +229,7 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // // "For backwards compatibility, Neon and VFP are required in the latest architectures." ("sve", Stable, &["neon"]), - // FEAT_SVE_B16B16 (SVE or SME Instructions) + // FEAT_SVE_B16B16 (SVE or SME Z-targeting instructions) ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]), // FEAT_SVE2 ("sve2", Stable, &["sve"]), diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index dcd5cd7f6b9..dd14c0266aa 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -82,6 +82,7 @@ fn aarch64_linux() { println!("sha2: {}", is_aarch64_feature_detected!("sha2")); println!("sha3: {}", is_aarch64_feature_detected!("sha3")); println!("sm4: {}", is_aarch64_feature_detected!("sm4")); + println!("sme-b16b16: {}", is_aarch64_feature_detected!("sme-b16b16")); println!("sme-f16f16: {}", is_aarch64_feature_detected!("sme-f16f16")); println!("sme-f64f64: {}", is_aarch64_feature_detected!("sme-f64f64")); println!("sme-f8f16: {}", is_aarch64_feature_detected!("sme-f8f16")); diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 7726c2d52f5..c21016e9290 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra` LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 244 more + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 245 more = note: see for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index c6d403104ea..da790bbd528 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -174,7 +174,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `partword-atomics`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `quadword-atomics`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zaamo`, `zabha`, `zalrsc`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `partword-atomics`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `quadword-atomics`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-b16b16`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zaamo`, `zabha`, `zalrsc`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` -- cgit 1.4.1-3-g733a5 From b7297ac4407e25f7872cd061246196cd4c8b485b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Sep 2024 13:08:48 -0400 Subject: Add gate for precise capturing in traits --- compiler/rustc_ast_lowering/src/lib.rs | 19 ++++++++++++++----- compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + .../feature-gate-precise_capturing_in_traits.rs | 6 ++++++ .../feature-gate-precise_capturing_in_traits.stderr | 13 +++++++++++++ .../precise-capturing/forgot-to-capture-type.stderr | 3 +++ .../precise-capturing/redundant.rpitit.stderr | 6 ++++++ .../rpitit-captures-more-method-lifetimes.stderr | 3 +++ tests/ui/impl-trait/precise-capturing/rpitit.stderr | 3 +++ .../impl-trait/precise-capturing/self-capture.stderr | 3 +++ 10 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.rs create mode 100644 tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.stderr (limited to 'compiler') diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b26797f4203..35af4d63cc7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1573,11 +1573,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Feature gate for RPITIT + use<..> match origin { rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => { - if let Some(span) = bounds.iter().find_map(|bound| match *bound { - ast::GenericBound::Use(_, span) => Some(span), - _ => None, - }) { - self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnRpitit { span }); + if !self.tcx.features().precise_capturing_in_traits + && let Some(span) = bounds.iter().find_map(|bound| match *bound { + ast::GenericBound::Use(_, span) => Some(span), + _ => None, + }) + { + let mut diag = + self.tcx.dcx().create_err(errors::NoPreciseCapturesOnRpitit { span }); + add_feature_diagnostics( + &mut diag, + self.tcx.sess, + sym::precise_capturing_in_traits, + ); + diag.emit(); } } _ => {} diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 380e36fe405..19a6960cf4d 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -565,6 +565,8 @@ declare_features! ( (incomplete, pin_ergonomics, "CURRENT_RUSTC_VERSION", Some(130494)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "1.79.0", Some(121618)), + /// Allows `use<..>` precise capturign on impl Trait in traits. + (unstable, precise_capturing_in_traits, "CURRENT_RUSTC_VERSION", Some(130044)), /// Allows macro attributes on expressions, statements and non-inline modules. (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1527600e764..683f59a8999 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1479,6 +1479,7 @@ symbols! { powif64, pre_dash_lto: "pre-lto", precise_capturing, + precise_capturing_in_traits, precise_pointer_size_matching, pref_align_of, prefetch_read_data, diff --git a/tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.rs b/tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.rs new file mode 100644 index 00000000000..308b41dfc68 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.rs @@ -0,0 +1,6 @@ +trait Foo { + fn test() -> impl Sized + use; + //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.stderr b/tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.stderr new file mode 100644 index 00000000000..b2c6bf61124 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-precise_capturing_in_traits.stderr @@ -0,0 +1,13 @@ +error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + --> $DIR/feature-gate-precise_capturing_in_traits.rs:2:31 + | +LL | fn test() -> impl Sized + use; + | ^^^^^^^^^ + | + = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + = note: see issue #130044 for more information + = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr index d9be9d543e4..23d6a3bd11e 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr @@ -5,6 +5,9 @@ LL | fn bar() -> impl Sized + use<>; | ^^^^^ | = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + = note: see issue #130044 for more information + = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `impl Trait` must mention all type parameters in scope in `use<...>` --> $DIR/forgot-to-capture-type.rs:1:23 diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr b/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr index 213888356e5..27f8ff92d3e 100644 --- a/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr +++ b/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr @@ -5,6 +5,9 @@ LL | fn in_trait() -> impl Sized + use<'a, Self>; | ^^^^^^^^^^^^^ | = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + = note: see issue #130044 for more information + = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits --> $DIR/redundant.rs:21:35 @@ -13,6 +16,9 @@ LL | fn in_trait() -> impl Sized + use<'a> {} | ^^^^^^^ | = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + = note: see issue #130044 for more information + = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr index b390a23eef4..ffd9646a403 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr @@ -5,6 +5,9 @@ LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use; | ^^^^^^^^^ | = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + = note: see issue #130044 for more information + = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: return type captures more lifetimes than trait definition --> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40 diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.stderr b/tests/ui/impl-trait/precise-capturing/rpitit.stderr index 5a120df9f04..c162875f327 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit.stderr @@ -5,6 +5,9 @@ LL | fn hello() -> impl PartialEq + use; | ^^^^^^^^^ | = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + = note: see issue #130044 for more information + = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list --> $DIR/rpitit.rs:9:19 diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.stderr b/tests/ui/impl-trait/precise-capturing/self-capture.stderr index c1974600f30..45ebc429d88 100644 --- a/tests/ui/impl-trait/precise-capturing/self-capture.stderr +++ b/tests/ui/impl-trait/precise-capturing/self-capture.stderr @@ -5,6 +5,9 @@ LL | fn bar<'a>() -> impl Sized + use; | ^^^^^^^^^ | = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope + = note: see issue #130044 for more information + = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 1 previous error -- cgit 1.4.1-3-g733a5 From a7dc98733da8b84cfc21a538541a41803c4529a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Sep 2024 13:41:13 -0400 Subject: Add variances to RPITITs --- compiler/rustc_hir_analysis/src/variance/mod.rs | 49 ++++++++++++++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 5 +- compiler/rustc_middle/src/ty/context.rs | 4 ++ compiler/rustc_type_ir/src/interner.rs | 2 + compiler/rustc_type_ir/src/relate.rs | 10 ++++ tests/ui/impl-trait/in-trait/variance.rs | 23 +++++---- tests/ui/impl-trait/in-trait/variance.stderr | 34 +++++++++---- .../precise-capturing/forgot-to-capture-type.rs | 3 +- .../forgot-to-capture-type.stderr | 17 ++----- .../precise-capturing/redundant.normal.stderr | 20 -------- .../precise-capturing/redundant.rpitit.stderr | 24 --------- tests/ui/impl-trait/precise-capturing/redundant.rs | 15 +++--- .../impl-trait/precise-capturing/redundant.stderr | 36 +++++++++++++ .../rpitit-captures-more-method-lifetimes.rs | 5 +- .../rpitit-captures-more-method-lifetimes.stderr | 23 +++------ .../rpitit-impl-captures-too-much.rs | 14 +++++ .../rpitit-impl-captures-too-much.stderr | 17 +++++++ tests/ui/impl-trait/precise-capturing/rpitit.rs | 31 +++++++++--- .../ui/impl-trait/precise-capturing/rpitit.stderr | 59 ++++++++++------------ .../impl-trait/precise-capturing/self-capture.rs | 5 +- .../precise-capturing/self-capture.stderr | 13 ----- 21 files changed, 241 insertions(+), 168 deletions(-) delete mode 100644 tests/ui/impl-trait/precise-capturing/redundant.normal.stderr delete mode 100644 tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/redundant.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.rs create mode 100644 tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr delete mode 100644 tests/ui/impl-trait/precise-capturing/self-capture.stderr (limited to 'compiler') diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 12bb9a3f9e0..02cfb57b836 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -5,6 +5,7 @@ use itertools::Itertools; use rustc_arena::DroplessArena; +use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; @@ -63,8 +64,29 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] { let crate_map = tcx.crate_variances(()); return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]); } + DefKind::AssocTy => match tcx.opt_rpitit_info(item_def_id.to_def_id()) { + Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { + return variance_of_opaque( + tcx, + opaque_def_id.expect_local(), + ForceCaptureTraitArgs::Yes, + ); + } + None | Some(ty::ImplTraitInTraitData::Impl { .. }) => {} + }, DefKind::OpaqueTy => { - return variance_of_opaque(tcx, item_def_id); + let force_capture_trait_args = if let hir::OpaqueTyOrigin::FnReturn { + parent: _, + in_trait_or_impl: Some(hir::RpitContext::Trait), + } = + tcx.hir_node_by_def_id(item_def_id).expect_opaque_ty().origin + { + ForceCaptureTraitArgs::Yes + } else { + ForceCaptureTraitArgs::No + }; + + return variance_of_opaque(tcx, item_def_id, force_capture_trait_args); } _ => {} } @@ -73,8 +95,18 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] { span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item"); } +#[derive(Debug, Copy, Clone)] +enum ForceCaptureTraitArgs { + Yes, + No, +} + #[instrument(level = "trace", skip(tcx), ret)] -fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] { +fn variance_of_opaque( + tcx: TyCtxt<'_>, + item_def_id: LocalDefId, + force_capture_trait_args: ForceCaptureTraitArgs, +) -> &[ty::Variance] { let generics = tcx.generics_of(item_def_id); // Opaque types may only use regions that are bound. So for @@ -115,9 +147,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc #[instrument(level = "trace", skip(self), ret)] fn visit_ty(&mut self, t: Ty<'tcx>) { match t.kind() { - ty::Alias(_, ty::AliasTy { def_id, args, .. }) - if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) => - { + ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { self.visit_opaque(*def_id, args); } _ => t.super_visit_with(self), @@ -135,6 +165,15 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc let mut generics = generics; while let Some(def_id) = generics.parent { generics = tcx.generics_of(def_id); + + // Don't mark trait params generic if we're in an RPITIT. + if matches!(force_capture_trait_args, ForceCaptureTraitArgs::Yes) + && generics.parent.is_none() + { + debug_assert_eq!(tcx.def_kind(def_id), DefKind::Trait); + break; + } + for param in &generics.own_params { match param.kind { ty::GenericParamDefKind::Lifetime => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 610c682d3a4..afe03531861 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1100,9 +1100,12 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def | DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn => true, + DefKind::AssocTy => { + // Only encode variances for RPITITs (for traits) + matches!(tcx.opt_rpitit_info(def_id), Some(ty::ImplTraitInTraitData::Trait { .. })) + } DefKind::Mod | DefKind::Field - | DefKind::AssocTy | DefKind::AssocConst | DefKind::TyParam | DefKind::ConstParam diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 90265f67bc1..590e1d336f3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -539,6 +539,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.trait_def(trait_def_id).implement_via_object } + fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { + self.is_impl_trait_in_trait(def_id) + } + fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed { self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string()) } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index a72e7b482a6..f06017d7e5c 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -261,6 +261,8 @@ pub trait Interner: fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool; + fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool; + fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed; fn is_general_coroutine(self, coroutine_def_id: Self::DefId) -> bool; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 1302906adab..e1f3e493e36 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -254,6 +254,16 @@ impl Relate for ty::AliasTy { b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, + ty::Projection if relation.cx().is_impl_trait_in_trait(a.def_id) => { + relate_args_with_variances( + relation, + a.def_id, + relation.cx().variances_of(a.def_id), + a.args, + b.args, + false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle + )? + } ty::Projection | ty::Weak | ty::Inherent => { relate_args_invariantly(relation, a.args, b.args)? } diff --git a/tests/ui/impl-trait/in-trait/variance.rs b/tests/ui/impl-trait/in-trait/variance.rs index 0ac44bf7546..19905c608e3 100644 --- a/tests/ui/impl-trait/in-trait/variance.rs +++ b/tests/ui/impl-trait/in-trait/variance.rs @@ -1,22 +1,25 @@ -#![feature(rustc_attrs)] +#![feature(rustc_attrs, precise_capturing_in_traits)] #![allow(internal_features)] #![rustc_variance_of_opaques] -trait Captures<'a> {} -impl Captures<'_> for T {} - trait Foo<'i> { fn implicit_capture_early<'a: 'a>() -> impl Sized {} - //~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o] + //~^ [Self: o, 'i: o, 'a: *, 'a: o, 'i: o] + + fn explicit_capture_early<'a: 'a>() -> impl Sized + use<'i, 'a, Self> {} + //~^ [Self: o, 'i: o, 'a: *, 'i: o, 'a: o] - fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} - //~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o] + fn not_captured_early<'a: 'a>() -> impl Sized + use<'i, Self> {} + //~^ [Self: o, 'i: o, 'a: *, 'i: o] fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} - //~^ [Self: o, 'i: *, 'a: o, 'i: o] + //~^ [Self: o, 'i: o, 'a: o, 'i: o] + + fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + use<'i, 'a, Self> {} + //~^ [Self: o, 'i: o, 'i: o, 'a: o] - fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} - //~^ [Self: o, 'i: *, 'a: o, 'i: o] + fn not_cpatured_late<'a>(_: &'a ()) -> impl Sized + use<'i, Self> {} + //~^ [Self: o, 'i: o, 'i: o] } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/variance.stderr b/tests/ui/impl-trait/in-trait/variance.stderr index 54e0afbaa95..f65174e1c35 100644 --- a/tests/ui/impl-trait/in-trait/variance.stderr +++ b/tests/ui/impl-trait/in-trait/variance.stderr @@ -1,26 +1,38 @@ -error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o] - --> $DIR/variance.rs:9:44 +error: [Self: o, 'i: o, 'a: *, 'a: o, 'i: o] + --> $DIR/variance.rs:6:44 | LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ -error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o] - --> $DIR/variance.rs:12:44 +error: [Self: o, 'i: o, 'a: *, 'i: o, 'a: o] + --> $DIR/variance.rs:9:44 + | +LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + use<'i, 'a, Self> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: [Self: o, 'i: o, 'a: *, 'i: o] + --> $DIR/variance.rs:12:40 | -LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn not_captured_early<'a: 'a>() -> impl Sized + use<'i, Self> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: [Self: o, 'i: *, 'a: o, 'i: o] +error: [Self: o, 'i: o, 'a: o, 'i: o] --> $DIR/variance.rs:15:48 | LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ -error: [Self: o, 'i: *, 'a: o, 'i: o] +error: [Self: o, 'i: o, 'i: o, 'a: o] --> $DIR/variance.rs:18:48 | -LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + use<'i, 'a, Self> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: [Self: o, 'i: o, 'i: o] + --> $DIR/variance.rs:21:44 + | +LL | fn not_cpatured_late<'a>(_: &'a ()) -> impl Sized + use<'i, Self> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs index 9d68819f657..6c2477c9744 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs @@ -1,10 +1,11 @@ +#![feature(precise_capturing_in_traits)] + fn type_param() -> impl Sized + use<> {} //~^ ERROR `impl Trait` must mention all type parameters in scope trait Foo { fn bar() -> impl Sized + use<>; //~^ ERROR `impl Trait` must mention the `Self` type of the trait - //~| ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr index 23d6a3bd11e..93b44a0c18c 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr @@ -1,16 +1,5 @@ -error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits - --> $DIR/forgot-to-capture-type.rs:5:30 - | -LL | fn bar() -> impl Sized + use<>; - | ^^^^^ - | - = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope - = note: see issue #130044 for more information - = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error: `impl Trait` must mention all type parameters in scope in `use<...>` - --> $DIR/forgot-to-capture-type.rs:1:23 + --> $DIR/forgot-to-capture-type.rs:3:23 | LL | fn type_param() -> impl Sized + use<> {} | - ^^^^^^^^^^^^^^^^^^ @@ -20,7 +9,7 @@ LL | fn type_param() -> impl Sized + use<> {} = note: currently, all type parameters are required to be mentioned in the precise captures list error: `impl Trait` must mention the `Self` type of the trait in `use<...>` - --> $DIR/forgot-to-capture-type.rs:5:17 + --> $DIR/forgot-to-capture-type.rs:7:17 | LL | trait Foo { | --------- `Self` type parameter is implicitly captured by this `impl Trait` @@ -29,5 +18,5 @@ LL | fn bar() -> impl Sized + use<>; | = note: currently, all type parameters are required to be mentioned in the precise captures list -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr b/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr deleted file mode 100644 index d1bcbaa33ae..00000000000 --- a/tests/ui/impl-trait/precise-capturing/redundant.normal.stderr +++ /dev/null @@ -1,20 +0,0 @@ -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant - --> $DIR/redundant.rs:5:19 - | -LL | fn hello<'a>() -> impl Sized + use<'a> {} - | ^^^^^^^^^^^^^------- - | | - | help: remove the `use<...>` syntax - | - = note: `#[warn(impl_trait_redundant_captures)]` on by default - -warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant - --> $DIR/redundant.rs:10:27 - | -LL | fn inherent(&self) -> impl Sized + use<'_> {} - | ^^^^^^^^^^^^^------- - | | - | help: remove the `use<...>` syntax - -warning: 2 warnings emitted - diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr b/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr deleted file mode 100644 index 27f8ff92d3e..00000000000 --- a/tests/ui/impl-trait/precise-capturing/redundant.rpitit.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits - --> $DIR/redundant.rs:16:35 - | -LL | fn in_trait() -> impl Sized + use<'a, Self>; - | ^^^^^^^^^^^^^ - | - = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope - = note: see issue #130044 for more information - = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits - --> $DIR/redundant.rs:21:35 - | -LL | fn in_trait() -> impl Sized + use<'a> {} - | ^^^^^^^ - | - = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope - = note: see issue #130044 for more information - = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors - diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs index 4a08ffb61be..e19d935f5b0 100644 --- a/tests/ui/impl-trait/precise-capturing/redundant.rs +++ b/tests/ui/impl-trait/precise-capturing/redundant.rs @@ -1,25 +1,24 @@ //@ compile-flags: -Zunstable-options --edition=2024 -//@ revisions: normal rpitit -//@[normal] check-pass +//@ check-pass + +#![feature(precise_capturing_in_traits)] fn hello<'a>() -> impl Sized + use<'a> {} -//[normal]~^ WARN all possible in-scope parameters are already captured +//~^ WARN all possible in-scope parameters are already captured struct Inherent; impl Inherent { fn inherent(&self) -> impl Sized + use<'_> {} - //[normal]~^ WARN all possible in-scope parameters are already captured + //~^ WARN all possible in-scope parameters are already captured } -#[cfg(rpitit)] trait Test<'a> { fn in_trait() -> impl Sized + use<'a, Self>; - //[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + //~^ WARN all possible in-scope parameters are already captured } -#[cfg(rpitit)] impl<'a> Test<'a> for () { fn in_trait() -> impl Sized + use<'a> {} - //[rpitit]~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits + //~^ WARN all possible in-scope parameters are already captured } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr new file mode 100644 index 00000000000..274d9d2375f --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/redundant.stderr @@ -0,0 +1,36 @@ +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:6:19 + | +LL | fn hello<'a>() -> impl Sized + use<'a> {} + | ^^^^^^^^^^^^^------- + | | + | help: remove the `use<...>` syntax + | + = note: `#[warn(impl_trait_redundant_captures)]` on by default + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:11:27 + | +LL | fn inherent(&self) -> impl Sized + use<'_> {} + | ^^^^^^^^^^^^^------- + | | + | help: remove the `use<...>` syntax + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:16:22 + | +LL | fn in_trait() -> impl Sized + use<'a, Self>; + | ^^^^^^^^^^^^^------------- + | | + | help: remove the `use<...>` syntax + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:20:22 + | +LL | fn in_trait() -> impl Sized + use<'a> {} + | ^^^^^^^^^^^^^------- + | | + | help: remove the `use<...>` syntax + +warning: 4 warnings emitted + diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs index 062351afecb..b39c1408c05 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs +++ b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs @@ -2,13 +2,14 @@ // trait definition, which is not allowed. Due to the default lifetime capture // rules of RPITITs, this is only doable if we use precise capturing. +#![feature(precise_capturing_in_traits)] + pub trait Foo { fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use; - //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits } impl Foo for () { - fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {} + fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {} //~^ ERROR return type captures more lifetimes than trait definition } diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr index ffd9646a403..45f755d3cc1 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.stderr @@ -1,28 +1,17 @@ -error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits - --> $DIR/rpitit-captures-more-method-lifetimes.rs:6:53 - | -LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use; - | ^^^^^^^^^ - | - = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope - = note: see issue #130044 for more information - = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error: return type captures more lifetimes than trait definition - --> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40 + --> $DIR/rpitit-captures-more-method-lifetimes.rs:12:40 | -LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {} - | --- ^^^^^^^^^^^^^^^^ +LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {} + | --- ^^^^^^^^^^^^^^^^^^^^^ | | | this lifetime was captured | note: hidden type must only reference lifetimes captured by this impl trait - --> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40 + --> $DIR/rpitit-captures-more-method-lifetimes.rs:8:40 | LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use; | ^^^^^^^^^^^^^^^^^^^^^^ - = note: hidden type inferred to be `impl Sized + 'im` + = note: hidden type inferred to be `impl Sized` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.rs b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.rs new file mode 100644 index 00000000000..b16b0522d6e --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.rs @@ -0,0 +1,14 @@ +#![feature(precise_capturing_in_traits)] + +struct Invariant<'a>(&'a mut &'a mut ()); + +trait Trait { + fn hello(self_: Invariant<'_>) -> impl Sized + use; +} + +impl Trait for () { + fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {} + //~^ ERROR return type captures more lifetimes than trait definition +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr new file mode 100644 index 00000000000..e1856b92910 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.stderr @@ -0,0 +1,17 @@ +error: return type captures more lifetimes than trait definition + --> $DIR/rpitit-impl-captures-too-much.rs:10:39 + | +LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {} + | -- ^^^^^^^^^^^^^^^^^^^^ + | | + | this lifetime was captured + | +note: hidden type must only reference lifetimes captured by this impl trait + --> $DIR/rpitit-impl-captures-too-much.rs:6:39 + | +LL | fn hello(self_: Invariant<'_>) -> impl Sized + use; + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: hidden type inferred to be `impl Sized` + +error: aborting due to 1 previous error + diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.rs b/tests/ui/impl-trait/precise-capturing/rpitit.rs index feeeb1461e8..3f887e8e47f 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit.rs +++ b/tests/ui/impl-trait/precise-capturing/rpitit.rs @@ -1,19 +1,34 @@ -//@ known-bug: unknown - // RPITITs don't have variances in their GATs, so they always relate invariantly // and act as if they capture all their args. // To fix this soundly, we need to make sure that all the trait header args // remain captured, since they affect trait selection. -trait Foo<'a> { - fn hello() -> impl PartialEq + use; +#![feature(precise_capturing_in_traits)] + +fn eq_types(_: T, _: T) {} + +trait TraitLt<'a: 'a> { + fn hello() -> impl Sized + use; + //~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list +} +fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () { + eq_types( + //~^ ERROR lifetime may not live long enough + //~| ERROR lifetime may not live long enough + >::hello(), + >::hello(), + ); } -fn test<'a, 'b, T: for<'r> Foo<'r>>() { - PartialEq::eq( - &>::hello(), - &>::hello(), +trait MethodLt { + fn hello<'a: 'a>() -> impl Sized + use; +} +fn method_lt<'a, 'b, T: MethodLt> () { + eq_types( + T::hello::<'a>(), + T::hello::<'b>(), ); + // Good! } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.stderr b/tests/ui/impl-trait/precise-capturing/rpitit.stderr index c162875f327..8c219bb04a2 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit.stderr @@ -1,47 +1,40 @@ -error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits - --> $DIR/rpitit.rs:9:36 - | -LL | fn hello() -> impl PartialEq + use; - | ^^^^^^^^^ - | - = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope - = note: see issue #130044 for more information - = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list - --> $DIR/rpitit.rs:9:19 + --> $DIR/rpitit.rs:11:19 | -LL | trait Foo<'a> { - | -- this lifetime parameter is captured -LL | fn hello() -> impl PartialEq + use; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait` +LL | trait TraitLt<'a: 'a> { + | -- this lifetime parameter is captured +LL | fn hello() -> impl Sized + use; + | ^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait` error: lifetime may not live long enough - --> $DIR/rpitit.rs:13:5 + --> $DIR/rpitit.rs:15:5 | -LL | fn test<'a, 'b, T: for<'r> Foo<'r>>() { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | / PartialEq::eq( -LL | | &>::hello(), -LL | | &>::hello(), +LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | / eq_types( +LL | | +LL | | +LL | | >::hello(), +LL | | >::hello(), LL | | ); | |_____^ argument requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` error: lifetime may not live long enough - --> $DIR/rpitit.rs:13:5 + --> $DIR/rpitit.rs:15:5 | -LL | fn test<'a, 'b, T: for<'r> Foo<'r>>() { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | / PartialEq::eq( -LL | | &>::hello(), -LL | | &>::hello(), +LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | / eq_types( +LL | | +LL | | +LL | | >::hello(), +LL | | >::hello(), LL | | ); | |_____^ argument requires that `'b` must outlive `'a` | @@ -49,5 +42,5 @@ LL | | ); help: `'a` and `'b` must be the same: replace one with the other -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.rs b/tests/ui/impl-trait/precise-capturing/self-capture.rs index a61a7f06edc..15985da50b5 100644 --- a/tests/ui/impl-trait/precise-capturing/self-capture.rs +++ b/tests/ui/impl-trait/precise-capturing/self-capture.rs @@ -1,6 +1,9 @@ +//@ check-pass + +#![feature(precise_capturing_in_traits)] + trait Foo { fn bar<'a>() -> impl Sized + use; - //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.stderr b/tests/ui/impl-trait/precise-capturing/self-capture.stderr deleted file mode 100644 index 45ebc429d88..00000000000 --- a/tests/ui/impl-trait/precise-capturing/self-capture.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits - --> $DIR/self-capture.rs:2:34 - | -LL | fn bar<'a>() -> impl Sized + use; - | ^^^^^^^^^ - | - = note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope - = note: see issue #130044 for more information - = help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -- cgit 1.4.1-3-g733a5 From 36076ecdc726c4e1104e70df2d142f39501a4f48 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Sep 2024 13:49:32 -0400 Subject: Clarify implicit captures for RPITIT --- compiler/rustc_hir_analysis/messages.ftl | 3 +++ compiler/rustc_hir_analysis/src/check/check.rs | 25 ++++++++++++++-------- .../src/errors/precise_captures.rs | 9 ++++++++ .../ui/impl-trait/precise-capturing/rpitit.stderr | 4 ++-- 4 files changed, 30 insertions(+), 11 deletions(-) (limited to 'compiler') diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index c73826c489f..a80dc87c622 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -259,6 +259,9 @@ hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetim hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl .label = type parameter declared here +hir_analysis_lifetime_implicitly_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + .param_label = all lifetime parameters originating from a trait are captured implicitly + hir_analysis_lifetime_must_be_first = lifetime parameter `{$name}` must be listed before non-lifetime parameters .label = move the lifetime before this parameter diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index eb62ff86c71..d0063b449f8 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -589,15 +589,22 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe param_span: tcx.def_span(def_id), }); } else { - // If the `use_span` is actually just the param itself, then we must - // have not duplicated the lifetime but captured the original. - // The "effective" `use_span` will be the span of the opaque itself, - // and the param span will be the def span of the param. - tcx.dcx().emit_err(errors::LifetimeNotCaptured { - opaque_span, - use_span: opaque_span, - param_span: use_span, - }); + if tcx.def_kind(tcx.parent(param.def_id)) == DefKind::Trait { + tcx.dcx().emit_err(errors::LifetimeImplicitlyCaptured { + opaque_span, + param_span: tcx.def_span(param.def_id), + }); + } else { + // If the `use_span` is actually just the param itself, then we must + // have not duplicated the lifetime but captured the original. + // The "effective" `use_span` will be the span of the opaque itself, + // and the param span will be the def span of the param. + tcx.dcx().emit_err(errors::LifetimeNotCaptured { + opaque_span, + use_span: opaque_span, + param_span: use_span, + }); + } } continue; } diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs index b6cffb90805..8a83866b7fa 100644 --- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -34,6 +34,15 @@ pub(crate) struct LifetimeNotCaptured { pub opaque_span: Span, } +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetime_implicitly_captured)] +pub(crate) struct LifetimeImplicitlyCaptured { + #[primary_span] + pub opaque_span: Span, + #[label(hir_analysis_param_label)] + pub param_span: Span, +} + #[derive(Diagnostic)] #[diag(hir_analysis_bad_precise_capture)] pub(crate) struct BadPreciseCapture { diff --git a/tests/ui/impl-trait/precise-capturing/rpitit.stderr b/tests/ui/impl-trait/precise-capturing/rpitit.stderr index 8c219bb04a2..498eae54a1c 100644 --- a/tests/ui/impl-trait/precise-capturing/rpitit.stderr +++ b/tests/ui/impl-trait/precise-capturing/rpitit.stderr @@ -2,9 +2,9 @@ error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use --> $DIR/rpitit.rs:11:19 | LL | trait TraitLt<'a: 'a> { - | -- this lifetime parameter is captured + | -- all lifetime parameters originating from a trait are captured implicitly LL | fn hello() -> impl Sized + use; - | ^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait` + | ^^^^^^^^^^^^^^^^^^^^^^ error: lifetime may not live long enough --> $DIR/rpitit.rs:15:5 -- cgit 1.4.1-3-g733a5 From 322c4bdac595e7689dcf08b847d0bd4d82a4bad9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 29 Sep 2024 13:49:53 -0400 Subject: Don't fire refinement lint if there are errors --- compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'compiler') diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 80334c6efe7..2d6b9813271 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -64,6 +64,10 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( return; }; + if hidden_tys.items().any(|(_, &ty)| ty.skip_binder().references_error()) { + return; + } + let mut collector = ImplTraitInTraitCollector { tcx, types: FxIndexSet::default() }; trait_m_sig.visit_with(&mut collector); -- cgit 1.4.1-3-g733a5