Skip to content

Rollup of 7 pull requests #131158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Oct 2, 2024
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0bebedd
Document a bit more how the SDK version actually works
madsmtm Sep 29, 2024
8964c48
Add run-make test to check the SDK version(s) that rustc produces
madsmtm Sep 29, 2024
6b06ceb
Do not specify an SDK version in object files
madsmtm Sep 29, 2024
eb75d20
Relax a debug assertion in codegen
compiler-errors Sep 28, 2024
cbb5047
Relate binders explicitly, do a leak check too
compiler-errors Sep 30, 2024
807e812
Handle `rustc-hir-analysis` cases of `rustc::potential_query_instabil…
ismailarilik Oct 2, 2024
9fa1205
mpmc doctest: make sure main thread waits for child threads
RalfJung Oct 2, 2024
e9b2d09
only query `params_in_repr` if def kind is adt
bvanjoi Oct 2, 2024
aa3251d
Replace zero-width whitespace with a visible `\`
jieyouxu Oct 2, 2024
7f6150b
Improve const traits diagnostics for new desugaring
fee1-dead Oct 2, 2024
f9ba552
Rollup merge of #130863 - compiler-errors:relax-codegen-dyn-assert, r…
matthiaskrgr Oct 2, 2024
5fd6218
Rollup merge of #131016 - madsmtm:no-sdk-version-in-object, r=jieyouxu
matthiaskrgr Oct 2, 2024
7e0797c
Rollup merge of #131140 - ismailarilik:handle-potential-query-instabi…
matthiaskrgr Oct 2, 2024
49f17ff
Rollup merge of #131141 - RalfJung:mpmc-test, r=Amanieu
matthiaskrgr Oct 2, 2024
2e0db79
Rollup merge of #131150 - bvanjoi:issue-128327, r=chenyukang
matthiaskrgr Oct 2, 2024
06d5218
Rollup merge of #131151 - jieyouxu:adjust-pr-template, r=fmease
matthiaskrgr Oct 2, 2024
b38f7ad
Rollup merge of #131152 - fee1-dead-contrib:fxdiag, r=compiler-errors
matthiaskrgr Oct 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -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 -->
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -3451,6 +3451,7 @@ dependencies = [
"rustc_span",
"rustc_symbol_mangling",
"rustc_target",
"rustc_trait_selection",
"rustc_type_ir",
"serde_json",
"smallvec",
17 changes: 3 additions & 14 deletions compiler/rustc_codegen_cranelift/src/unsize.rs
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"] }
48 changes: 41 additions & 7 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -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
10 changes: 7 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
@@ -402,13 +402,17 @@ fn macho_object_build_version_for_target(target: &Target) -> object::write::Mach
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
}

59 changes: 53 additions & 6 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
@@ -27,6 +27,9 @@ use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType};
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}"
);

20 changes: 10 additions & 10 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use std::cell::LazyCell;
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)
}
Original file line number Diff line number Diff line change
@@ -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 @@ impl<'tcx> InherentOverlapChecker<'tcx> {

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.
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ mod lint;
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 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
#[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) {
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -58,7 +58,6 @@ This API is completely unstable and subject to change.
// 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)]
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/macros.rs
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@ macro_rules! TrivialLiftImpls {
};
}

/// 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 {
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -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>>,
46 changes: 34 additions & 12 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
@@ -1951,19 +1951,18 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {

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,13 +2947,29 @@ impl<'tcx> ty::TraitPredicate<'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(
self,
) -> 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 @@ define_print! {

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 @@ 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))
}
10 changes: 5 additions & 5 deletions compiler/rustc_middle/src/ty/visit.rs
Original file line number Diff line number Diff line change
@@ -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 @@ impl<'tcx> TyCtxt<'tcx> {
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 @@ impl<'tcx> TyCtxt<'tcx> {
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 @@ impl<'tcx> TyCtxt<'tcx> {
self,
value: Binder<'tcx, T>,
just_constrained: bool,
) -> FxHashSet<ty::BoundRegionKind>
) -> FxIndexSet<ty::BoundRegionKind>
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
@@ -148,7 +148,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// 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
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/values.rs
Original file line number Diff line number Diff line change
@@ -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 {
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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>,

17 changes: 0 additions & 17 deletions compiler/rustc_target/src/spec/base/apple/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ pub mod crt_objects;
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;

Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
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 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
} 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 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
return guar;
}

// FIXME(effects)
let predicate_is_const = false;

if let Err(guar) = leaf_trait_predicate.error_reported()
{
return guar;
@@ -227,7 +227,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
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 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}

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 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
&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 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}

/// 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>,
7 changes: 7 additions & 0 deletions compiler/rustc_type_ir/src/predicate.rs
Original file line number Diff line number Diff line change
@@ -755,3 +755,10 @@ impl fmt::Display for BoundConstness {
}
}
}

impl<I> Lift<I> for BoundConstness {
type Lifted = BoundConstness;
fn lift_to_interner(self, _: I) -> Option<Self::Lifted> {
Some(self)
}
}
46 changes: 24 additions & 22 deletions library/std/src/sync/mpmc/mod.rs
Original file line number Diff line number Diff line change
@@ -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:
5 changes: 0 additions & 5 deletions tests/crashes/128327.rs

This file was deleted.

1 change: 1 addition & 0 deletions tests/run-make/apple-sdk-version/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fn main() {}
95 changes: 95 additions & 0 deletions tests/run-make/apple-sdk-version/rmake.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
8 changes: 8 additions & 0 deletions tests/ui/codegen/sub-principals-in-codegen.rs
Original file line number Diff line number Diff line change
@@ -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;
}
22 changes: 11 additions & 11 deletions tests/ui/generic-associated-types/self-outlives-lint.stderr
Original file line number Diff line number Diff line change
@@ -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
|
3 changes: 3 additions & 0 deletions tests/ui/infinite/auxiliary/alias.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
pub struct W<T>(T);
pub type Wrapper<T> = W<T>;
pub trait Trait {
type T;
}
16 changes: 16 additions & 0 deletions tests/ui/infinite/infinite-assoc.rs
Original file line number Diff line number Diff line change
@@ -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() {}
25 changes: 25 additions & 0 deletions tests/ui/infinite/infinite-assoc.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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 @@ impl const ConstDefaultFn for ConstImpl {

const fn test() {
NonConstImpl.a();
//~^ ERROR the trait bound
//~^ ERROR the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
ConstImpl.a();
}

Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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
|
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#![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 {
fn a(&self) {}

fn b(&self) {
().a()
//~^ ERROR the trait bound
//~^ ERROR the trait bound `(): ~const Tr` is not satisfied
}
}

Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ impl Trait for Ty {
}

fn main() {
// FIXME(effects): improve diagnostics on this
require::<Ty>();
}

Original file line number Diff line number Diff line change
@@ -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,25 +16,29 @@ 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`
|
= 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