Auto merge of #131158 - matthiaskrgr:rollup-3x2vado, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #130863 (Relax a debug assertion for dyn principal *equality* in codegen)
 - #131016 (Apple: Do not specify an SDK version in `rlib` object files)
 - #131140 (Handle `rustc_hir_analysis` cases of `potential_query_instability` lint)
 - #131141 (mpmc doctest: make sure main thread waits for child threads)
 - #131150 (only query `params_in_repr` if def kind is adt)
 - #131151 (Replace zero-width whitespace with a visible `\` in the PR template)
 - #131152 (Improve const traits diagnostics for new desugaring)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-10-02 16:24:05 +00:00
commit 5384697e9e
50 changed files with 538 additions and 279 deletions

View File

@ -7,6 +7,6 @@ tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
r\? <reviewer name> (with the `\` removed)
-->
<!-- homu-ignore:end -->

View File

@ -3451,6 +3451,7 @@ dependencies = [
"rustc_span",
"rustc_symbol_mangling",
"rustc_target",
"rustc_trait_selection",
"rustc_type_ir",
"serde_json",
"smallvec",

View File

@ -2,6 +2,7 @@
//!
//! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize`
use rustc_codegen_ssa::base::validate_trivial_unsize;
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use crate::base::codegen_panic_nounwind;
@ -34,20 +35,8 @@ pub(crate) fn unsized_info<'tcx>(
let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() {
// Codegen takes advantage of the additional assumption, where if the
// principal trait def id of what's being casted doesn't change,
// then we don't need to adjust the vtable at all. This
// corresponds to the fact that `dyn Tr<A>: Unsize<dyn Tr<B>>`
// requires that `A = B`; we don't allow *upcasting* objects
// between the same trait with different args. If we, for
// some reason, were to relax the `Unsize` trait, it could become
// unsound, so let's assert here that the trait refs are *equal*.
//
// We can use `assert_eq` because the binders should have been anonymized,
// and because higher-ranked equality now requires the binders are equal.
debug_assert_eq!(
data_a.principal(),
data_b.principal(),
debug_assert!(
validate_trivial_unsize(fx.tcx, data_a, data_b),
"NOP unsize vtable changed principal trait ref: {data_a} -> {data_b}"
);
return old_info;

View File

@ -34,6 +34,7 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_type_ir = { path = "../rustc_type_ir" }
serde_json = "1.0.59"
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }

View File

@ -2959,11 +2959,12 @@ pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool
}
}
/// We need to communicate four things to the linker on Apple/Darwin targets:
/// We need to communicate five things to the linker on Apple/Darwin targets:
/// - The architecture.
/// - The operating system (and that it's an Apple platform).
/// - The deployment target.
/// - The environment / ABI.
/// - The deployment target.
/// - The SDK version.
fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if !sess.target.is_like_osx {
return;
@ -3039,7 +3040,38 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
let (major, minor, patch) = current_apple_deployment_target(&sess.target);
let min_version = format!("{major}.{minor}.{patch}");
// Lie about the SDK version, we don't know it here
// The SDK version is used at runtime when compiling with a newer SDK / version of Xcode:
// - By dyld to give extra warnings and errors, see e.g.:
// <https://github.com/apple-oss-distributions/dyld/blob/dyld-1165.3/common/MachOFile.cpp#L3029>
// <https://github.com/apple-oss-distributions/dyld/blob/dyld-1165.3/common/MachOFile.cpp#L3738-L3857>
// - By system frameworks to change certain behaviour. For example, the default value of
// `-[NSView wantsBestResolutionOpenGLSurface]` is `YES` when the SDK version is >= 10.15.
// <https://developer.apple.com/documentation/appkit/nsview/1414938-wantsbestresolutionopenglsurface?language=objc>
//
// We do not currently know the actual SDK version though, so we have a few options:
// 1. Use the minimum version supported by rustc.
// 2. Use the same as the deployment target.
// 3. Use an arbitary recent version.
// 4. Omit the version.
//
// The first option is too low / too conservative, and means that users will not get the
// same behaviour from a binary compiled with rustc as with one compiled by clang.
//
// The second option is similarly conservative, and also wrong since if the user specified a
// higher deployment target than the SDK they're compiling/linking with, the runtime might
// make invalid assumptions about the capabilities of the binary.
//
// The third option requires that `rustc` is periodically kept up to date with Apple's SDK
// version, and is also wrong for similar reasons as above.
//
// The fourth option is bad because while `ld`, `otool`, `vtool` and such understand it to
// mean "absent" or `n/a`, dyld doesn't actually understand it, and will end up interpreting
// it as 0.0, which is again too low/conservative.
//
// Currently, we lie about the SDK version, and choose the second option.
//
// FIXME(madsmtm): Parse the SDK version from the SDK root instead.
// <https://github.com/rust-lang/rust/issues/129432>
let sdk_version = &*min_version;
// From the man page for ld64 (`man ld`):
@ -3053,11 +3085,13 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
cmd.link_args(&["-platform_version", platform_name, &*min_version, sdk_version]);
} else {
// cc == Cc::Yes
//
// We'd _like_ to use `-target` everywhere, since that can uniquely
// communicate all the required details, but that doesn't work on GCC,
// and since we don't know whether the `cc` compiler is Clang, GCC, or
// something else, we fall back to other options that also work on GCC
// when compiling for macOS.
// communicate all the required details except for the SDK version
// (which is read by Clang itself from the SDKROOT), but that doesn't
// work on GCC, and since we don't know whether the `cc` compiler is
// Clang, GCC, or something else, we fall back to other options that
// also work on GCC when compiling for macOS.
//
// Targets other than macOS are ill-supported by GCC (it doesn't even
// support e.g. `-miphoneos-version-min`), so in those cases we can

View File

@ -402,13 +402,17 @@ fn pack_version((major, minor, patch): (u16, u8, u8)) -> u32 {
let platform =
rustc_target::spec::current_apple_platform(target).expect("unknown Apple target OS");
let min_os = rustc_target::spec::current_apple_deployment_target(target);
let (sdk_major, sdk_minor) =
rustc_target::spec::current_apple_sdk_version(platform).expect("unknown Apple target OS");
let mut build_version = object::write::MachOBuildVersion::default();
build_version.platform = platform;
build_version.minos = pack_version(min_os);
build_version.sdk = pack_version((sdk_major, sdk_minor, 0));
// The version here does not _really_ matter, since it is only used at runtime, and we specify
// it when linking the final binary, so we will omit the version. This is also what LLVM does,
// and the tooling also allows this (and shows the SDK version as `n/a`). Finally, it is the
// semantically correct choice, as the SDK has not influenced the binary generated by rustc at
// this point in time.
build_version.sdk = 0;
build_version
}

View File

@ -27,6 +27,9 @@
use rustc_span::symbol::sym;
use rustc_span::{DUMMY_SP, Symbol};
use rustc_target::abi::FIRST_VARIANT;
use rustc_trait_selection::infer::at::ToTrace;
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
use tracing::{debug, info};
use crate::assert_module_sources::CguReuse;
@ -101,6 +104,54 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx.sext(cmp, ret_ty)
}
/// Codegen takes advantage of the additional assumption, where if the
/// principal trait def id of what's being casted doesn't change,
/// then we don't need to adjust the vtable at all. This
/// corresponds to the fact that `dyn Tr<A>: Unsize<dyn Tr<B>>`
/// requires that `A = B`; we don't allow *upcasting* objects
/// between the same trait with different args. If we, for
/// some reason, were to relax the `Unsize` trait, it could become
/// unsound, so let's validate here that the trait refs are subtypes.
pub fn validate_trivial_unsize<'tcx>(
tcx: TyCtxt<'tcx>,
source_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
target_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> bool {
match (source_data.principal(), target_data.principal()) {
(Some(hr_source_principal), Some(hr_target_principal)) => {
let infcx = tcx.infer_ctxt().build();
let universe = infcx.universe();
let ocx = ObligationCtxt::new(&infcx);
infcx.enter_forall(hr_target_principal, |target_principal| {
let source_principal = infcx.instantiate_binder_with_fresh_vars(
DUMMY_SP,
BoundRegionConversionTime::HigherRankedType,
hr_source_principal,
);
let Ok(()) = ocx.eq_trace(
&ObligationCause::dummy(),
ty::ParamEnv::reveal_all(),
ToTrace::to_trace(
&ObligationCause::dummy(),
hr_target_principal,
hr_source_principal,
),
target_principal,
source_principal,
) else {
return false;
};
if !ocx.select_all_or_error().is_empty() {
return false;
}
infcx.leak_check(universe, None).is_ok()
})
}
(None, None) => true,
_ => false,
}
}
/// Retrieves the information we are losing (making dynamic) in an unsizing
/// adjustment.
///
@ -133,12 +184,8 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// between the same trait with different args. If we, for
// some reason, were to relax the `Unsize` trait, it could become
// unsound, so let's assert here that the trait refs are *equal*.
//
// We can use `assert_eq` because the binders should have been anonymized,
// and because higher-ranked equality now requires the binders are equal.
debug_assert_eq!(
data_a.principal(),
data_b.principal(),
debug_assert!(
validate_trivial_unsize(cx.tcx(), data_a, data_b),
"NOP unsize vtable changed principal trait ref: {data_a} -> {data_b}"
);

View File

@ -2,7 +2,7 @@
use std::ops::{ControlFlow, Deref};
use hir::intravisit::{self, Visitor};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_hir::ItemKind;
@ -404,7 +404,7 @@ fn check_trait_item<'tcx>(
/// ```
fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
// Associates every GAT's def_id to a list of possibly missing bounds detected by this lint.
let mut required_bounds_by_item = FxHashMap::default();
let mut required_bounds_by_item = FxIndexMap::default();
let associated_items = tcx.associated_items(trait_def_id);
// Loop over all GATs together, because if this lint suggests adding a where-clause bound
@ -430,7 +430,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
// Gather the bounds with which all other items inside of this trait constrain the GAT.
// This is calculated by taking the intersection of the bounds that each item
// constrains the GAT with individually.
let mut new_required_bounds: Option<FxHashSet<ty::Clause<'_>>> = None;
let mut new_required_bounds: Option<FxIndexSet<ty::Clause<'_>>> = None;
for item in associated_items.in_definition_order() {
let item_def_id = item.def_id.expect_local();
// Skip our own GAT, since it does not constrain itself at all.
@ -589,7 +589,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
fn augment_param_env<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
new_predicates: Option<&FxHashSet<ty::Clause<'tcx>>>,
new_predicates: Option<&FxIndexSet<ty::Clause<'tcx>>>,
) -> ty::ParamEnv<'tcx> {
let Some(new_predicates) = new_predicates else {
return param_env;
@ -625,9 +625,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
wf_tys: &FxIndexSet<Ty<'tcx>>,
gat_def_id: LocalDefId,
gat_generics: &'tcx ty::Generics,
) -> Option<FxHashSet<ty::Clause<'tcx>>> {
) -> Option<FxIndexSet<ty::Clause<'tcx>>> {
// The bounds we that we would require from `to_check`
let mut bounds = FxHashSet::default();
let mut bounds = FxIndexSet::default();
let (regions, types) = GATArgsCollector::visit(gat_def_id.to_def_id(), to_check);
@ -789,18 +789,18 @@ fn test_region_obligations<'tcx>(
struct GATArgsCollector<'tcx> {
gat: DefId,
// Which region appears and which parameter index its instantiated with
regions: FxHashSet<(ty::Region<'tcx>, usize)>,
regions: FxIndexSet<(ty::Region<'tcx>, usize)>,
// Which params appears and which parameter index its instantiated with
types: FxHashSet<(Ty<'tcx>, usize)>,
types: FxIndexSet<(Ty<'tcx>, usize)>,
}
impl<'tcx> GATArgsCollector<'tcx> {
fn visit<T: TypeFoldable<TyCtxt<'tcx>>>(
gat: DefId,
t: T,
) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
) -> (FxIndexSet<(ty::Region<'tcx>, usize)>, FxIndexSet<(Ty<'tcx>, usize)>) {
let mut visitor =
GATArgsCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
GATArgsCollector { gat, regions: FxIndexSet::default(), types: FxIndexSet::default() };
t.visit_with(&mut visitor);
(visitor.regions, visitor.types)
}

View File

@ -1,4 +1,4 @@
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, IndexEntry};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet, IndexEntry};
use rustc_errors::codes::*;
use rustc_errors::struct_span_code_err;
use rustc_hir as hir;
@ -215,7 +215,7 @@ fn check_item(&mut self, id: hir::ItemId) -> Result<(), ErrorGuaranteed> {
struct ConnectedRegion {
idents: SmallVec<[Symbol; 8]>,
impl_blocks: FxHashSet<usize>,
impl_blocks: FxIndexSet<usize>,
}
let mut connected_regions: IndexVec<RegionId, _> = Default::default();
// Reverse map from the Symbol to the connected region id.

View File

@ -23,7 +23,7 @@
use std::slice;
use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
@ -2394,8 +2394,8 @@ pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
#[instrument(level = "trace", skip(self, generate_err))]
fn validate_late_bound_regions<'cx>(
&'cx self,
constrained_regions: FxHashSet<ty::BoundRegionKind>,
referenced_regions: FxHashSet<ty::BoundRegionKind>,
constrained_regions: FxIndexSet<ty::BoundRegionKind>,
referenced_regions: FxIndexSet<ty::BoundRegionKind>,
generate_err: impl Fn(&str) -> Diag<'cx>,
) {
for br in referenced_regions.difference(&constrained_regions) {

View File

@ -58,7 +58,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::potential_query_instability)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]

View File

@ -67,7 +67,7 @@ fn lift_to_interner(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> {
};
}
/// Used for types that are `Copy` and which **do not care arena
/// Used for types that are `Copy` and which **do not care about arena
/// allocated data** (i.e., don't need to be folded).
#[macro_export]
macro_rules! TrivialTypeTraversalImpls {

View File

@ -186,7 +186,7 @@ pub struct ResolverGlobalCtxt {
pub proc_macros: Vec<LocalDefId>,
/// Mapping from ident span to path span for paths that don't exist as written, but that
/// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
pub confused_type_with_std_module: FxHashMap<Span, Span>,
pub confused_type_with_std_module: FxIndexMap<Span, Span>,
pub doc_link_resolutions: FxHashMap<LocalDefId, DocLinkResMap>,
pub doc_link_traits_in_scope: FxHashMap<LocalDefId, Vec<DefId>>,
pub all_macro_rules: FxHashMap<Symbol, Res<ast::NodeId>>,

View File

@ -1951,19 +1951,18 @@ fn pretty_closure_as_impl(
fn pretty_print_bound_constness(
&mut self,
trait_ref: ty::TraitRef<'tcx>,
constness: ty::BoundConstness,
) -> Result<(), PrintError> {
define_scoped_cx!(self);
let Some(idx) = self.tcx().generics_of(trait_ref.def_id).host_effect_index else {
return Ok(());
};
let arg = trait_ref.args.const_at(idx);
if arg == self.tcx().consts.false_ {
p!("const ");
} else if arg != self.tcx().consts.true_ && !arg.has_infer() {
p!("~const ");
match constness {
ty::BoundConstness::NotConst => {}
ty::BoundConstness::Const => {
p!("const ");
}
ty::BoundConstness::ConstIfConst => {
p!("~const ");
}
}
Ok(())
}
@ -2948,6 +2947,15 @@ fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx>
}
}
#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Lift)]
pub struct TraitPredPrintWithBoundConstness<'tcx>(ty::TraitPredicate<'tcx>, ty::BoundConstness);
impl<'tcx> fmt::Debug for TraitPredPrintWithBoundConstness<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
#[extension(pub trait PrintPolyTraitPredicateExt<'tcx>)]
impl<'tcx> ty::PolyTraitPredicate<'tcx> {
fn print_modifiers_and_trait_path(
@ -2955,6 +2963,13 @@ fn print_modifiers_and_trait_path(
) -> ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>> {
self.map_bound(TraitPredPrintModifiersAndPath)
}
fn print_with_bound_constness(
self,
constness: ty::BoundConstness,
) -> ty::Binder<'tcx, TraitPredPrintWithBoundConstness<'tcx>> {
self.map_bound(|trait_pred| TraitPredPrintWithBoundConstness(trait_pred, constness))
}
}
#[derive(Debug, Copy, Clone, Lift)]
@ -3052,7 +3067,6 @@ macro_rules! define_print_and_forward_display {
ty::TraitPredicate<'tcx> {
p!(print(self.trait_ref.self_ty()), ": ");
p!(pretty_print_bound_constness(self.trait_ref));
if let ty::PredicatePolarity::Negative = self.polarity {
p!("!");
}
@ -3184,13 +3198,21 @@ macro_rules! define_print_and_forward_display {
}
TraitPredPrintModifiersAndPath<'tcx> {
p!(pretty_print_bound_constness(self.0.trait_ref));
if let ty::PredicatePolarity::Negative = self.0.polarity {
p!("!")
}
p!(print(self.0.trait_ref.print_trait_sugared()));
}
TraitPredPrintWithBoundConstness<'tcx> {
p!(print(self.0.trait_ref.self_ty()), ": ");
p!(pretty_print_bound_constness(self.1));
if let ty::PredicatePolarity::Negative = self.0.polarity {
p!("!");
}
p!(print(self.0.trait_ref.print_trait_sugared()))
}
PrintClosureAsImpl<'tcx> {
p!(pretty_closure_as_impl(self.closure))
}

View File

@ -1,6 +1,6 @@
use std::ops::ControlFlow;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::FxIndexSet;
use rustc_type_ir::fold::TypeFoldable;
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
@ -110,7 +110,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
pub fn collect_constrained_late_bound_regions<T>(
self,
value: Binder<'tcx, T>,
) -> FxHashSet<ty::BoundRegionKind>
) -> FxIndexSet<ty::BoundRegionKind>
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
@ -121,7 +121,7 @@ pub fn collect_constrained_late_bound_regions<T>(
pub fn collect_referenced_late_bound_regions<T>(
self,
value: Binder<'tcx, T>,
) -> FxHashSet<ty::BoundRegionKind>
) -> FxIndexSet<ty::BoundRegionKind>
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
@ -132,7 +132,7 @@ fn collect_late_bound_regions<T>(
self,
value: Binder<'tcx, T>,
just_constrained: bool,
) -> FxHashSet<ty::BoundRegionKind>
) -> FxIndexSet<ty::BoundRegionKind>
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
@ -148,7 +148,7 @@ fn collect_late_bound_regions<T>(
/// into a hash set.
struct LateBoundRegionsCollector {
current_index: ty::DebruijnIndex,
regions: FxHashSet<ty::BoundRegionKind>,
regions: FxIndexSet<ty::BoundRegionKind>,
/// `true` if we only want regions that are known to be
/// "constrained" when you equate this type with another type. In

View File

@ -358,7 +358,7 @@ fn find_item_ty_spans(
match ty.kind {
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
if let Res::Def(kind, def_id) = path.res
&& !matches!(kind, DefKind::TyAlias)
&& matches!(kind, DefKind::Enum | DefKind::Struct | DefKind::Union)
{
let check_params = def_id.as_local().map_or(true, |def_id| {
if def_id == needle {

View File

@ -1188,7 +1188,7 @@ pub struct Resolver<'ra, 'tcx> {
/// A list of proc macro LocalDefIds, written out in the order in which
/// they are declared in the static array generated by proc_macro_harness.
proc_macros: Vec<NodeId>,
confused_type_with_std_module: FxHashMap<Span, Span>,
confused_type_with_std_module: FxIndexMap<Span, Span>,
/// Whether lifetime elision was successful.
lifetime_elision_allowed: FxHashSet<NodeId>,

View File

@ -158,23 +158,6 @@ pub(crate) fn base(
(opts, llvm_target(os, arch, abi), arch.target_arch())
}
pub fn sdk_version(platform: u32) -> Option<(u16, u8)> {
// NOTE: These values are from an arbitrary point in time but shouldn't make it into the final
// binary since the final link command will have the current SDK version passed to it.
match platform {
object::macho::PLATFORM_MACOS => Some((13, 1)),
object::macho::PLATFORM_IOS
| object::macho::PLATFORM_IOSSIMULATOR
| object::macho::PLATFORM_TVOS
| object::macho::PLATFORM_TVOSSIMULATOR
| object::macho::PLATFORM_MACCATALYST => Some((16, 2)),
object::macho::PLATFORM_WATCHOS | object::macho::PLATFORM_WATCHOSSIMULATOR => Some((9, 1)),
// FIXME: Upgrade to `object-rs` 0.33+ implementation with visionOS platform definition
11 | 12 => Some((1, 0)),
_ => None,
}
}
pub fn platform(target: &Target) -> Option<u32> {
Some(match (&*target.os, &*target.abi) {
("macos", _) => object::macho::PLATFORM_MACOS,

View File

@ -61,7 +61,7 @@
mod base;
pub use base::apple::{
deployment_target_for_target as current_apple_deployment_target,
platform as current_apple_platform, sdk_version as current_apple_sdk_version,
platform as current_apple_platform,
};
pub use base::avr_gnu::ef_avr_arch;

View File

@ -19,8 +19,8 @@
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::print::{
FmtPrinter, Print, PrintTraitPredicateExt as _, PrintTraitRefExt as _,
with_forced_trimmed_paths,
FmtPrinter, Print, PrintPolyTraitPredicateExt, PrintTraitPredicateExt as _,
PrintTraitRefExt as _, with_forced_trimmed_paths,
};
use rustc_middle::ty::{
self, ToPolyTraitRef, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast,
@ -154,6 +154,9 @@ pub fn report_selection_error(
} else {
(leaf_trait_predicate, &obligation)
};
let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span);
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
@ -164,9 +167,6 @@ pub fn report_selection_error(
return guar;
}
// FIXME(effects)
let predicate_is_const = false;
if let Err(guar) = leaf_trait_predicate.error_reported()
{
return guar;
@ -227,7 +227,7 @@ pub fn report_selection_error(
let err_msg = self.get_standard_error_message(
main_trait_predicate,
message,
predicate_is_const,
predicate_constness,
append_const_msg,
post_message,
);
@ -286,7 +286,7 @@ pub fn report_selection_error(
}
if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
&& predicate_is_const
&& matches!(predicate_constness, ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const)
{
err.note("`~const Drop` was renamed to `~const Destruct`");
err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
@ -2187,29 +2187,34 @@ fn get_standard_error_message(
&self,
trait_predicate: ty::PolyTraitPredicate<'tcx>,
message: Option<String>,
predicate_is_const: bool,
predicate_constness: ty::BoundConstness,
append_const_msg: Option<AppendConstMessage>,
post_message: String,
) -> String {
message
.and_then(|cannot_do_this| {
match (predicate_is_const, append_const_msg) {
match (predicate_constness, append_const_msg) {
// do nothing if predicate is not const
(false, _) => Some(cannot_do_this),
(ty::BoundConstness::NotConst, _) => Some(cannot_do_this),
// suggested using default post message
(true, Some(AppendConstMessage::Default)) => {
Some(format!("{cannot_do_this} in const contexts"))
}
(
ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
Some(AppendConstMessage::Default),
) => Some(format!("{cannot_do_this} in const contexts")),
// overridden post message
(true, Some(AppendConstMessage::Custom(custom_msg, _))) => {
Some(format!("{cannot_do_this}{custom_msg}"))
}
(
ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst,
Some(AppendConstMessage::Custom(custom_msg, _)),
) => Some(format!("{cannot_do_this}{custom_msg}")),
// fallback to generic message
(true, None) => None,
(ty::BoundConstness::Const | ty::BoundConstness::ConstIfConst, None) => None,
}
})
.unwrap_or_else(|| {
format!("the trait bound `{trait_predicate}` is not satisfied{post_message}")
format!(
"the trait bound `{}` is not satisfied{post_message}",
trait_predicate.print_with_bound_constness(predicate_constness)
)
})
}
@ -2333,6 +2338,51 @@ fn get_safe_transmute_error_and_reason(
}
}
/// For effects predicates such as `<u32 as Add>::Effects: Compat<host>`, pretend that the
/// predicate that failed was `u32: Add`. Return the constness of such predicate to later
/// print as `u32: ~const Add`.
fn get_effects_trait_pred_override(
&self,
p: ty::PolyTraitPredicate<'tcx>,
leaf: ty::PolyTraitPredicate<'tcx>,
span: Span,
) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) {
let trait_ref = p.to_poly_trait_ref();
if !self.tcx.is_lang_item(trait_ref.def_id(), LangItem::EffectsCompat) {
return (p, leaf, ty::BoundConstness::NotConst);
}
let Some(ty::Alias(ty::AliasTyKind::Projection, projection)) =
trait_ref.self_ty().no_bound_vars().map(Ty::kind)
else {
return (p, leaf, ty::BoundConstness::NotConst);
};
let constness = trait_ref.skip_binder().args.const_at(1);
let constness = if constness == self.tcx.consts.true_ || constness.is_ct_infer() {
ty::BoundConstness::NotConst
} else if constness == self.tcx.consts.false_ {
ty::BoundConstness::Const
} else if matches!(constness.kind(), ty::ConstKind::Param(_)) {
ty::BoundConstness::ConstIfConst
} else {
self.dcx().span_bug(span, format!("Unknown constness argument: {constness:?}"));
};
let new_pred = p.map_bound(|mut trait_pred| {
trait_pred.trait_ref = projection.trait_ref(self.tcx);
trait_pred
});
let new_leaf = leaf.map_bound(|mut trait_pred| {
trait_pred.trait_ref = projection.trait_ref(self.tcx);
trait_pred
});
(new_pred, new_leaf, constness)
}
fn add_tuple_trait_message(
&self,
obligation_cause_code: &ObligationCauseCode<'tcx>,

View File

@ -755,3 +755,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
}
impl<I> Lift<I> for BoundConstness {
type Lifted = BoundConstness;
fn lift_to_interner(self, _: I) -> Option<Self::Lifted> {
Some(self)
}
}

View File

@ -66,29 +66,31 @@
//! use std::thread;
//! use std::sync::mpmc::channel;
//!
//! // Create a shared channel that can be sent along from many threads
//! // where tx is the sending half (tx for transmission), and rx is the receiving
//! // half (rx for receiving).
//! let (tx, rx) = channel();
//! for i in 0..10 {
//! let tx = tx.clone();
//! thread::spawn(move || {
//! tx.send(i).unwrap();
//! });
//! }
//! thread::scope(|s| {
//! // Create a shared channel that can be sent along from many threads
//! // where tx is the sending half (tx for transmission), and rx is the receiving
//! // half (rx for receiving).
//! let (tx, rx) = channel();
//! for i in 0..10 {
//! let tx = tx.clone();
//! s.spawn(move || {
//! tx.send(i).unwrap();
//! });
//! }
//!
//! for _ in 0..5 {
//! let rx1 = rx.clone();
//! let rx2 = rx.clone();
//! thread::spawn(move || {
//! let j = rx1.recv().unwrap();
//! assert!(0 <= j && j < 10);
//! });
//! thread::spawn(move || {
//! let j = rx2.recv().unwrap();
//! assert!(0 <= j && j < 10);
//! });
//! }
//! for _ in 0..5 {
//! let rx1 = rx.clone();
//! let rx2 = rx.clone();
//! s.spawn(move || {
//! let j = rx1.recv().unwrap();
//! assert!(0 <= j && j < 10);
//! });
//! s.spawn(move || {
//! let j = rx2.recv().unwrap();
//! assert!(0 <= j && j < 10);
//! });
//! }
//! })
//! ```
//!
//! Propagating panics:

View File

@ -1,5 +0,0 @@
//@ known-bug: rust-lang/rust#128327
use std::ops::Deref;
struct Apple((Apple, <&'static [f64] as Deref>::Target(Banana ? Citron)));
fn main(){}

View File

@ -0,0 +1 @@
fn main() {}

View File

@ -0,0 +1,95 @@
//! Test codegen when setting SDK version on Apple platforms.
//!
//! This is important since its a compatibility hazard. The linker will
//! generate load commands differently based on what minimum OS it can assume.
//!
//! See https://github.com/rust-lang/rust/issues/129432.
//@ only-apple
use run_make_support::{apple_os, cmd, run_in_tmpdir, rustc, target};
/// Run vtool to check the `sdk` field in LC_BUILD_VERSION.
///
/// On lower deployment targets, LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS and similar
/// are used instead of LC_BUILD_VERSION, but both name the relevant variable `sdk`.
#[track_caller]
fn has_sdk_version(file: &str, version: &str) {
cmd("vtool")
.arg("-show-build")
.arg(file)
.run()
.assert_stdout_contains(format!("sdk {version}"));
}
fn main() {
// Fetch rustc's inferred deployment target.
let current_deployment_target =
rustc().target(target()).print("deployment-target").run().stdout_utf8();
let current_deployment_target =
current_deployment_target.strip_prefix("deployment_target=").unwrap().trim();
// Fetch current SDK version via. xcrun.
//
// Assumes a standard Xcode distribution, where e.g. the macOS SDK's Mac Catalyst
// and the iPhone Simulator version is the same as for the iPhone SDK.
let sdk_name = match apple_os() {
"macos" => "macosx",
"ios" => "iphoneos",
"watchos" => "watchos",
"tvos" => "appletvos",
"visionos" => "xros",
_ => unreachable!(),
};
let current_sdk_version =
cmd("xcrun").arg("--show-sdk-version").arg("--sdk").arg(sdk_name).run().stdout_utf8();
let current_sdk_version = current_sdk_version.trim();
// Check the SDK version in the object file produced by the codegen backend.
rustc().target(target()).crate_type("lib").emit("obj").input("foo.rs").output("foo.o").run();
// Set to 0, which means not set or "n/a".
has_sdk_version("foo.o", "n/a");
// Check the SDK version in the .rmeta file, as set in `create_object_file`.
//
// This is just to ensure that we don't set some odd version in `create_object_file`,
// if the rmeta file is packed in a different way in the future, this can safely be removed.
rustc().target(target()).crate_type("rlib").input("foo.rs").output("libfoo.rlib").run();
// Extra .rmeta file (which is encoded as an object file).
cmd("ar").arg("-x").arg("libfoo.rlib").arg("lib.rmeta").run();
has_sdk_version("lib.rmeta", "n/a");
// Test that version makes it to the linker.
for (crate_type, file_ext) in [("bin", ""), ("dylib", ".dylib")] {
// Non-simulator watchOS targets don't support dynamic linking,
// for simplicity we disable the test on all watchOS targets.
if crate_type == "dylib" && apple_os() == "watchos" {
continue;
}
// Test with clang
let file_name = format!("foo_cc{file_ext}");
rustc()
.target(target())
.crate_type("bin")
.arg("-Clinker-flavor=gcc")
.input("foo.rs")
.output(&file_name)
.run();
has_sdk_version(&file_name, current_sdk_version);
// Test with ld64
let file_name = format!("foo_ld{file_ext}");
rustc()
.target(target())
.crate_type("bin")
.arg("-Clinker-flavor=ld")
.input("foo.rs")
.output(&file_name)
.run();
// FIXME(madsmtm): This uses the current deployment target
// instead of the current SDK version like Clang does.
// https://github.com/rust-lang/rust/issues/129432
has_sdk_version(&file_name, current_deployment_target);
}
}

View File

@ -0,0 +1,8 @@
//@ build-pass
// Regression test for an overly aggressive assertion in #130855.
fn main() {
let subtype: &(dyn for<'a> Fn(&'a i32) -> &'a i32) = &|x| x;
let supertype: &(dyn Fn(&'static i32) -> &'static i32) = subtype;
}

View File

@ -108,17 +108,6 @@ LL | type Bar<'b>;
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Iterator`
--> $DIR/self-outlives-lint.rs:142:5
|
LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: add the required where clause: `where Self: 'a`
|
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Item`
--> $DIR/self-outlives-lint.rs:140:5
|
@ -130,6 +119,17 @@ LL | type Item<'a>;
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Iterator`
--> $DIR/self-outlives-lint.rs:142:5
|
LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: add the required where clause: `where Self: 'a`
|
= note: this bound is currently required to ensure that impls have maximum flexibility
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
error: missing required bound on `Item`
--> $DIR/self-outlives-lint.rs:148:5
|

View File

@ -1,2 +1,5 @@
pub struct W<T>(T);
pub type Wrapper<T> = W<T>;
pub trait Trait {
type T;
}

View File

@ -0,0 +1,16 @@
//@ aux-build: alias.rs
// issue#128327
extern crate alias;
use alias::Trait;
struct S;
impl Trait for S {
type T = ();
}
struct A((A, <S as Trait>::T<NOT_EXIST?>));
//~^ ERROR: invalid `?` in type
//~| ERROR: recursive type `A` has infinite size
fn main() {}

View File

@ -0,0 +1,25 @@
error: invalid `?` in type
--> $DIR/infinite-assoc.rs:12:39
|
LL | struct A((A, <S as Trait>::T<NOT_EXIST?>));
| ^ `?` is only allowed on expressions, not types
|
help: if you meant to express that the type might not contain a value, use the `Option` wrapper type
|
LL | struct A((A, <S as Trait>::T<Option<NOT_EXIST>>));
| +++++++ ~
error[E0072]: recursive type `A` has infinite size
--> $DIR/infinite-assoc.rs:12:1
|
LL | struct A((A, <S as Trait>::T<NOT_EXIST?>));
| ^^^^^^^^ - recursive without indirection
|
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
LL | struct A((Box<A>, <S as Trait>::T<NOT_EXIST?>));
| ++++ +
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0072`.

View File

@ -3,11 +3,11 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
--> $DIR/assoc-type-const-bound-usage-0.rs:13:5
|
LL | T::Assoc::func()
| ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
| ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
note: required by a bound in `Trait::func`
--> $DIR/assoc-type-const-bound-usage-0.rs:6:1
@ -17,12 +17,16 @@ LL | #[const_trait]
...
LL | fn func() -> i32;
| ---- required by a bound in this associated function
help: consider further restricting the associated type
|
LL | const fn unqualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
| ++++++++++++++++++++++++++++++++
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
--> $DIR/assoc-type-const-bound-usage-0.rs:17:5
|
LL | <T as Trait>::Assoc::func()
| ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
note: required by a bound in `Trait::func`
--> $DIR/assoc-type-const-bound-usage-0.rs:6:1
@ -32,6 +36,10 @@ LL | #[const_trait]
...
LL | fn func() -> i32;
| ---- required by a bound in this associated function
help: consider further restricting the associated type
|
LL | const fn qualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
| ++++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors

View File

@ -3,11 +3,11 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
--> $DIR/assoc-type-const-bound-usage-1.rs:15:44
|
LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> {
| ^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
| ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
note: required by a bound in `Trait::func`
--> $DIR/assoc-type-const-bound-usage-1.rs:7:1
@ -17,12 +17,16 @@ LL | #[const_trait]
...
LL | fn func() -> i32;
| ---- required by a bound in this associated function
help: consider further restricting the associated type
|
LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> where <T as Trait>::Assoc: Trait {
| ++++++++++++++++++++++++++++++++
error[E0277]: the trait bound `Trait::{synthetic#0}: Compat` is not satisfied
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
--> $DIR/assoc-type-const-bound-usage-1.rs:19:42
|
LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> {
| ^^^^^^^^^^^^^^^^^^^ the trait `Compat` is not implemented for `Trait::{synthetic#0}`
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
note: required by a bound in `Trait::func`
--> $DIR/assoc-type-const-bound-usage-1.rs:7:1
@ -32,6 +36,10 @@ LL | #[const_trait]
...
LL | fn func() -> i32;
| ---- required by a bound in this associated function
help: consider further restricting the associated type
|
LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> where <T as Trait>::Assoc: Trait {
| ++++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors

View File

@ -1,4 +1,6 @@
#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
//@ compile-flags: -Znext-solver
#![allow(incomplete_features)]
#![feature(const_trait_impl, effects)]
#[const_trait]
pub trait Plus {
@ -23,7 +25,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
pub const fn add_u32(a: u32, b: u32) -> u32 {
a.plus(b)
//~^ ERROR the trait bound
//~^ ERROR the trait bound `u32: ~const Plus`
}
fn main() {}

View File

@ -1,33 +1,22 @@
warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/call-const-trait-method-fail.rs:1:30
|
LL | #![feature(const_trait_impl, effects)]
| ^^^^^^^
|
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied
--> $DIR/call-const-trait-method-fail.rs:25:5
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
--> $DIR/call-const-trait-method-fail.rs:27:5
|
LL | a.plus(b)
| ^ the trait `~const Compat` is not implemented for `Runtime`
| ^ the trait `Plus` is not implemented for `u32`
|
= help: the trait `Compat` is implemented for `Runtime`
note: required by a bound in `Plus::plus`
--> $DIR/call-const-trait-method-fail.rs:3:1
--> $DIR/call-const-trait-method-fail.rs:5:1
|
LL | #[const_trait]
| ^^^^^^^^^^^^^^ required by this bound in `Plus::plus`
LL | pub trait Plus {
LL | fn plus(self, rhs: Self) -> Self;
| ---- required by a bound in this associated function
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub const fn add_u32(a: u32, b: u32) -> u32 where u32: Plus {
| +++++++++++++++
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,4 +1,6 @@
#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
//@ compile-flags: -Znext-solver
#![allow(incomplete_features)]
#![feature(const_trait_impl, effects)]
struct S;
@ -21,7 +23,6 @@ const fn equals_self<T: ~const Foo>(t: &T) -> bool {
// it not using the impl.
pub const EQ: bool = equals_self(&S);
//~^ ERROR: the trait bound `Runtime: const Compat` is not satisfied
// FIXME(effects) diagnostic
//~^ ERROR: the trait bound `S: const Foo` is not satisfied
fn main() {}

View File

@ -1,32 +1,21 @@
warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/call-generic-method-nonconst.rs:1:30
|
LL | #![feature(const_trait_impl, effects)]
| ^^^^^^^
|
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0277]: the trait bound `Runtime: const Compat` is not satisfied
--> $DIR/call-generic-method-nonconst.rs:23:34
error[E0277]: the trait bound `S: const Foo` is not satisfied
--> $DIR/call-generic-method-nonconst.rs:25:34
|
LL | pub const EQ: bool = equals_self(&S);
| ----------- ^^ the trait `const Compat` is not implemented for `Runtime`
| ----------- ^^ the trait `Foo` is not implemented for `S`
| |
| required by a bound introduced by this call
|
= help: the trait `Compat` is implemented for `Runtime`
note: required by a bound in `equals_self`
--> $DIR/call-generic-method-nonconst.rs:16:25
--> $DIR/call-generic-method-nonconst.rs:18:25
|
LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
| ^^^^^^^^^^ required by this bound in `equals_self`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub const EQ: bool where S: Foo = equals_self(&S);
| ++++++++++++
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,4 +1,6 @@
#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
//@ compile-flags: -Znext-solver
#![allow(incomplete_features)]
#![feature(const_trait_impl, effects)]
#[const_trait]
trait ConstDefaultFn: Sized {
@ -22,7 +24,7 @@ fn b(self) {}
const fn test() {
NonConstImpl.a();
//~^ ERROR the trait bound
//~^ ERROR the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
ConstImpl.a();
}

View File

@ -1,33 +1,22 @@
warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/const-default-method-bodies.rs:1:30
|
LL | #![feature(const_trait_impl, effects)]
| ^^^^^^^
|
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied
--> $DIR/const-default-method-bodies.rs:24:18
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
--> $DIR/const-default-method-bodies.rs:26:18
|
LL | NonConstImpl.a();
| ^ the trait `~const Compat` is not implemented for `Runtime`
| ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl`
|
= help: the trait `Compat` is implemented for `Runtime`
note: required by a bound in `ConstDefaultFn::a`
--> $DIR/const-default-method-bodies.rs:3:1
--> $DIR/const-default-method-bodies.rs:5:1
|
LL | #[const_trait]
| ^^^^^^^^^^^^^^ required by this bound in `ConstDefaultFn::a`
...
LL | fn a(self) {
| - required by a bound in this associated function
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | const fn test() where NonConstImpl: ConstDefaultFn {
| ++++++++++++++++++++++++++++++++++
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `FnOnce<()>::{synthetic#0}: const Compat` is not satisfied
error[E0277]: the trait bound `fn() {foo}: const FnOnce()` is not satisfied
--> $DIR/const-fns-are-early-bound.rs:31:17
|
LL | is_const_fn(foo);
| ----------- ^^^ the trait `const Compat` is not implemented for `FnOnce<()>::{synthetic#0}`
| ----------- ^^^ the trait `FnOnce()` is not implemented for fn item `fn() {foo}`
| |
| required by a bound introduced by this call
|

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `cross_crate::MyTrait::{synthetic#0}: ~const Compat` is not satisfied
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
--> $DIR/cross-crate.rs:19:14
|
LL | NonConst.func();
| ^^^^ the trait `~const Compat` is not implemented for `cross_crate::MyTrait::{synthetic#0}`
| ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
note: required by a bound in `func`
--> $DIR/auxiliary/cross-crate.rs:5:1
@ -12,6 +12,10 @@ LL | #[const_trait]
...
LL | fn func(self);
| ---- required by a bound in this associated function
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | const fn const_context() where cross_crate::NonConst: cross_crate::MyTrait {
| +++++++++++++++++++++++++++++++++++++++++++++++++
error: aborting due to 1 previous error

View File

@ -1,4 +1,6 @@
#![feature(const_trait_impl, effects)] //~ WARN the feature `effects` is incomplete
//@ compile-flags: -Znext-solver
#![allow(incomplete_features)]
#![feature(const_trait_impl, effects)]
#[const_trait]
pub trait Tr {
@ -6,7 +8,7 @@ fn a(&self) {}
fn b(&self) {
().a()
//~^ ERROR the trait bound
//~^ ERROR the trait bound `(): ~const Tr` is not satisfied
}
}

View File

@ -1,33 +1,22 @@
warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/default-method-body-is-const-same-trait-ck.rs:1:30
|
LL | #![feature(const_trait_impl, effects)]
| ^^^^^^^
|
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0277]: the trait bound `Runtime: ~const Compat` is not satisfied
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
|
LL | ().a()
| ^ the trait `~const Compat` is not implemented for `Runtime`
| ^ the trait `Tr` is not implemented for `()`
|
= help: the trait `Compat` is implemented for `Runtime`
note: required by a bound in `Tr::a`
--> $DIR/default-method-body-is-const-same-trait-ck.rs:3:1
--> $DIR/default-method-body-is-const-same-trait-ck.rs:5:1
|
LL | #[const_trait]
| ^^^^^^^^^^^^^^ required by this bound in `Tr::a`
LL | pub trait Tr {
LL | fn a(&self) {}
| - required by a bound in this associated function
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | pub trait Tr where (): Tr {
| ++++++++++++
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -17,8 +17,7 @@ trait Bar: ~const Foo {}
const fn foo<T: Bar>(x: &T) {
x.a();
//[yy,yn]~^ ERROR the trait bound
// FIXME(effects) diagnostic
//[yy,yn]~^ ERROR the trait bound `T: ~const Foo`
}
fn main() {}

View File

@ -10,11 +10,11 @@ note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bou
LL | trait Bar: ~const Foo {}
| ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
--> $DIR/super-traits-fail-2.rs:19:7
|
LL | x.a();
| ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}`
| ^ the trait `Foo` is not implemented for `T`
|
note: required by a bound in `Foo::a`
--> $DIR/super-traits-fail-2.rs:6:25
@ -24,10 +24,10 @@ LL | #[cfg_attr(any(yy, yn), const_trait)]
LL | trait Foo {
LL | fn a(&self);
| - required by a bound in this associated function
help: consider further restricting the associated type
help: consider further restricting this bound
|
LL | const fn foo<T: Bar>(x: &T) where Foo::{synthetic#0}: ~const Compat {
| +++++++++++++++++++++++++++++++++++++++
LL | const fn foo<T: Bar + Foo>(x: &T) {
| +++++
error: aborting due to 2 previous errors

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
--> $DIR/super-traits-fail-2.rs:19:7
|
LL | x.a();
| ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}`
| ^ the trait `Foo` is not implemented for `T`
|
note: required by a bound in `Foo::a`
--> $DIR/super-traits-fail-2.rs:6:25
@ -12,10 +12,10 @@ LL | #[cfg_attr(any(yy, yn), const_trait)]
LL | trait Foo {
LL | fn a(&self);
| - required by a bound in this associated function
help: consider further restricting the associated type
help: consider further restricting this bound
|
LL | const fn foo<T: Bar>(x: &T) where Foo::{synthetic#0}: ~const Compat {
| +++++++++++++++++++++++++++++++++++++++
LL | const fn foo<T: Bar + Foo>(x: &T) {
| +++++
error: aborting due to 1 previous error

View File

@ -20,7 +20,7 @@ trait Bar: ~const Foo {}
const fn foo<T: ~const Bar>(x: &T) {
//[yn,nn]~^ ERROR: `~const` can only be applied to `#[const_trait]`
x.a();
//[yn]~^ ERROR: the trait bound
//[yn]~^ ERROR: the trait bound `T: ~const Foo` is not satisfied
}
fn main() {}

View File

@ -16,11 +16,11 @@ error: `~const` can only be applied to `#[const_trait]` traits
LL | const fn foo<T: ~const Bar>(x: &T) {
| ^^^
error[E0277]: the trait bound `Foo::{synthetic#0}: ~const Compat` is not satisfied
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
--> $DIR/super-traits-fail-3.rs:22:7
|
LL | x.a();
| ^ the trait `~const Compat` is not implemented for `Foo::{synthetic#0}`
| ^ the trait `Foo` is not implemented for `T`
|
note: required by a bound in `Foo::a`
--> $DIR/super-traits-fail-3.rs:8:25
@ -30,10 +30,10 @@ LL | #[cfg_attr(any(yy, yn), const_trait)]
LL | trait Foo {
LL | fn a(&self);
| - required by a bound in this associated function
help: consider further restricting the associated type
help: consider further restricting this bound
|
LL | const fn foo<T: ~const Bar>(x: &T) where Foo::{synthetic#0}: ~const Compat {
| +++++++++++++++++++++++++++++++++++++++
LL | const fn foo<T: ~const Bar + Foo>(x: &T) {
| +++++
error: aborting due to 3 previous errors

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied
error[E0277]: the trait bound `T: Foo` is not satisfied
--> $DIR/trait-where-clause-const.rs:22:5
|
LL | T::b();
| ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}`
| ^ the trait `Foo` is not implemented for `T`
|
note: required by a bound in `Foo::b`
--> $DIR/trait-where-clause-const.rs:13:1
@ -12,10 +12,6 @@ LL | #[const_trait]
...
LL | fn b() where Self: ~const Bar;
| - required by a bound in this associated function
help: consider further restricting the associated type
|
LL | const fn test1<T: ~const Foo + Bar>() where Foo::{synthetic#0}: Compat {
| ++++++++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/trait-where-clause-const.rs:22:5
@ -26,11 +22,11 @@ LL | T::b();
= note: expected constant `host`
found constant `true`
error[E0277]: the trait bound `Foo::{synthetic#0}: Compat` is not satisfied
error[E0277]: the trait bound `T: Foo` is not satisfied
--> $DIR/trait-where-clause-const.rs:25:5
|
LL | T::c::<T>();
| ^ the trait `Compat` is not implemented for `Foo::{synthetic#0}`
| ^ the trait `Foo` is not implemented for `T`
|
note: required by a bound in `Foo::c`
--> $DIR/trait-where-clause-const.rs:13:1
@ -40,10 +36,6 @@ LL | #[const_trait]
...
LL | fn c<T: ~const Bar>();
| - required by a bound in this associated function
help: consider further restricting the associated type
|
LL | const fn test1<T: ~const Foo + Bar>() where Foo::{synthetic#0}: Compat {
| ++++++++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/trait-where-clause-const.rs:25:5

View File

@ -19,7 +19,6 @@ fn make() -> u32 { 0 }
}
fn main() {
// FIXME(effects): improve diagnostics on this
require::<Ty>();
}

View File

@ -7,7 +7,7 @@ LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
= help: remove one of these features
error[E0308]: mismatched types
--> $DIR/unsatisfied-const-trait-bound.rs:30:37
--> $DIR/unsatisfied-const-trait-bound.rs:29:37
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^ expected `false`, found `true`
@ -16,7 +16,7 @@ LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
found constant `true`
error[E0308]: mismatched types
--> $DIR/unsatisfied-const-trait-bound.rs:34:50
--> $DIR/unsatisfied-const-trait-bound.rs:33:50
|
LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^ expected `false`, found `host`
@ -24,17 +24,21 @@ LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
= note: expected constant `false`
found constant `host`
error[E0277]: the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied
--> $DIR/unsatisfied-const-trait-bound.rs:23:15
error[E0277]: the trait bound `Ty: const Trait` is not satisfied
--> $DIR/unsatisfied-const-trait-bound.rs:22:15
|
LL | require::<Ty>();
| ^^ the trait `const Compat` is not implemented for `Trait::{synthetic#0}`
| ^^ the trait `Trait` is not implemented for `Ty`
|
note: required by a bound in `require`
--> $DIR/unsatisfied-const-trait-bound.rs:8:15
|
LL | fn require<T: const Trait>() {}
| ^^^^^^^^^^^ required by this bound in `require`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
LL | fn main() where Ty: Trait {
| +++++++++++++++
error: aborting due to 4 previous errors