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:
commit
5384697e9e
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@ -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 -->
|
||||
|
@ -3451,6 +3451,7 @@ dependencies = [
|
||||
"rustc_span",
|
||||
"rustc_symbol_mangling",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"rustc_type_ir",
|
||||
"serde_json",
|
||||
"smallvec",
|
||||
|
@ -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;
|
||||
|
@ -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"] }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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}"
|
||||
);
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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)]
|
||||
|
@ -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 {
|
||||
|
@ -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>>,
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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>,
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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(){}
|
1
tests/run-make/apple-sdk-version/foo.rs
Normal file
1
tests/run-make/apple-sdk-version/foo.rs
Normal file
@ -0,0 +1 @@
|
||||
fn main() {}
|
95
tests/run-make/apple-sdk-version/rmake.rs
Normal file
95
tests/run-make/apple-sdk-version/rmake.rs
Normal 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);
|
||||
}
|
||||
}
|
8
tests/ui/codegen/sub-principals-in-codegen.rs
Normal file
8
tests/ui/codegen/sub-principals-in-codegen.rs
Normal 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;
|
||||
}
|
@ -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
|
||||
|
|
||||
|
@ -1,2 +1,5 @@
|
||||
pub struct W<T>(T);
|
||||
pub type Wrapper<T> = W<T>;
|
||||
pub trait Trait {
|
||||
type T;
|
||||
}
|
||||
|
16
tests/ui/infinite/infinite-assoc.rs
Normal file
16
tests/ui/infinite/infinite-assoc.rs
Normal 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() {}
|
25
tests/ui/infinite/infinite-assoc.stderr
Normal file
25
tests/ui/infinite/infinite-assoc.stderr
Normal 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`.
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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`.
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -19,7 +19,6 @@ fn make() -> u32 { 0 }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// FIXME(effects): improve diagnostics on this
|
||||
require::<Ty>();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user