Auto merge of #152574 - JonathanBrouwer:rollup-ERc05AE, r=JonathanBrouwer
Rollup of 14 pull requests Successful merges: - rust-lang/rust#152323 (Fix ICE in borrowck when recovering `fn_sig` for `-> _`) - rust-lang/rust#152469 (Remove unused features) - rust-lang/rust#152515 (Extract `DepKindVTable` constructors to their own module) - rust-lang/rust#152555 (Port `#[rustc_diagnostic_item]` to the new attribute parsers) - rust-lang/rust#152218 (Report unconstrained region in hidden types lazily) - rust-lang/rust#152356 (Improve the `inline_fluent!` macro) - rust-lang/rust#152392 (Fix ICE in supertrait_vtable_slot when supertrait has missing generics) - rust-lang/rust#152407 (Add regression test for type_const with unit struct ctor under mGCA) - rust-lang/rust#152440 (Fix typos and grammar in compiler and build documentation) - rust-lang/rust#152536 (bootstrap: add explicit UTF-8 encoding to text-mode open() calls) - rust-lang/rust#152554 (Remove `deprecated_safe` and its corresponding feature gate) - rust-lang/rust#152556 (doc: move riscv64a23-unknown-linux-gnu to tier 2) - rust-lang/rust#152563 (Replace "bug" with "issue" in triagebot ping messages) - rust-lang/rust#152565 (fix missleading error for tuple ctor) Failed merges: - rust-lang/rust#152512 (core: Implement feature `float_exact_integer_constants`) - rust-lang/rust#152296 (Port `rust_nonnull_optimization_guaranteed` and `rustc_do_not_const_check` to the new attribute parser)
This commit is contained in:
commit
f403dee04e
103 changed files with 1086 additions and 652 deletions
|
|
@ -1,5 +1,5 @@
|
|||
// tidy-alphabetical-start
|
||||
#![cfg_attr(all(feature = "nightly", bootstrap), feature(assert_matches))]
|
||||
#![cfg_attr(all(feature = "nightly", bootstrap, test), feature(assert_matches))]
|
||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
|
||||
#![cfg_attr(feature = "nightly", feature(step_trait))]
|
||||
|
|
|
|||
|
|
@ -1103,6 +1103,45 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
|
|||
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility;
|
||||
}
|
||||
|
||||
pub(crate) struct RustcDiagnosticItemParser;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for RustcDiagnosticItemParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_diagnostic_item];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
|
||||
Allow(Target::Trait),
|
||||
Allow(Target::Struct),
|
||||
Allow(Target::Enum),
|
||||
Allow(Target::MacroDef),
|
||||
Allow(Target::TyAlias),
|
||||
Allow(Target::AssocTy),
|
||||
Allow(Target::AssocConst),
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Const),
|
||||
Allow(Target::Mod),
|
||||
Allow(Target::Impl { of_trait: false }),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
Allow(Target::Method(MethodKind::Trait { body: false })),
|
||||
Allow(Target::Method(MethodKind::Trait { body: true })),
|
||||
Allow(Target::Method(MethodKind::TraitImpl)),
|
||||
Allow(Target::Crate),
|
||||
]);
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
|
||||
let Some(nv) = args.name_value() else {
|
||||
cx.expected_name_value(cx.attr_span, None);
|
||||
return None;
|
||||
};
|
||||
let Some(value) = nv.value_as_str() else {
|
||||
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
|
||||
return None;
|
||||
};
|
||||
Some(AttributeKind::RustcDiagnosticItem(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct RustcSymbolName;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for RustcSymbolName {
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ attribute_parsers!(
|
|||
Single<RustcBuiltinMacroParser>,
|
||||
Single<RustcDefPath>,
|
||||
Single<RustcDeprecatedSafe2024Parser>,
|
||||
Single<RustcDiagnosticItemParser>,
|
||||
Single<RustcForceInlineParser>,
|
||||
Single<RustcIfThisChangedParser>,
|
||||
Single<RustcLayoutScalarValidRangeEndParser>,
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
|||
use tracing::{debug, instrument};
|
||||
|
||||
use super::reverse_sccs::ReverseSccGraph;
|
||||
use crate::BorrowckInferCtxt;
|
||||
use crate::consumers::RegionInferenceContext;
|
||||
use crate::session_diagnostics::LifetimeMismatchOpaqueParam;
|
||||
use crate::type_check::canonical::fully_perform_op_raw;
|
||||
use crate::type_check::free_region_relations::UniversalRegionRelations;
|
||||
use crate::type_check::{Locations, MirTypeckRegionConstraints};
|
||||
use crate::universal_regions::{RegionClassification, UniversalRegions};
|
||||
use crate::{BorrowckInferCtxt, CollectRegionConstraintsResult};
|
||||
|
||||
mod member_constraints;
|
||||
mod region_ctxt;
|
||||
|
|
@ -126,6 +126,31 @@ fn nll_var_to_universal_region<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Record info needed to report the same name error later.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) struct UnexpectedHiddenRegion<'tcx> {
|
||||
// The def_id of the body where this error occurs.
|
||||
// Needed to handle region vars with their corresponding `infcx`.
|
||||
def_id: LocalDefId,
|
||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
hidden_type: ProvisionalHiddenType<'tcx>,
|
||||
member_region: Region<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> UnexpectedHiddenRegion<'tcx> {
|
||||
pub(crate) fn to_error(self) -> (LocalDefId, DeferredOpaqueTypeError<'tcx>) {
|
||||
let UnexpectedHiddenRegion { def_id, opaque_type_key, hidden_type, member_region } = self;
|
||||
(
|
||||
def_id,
|
||||
DeferredOpaqueTypeError::UnexpectedHiddenRegion {
|
||||
opaque_type_key,
|
||||
hidden_type,
|
||||
member_region,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all defining uses of opaque types inside of this typeck root. This
|
||||
/// expects the hidden type to be mapped to the definition parameters of the opaque
|
||||
/// and errors if we end up with distinct hidden types.
|
||||
|
|
@ -176,11 +201,13 @@ struct DefiningUse<'tcx> {
|
|||
/// It also means that this whole function is not really soundness critical as we
|
||||
/// recheck all uses of the opaques regardless.
|
||||
pub(crate) fn compute_definition_site_hidden_types<'tcx>(
|
||||
def_id: LocalDefId,
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
|
||||
constraints: &MirTypeckRegionConstraints<'tcx>,
|
||||
location_map: Rc<DenseLocationMap>,
|
||||
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
|
||||
unconstrained_hidden_type_errors: &mut Vec<UnexpectedHiddenRegion<'tcx>>,
|
||||
opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)],
|
||||
) -> Vec<DeferredOpaqueTypeError<'tcx>> {
|
||||
let mut errors = Vec::new();
|
||||
|
|
@ -204,8 +231,10 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>(
|
|||
// up equal to one of their choice regions and compute the actual hidden type of
|
||||
// the opaque type definition. This is stored in the `root_cx`.
|
||||
compute_definition_site_hidden_types_from_defining_uses(
|
||||
def_id,
|
||||
&rcx,
|
||||
hidden_types,
|
||||
unconstrained_hidden_type_errors,
|
||||
&defining_uses,
|
||||
&mut errors,
|
||||
);
|
||||
|
|
@ -274,8 +303,10 @@ fn collect_defining_uses<'tcx>(
|
|||
|
||||
#[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))]
|
||||
fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
|
||||
def_id: LocalDefId,
|
||||
rcx: &RegionCtxt<'_, 'tcx>,
|
||||
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
|
||||
unconstrained_hidden_type_errors: &mut Vec<UnexpectedHiddenRegion<'tcx>>,
|
||||
defining_uses: &[DefiningUse<'tcx>],
|
||||
errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
|
||||
) {
|
||||
|
|
@ -293,16 +324,29 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
|
|||
Ok(hidden_type) => hidden_type,
|
||||
Err(r) => {
|
||||
debug!("UnexpectedHiddenRegion: {:?}", r);
|
||||
errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
|
||||
hidden_type,
|
||||
opaque_type_key,
|
||||
member_region: ty::Region::new_var(tcx, r),
|
||||
});
|
||||
let guar = tcx.dcx().span_delayed_bug(
|
||||
hidden_type.span,
|
||||
"opaque type with non-universal region args",
|
||||
);
|
||||
ty::ProvisionalHiddenType::new_error(tcx, guar)
|
||||
// If we're using the next solver, the unconstrained region may be resolved by a
|
||||
// fully defining use from another body.
|
||||
// So we don't generate error eagerly here.
|
||||
if rcx.infcx.tcx.use_typing_mode_borrowck() {
|
||||
unconstrained_hidden_type_errors.push(UnexpectedHiddenRegion {
|
||||
def_id,
|
||||
hidden_type,
|
||||
opaque_type_key,
|
||||
member_region: ty::Region::new_var(tcx, r),
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
|
||||
hidden_type,
|
||||
opaque_type_key,
|
||||
member_region: ty::Region::new_var(tcx, r),
|
||||
});
|
||||
let guar = tcx.dcx().span_delayed_bug(
|
||||
hidden_type.span,
|
||||
"opaque type with non-universal region args",
|
||||
);
|
||||
ty::ProvisionalHiddenType::new_error(tcx, guar)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -570,6 +614,40 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
|
|||
errors
|
||||
}
|
||||
|
||||
/// We handle `UnexpectedHiddenRegion` error lazily in the next solver as
|
||||
/// there may be a fully defining use in another body.
|
||||
///
|
||||
/// In case such a defining use does not exist, we register an error here.
|
||||
pub(crate) fn handle_unconstrained_hidden_type_errors<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
|
||||
unconstrained_hidden_type_errors: &mut Vec<UnexpectedHiddenRegion<'tcx>>,
|
||||
collect_region_constraints_results: &mut FxIndexMap<
|
||||
LocalDefId,
|
||||
CollectRegionConstraintsResult<'tcx>,
|
||||
>,
|
||||
) {
|
||||
let mut unconstrained_hidden_type_errors = std::mem::take(unconstrained_hidden_type_errors);
|
||||
unconstrained_hidden_type_errors
|
||||
.retain(|unconstrained| !hidden_types.contains_key(&unconstrained.opaque_type_key.def_id));
|
||||
|
||||
unconstrained_hidden_type_errors.iter().for_each(|t| {
|
||||
tcx.dcx()
|
||||
.span_delayed_bug(t.hidden_type.span, "opaque type with non-universal region args");
|
||||
});
|
||||
|
||||
// `UnexpectedHiddenRegion` error contains region var which only makes sense in the
|
||||
// corresponding `infcx`.
|
||||
// So we need to insert the error to the body where it originates from.
|
||||
for error in unconstrained_hidden_type_errors {
|
||||
let (def_id, error) = error.to_error();
|
||||
let Some(result) = collect_region_constraints_results.get_mut(&def_id) else {
|
||||
unreachable!("the body should depend on opaques type if it has opaque use");
|
||||
};
|
||||
result.deferred_opaque_type_errors.push(error);
|
||||
}
|
||||
}
|
||||
|
||||
/// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types.
|
||||
/// We do not check these new uses so this could be unsound.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ use smallvec::SmallVec;
|
|||
use crate::consumers::BorrowckConsumer;
|
||||
use crate::nll::compute_closure_requirements_modulo_opaques;
|
||||
use crate::region_infer::opaque_types::{
|
||||
apply_definition_site_hidden_types, clone_and_resolve_opaque_types,
|
||||
UnexpectedHiddenRegion, apply_definition_site_hidden_types, clone_and_resolve_opaque_types,
|
||||
compute_definition_site_hidden_types, detect_opaque_types_added_while_handling_opaque_types,
|
||||
handle_unconstrained_hidden_type_errors,
|
||||
};
|
||||
use crate::type_check::{Locations, constraint_conversion};
|
||||
use crate::{
|
||||
|
|
@ -26,7 +27,12 @@ use crate::{
|
|||
pub(super) struct BorrowCheckRootCtxt<'tcx> {
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
root_def_id: LocalDefId,
|
||||
/// This contains fully resolved hidden types or `ty::Error`.
|
||||
hidden_types: FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
|
||||
/// This contains unconstrained regions in hidden types.
|
||||
/// Only used for deferred error reporting. See
|
||||
/// [`crate::region_infer::opaque_types::handle_unconstrained_hidden_type_errors`]
|
||||
unconstrained_hidden_type_errors: Vec<UnexpectedHiddenRegion<'tcx>>,
|
||||
/// The region constraints computed by [borrowck_collect_region_constraints]. This uses
|
||||
/// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before
|
||||
/// their parents.
|
||||
|
|
@ -49,6 +55,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
|
|||
tcx,
|
||||
root_def_id,
|
||||
hidden_types: Default::default(),
|
||||
unconstrained_hidden_type_errors: Default::default(),
|
||||
collect_region_constraints_results: Default::default(),
|
||||
propagated_borrowck_results: Default::default(),
|
||||
tainted_by_errors: None,
|
||||
|
|
@ -84,23 +91,32 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
|
|||
|
||||
fn handle_opaque_type_uses(&mut self) {
|
||||
let mut per_body_info = Vec::new();
|
||||
for input in self.collect_region_constraints_results.values_mut() {
|
||||
for (def_id, input) in &mut self.collect_region_constraints_results {
|
||||
let (num_entries, opaque_types) = clone_and_resolve_opaque_types(
|
||||
&input.infcx,
|
||||
&input.universal_region_relations,
|
||||
&mut input.constraints,
|
||||
);
|
||||
input.deferred_opaque_type_errors = compute_definition_site_hidden_types(
|
||||
*def_id,
|
||||
&input.infcx,
|
||||
&input.universal_region_relations,
|
||||
&input.constraints,
|
||||
Rc::clone(&input.location_map),
|
||||
&mut self.hidden_types,
|
||||
&mut self.unconstrained_hidden_type_errors,
|
||||
&opaque_types,
|
||||
);
|
||||
per_body_info.push((num_entries, opaque_types));
|
||||
}
|
||||
|
||||
handle_unconstrained_hidden_type_errors(
|
||||
self.tcx,
|
||||
&mut self.hidden_types,
|
||||
&mut self.unconstrained_hidden_type_errors,
|
||||
&mut self.collect_region_constraints_results,
|
||||
);
|
||||
|
||||
for (input, (opaque_types_storage_num_entries, opaque_types)) in
|
||||
self.collect_region_constraints_results.values_mut().zip(per_body_info)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Note: please avoid adding other feature gates where possible
|
||||
#![feature(rustc_private)]
|
||||
// Only used to define intrinsics in `compiler_builtins.rs`.
|
||||
#![feature(f16)]
|
||||
#![feature(f128)]
|
||||
#![cfg_attr(feature = "jit", feature(f16))]
|
||||
#![cfg_attr(feature = "jit", feature(f128))]
|
||||
// Note: please avoid adding other feature gates where possible
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![warn(unreachable_pub)]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ module to generate correct metadata and insert it into the LLVM IR.
|
|||
As the exact format of metadata trees may change between different LLVM
|
||||
versions, we now use LLVM
|
||||
[DIBuilder](https://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html)
|
||||
to create metadata where possible. This will hopefully ease the adaption of
|
||||
to create metadata where possible. This will hopefully ease the adaptation of
|
||||
this module to future LLVM versions.
|
||||
|
||||
The public API of the module is a set of functions that will insert the
|
||||
|
|
@ -87,19 +87,19 @@ describe the type anew. This behavior is encapsulated in the
|
|||
## Source Locations and Line Information
|
||||
|
||||
In addition to data type descriptions the debugging information must also
|
||||
allow to map machine code locations back to source code locations in order
|
||||
allow mapping machine code locations back to source code locations in order
|
||||
to be useful. This functionality is also handled in this module. The
|
||||
following functions allow to control source mappings:
|
||||
following functions allow controlling source mappings:
|
||||
|
||||
+ `set_source_location()`
|
||||
+ `clear_source_location()`
|
||||
+ `start_emitting_source_locations()`
|
||||
|
||||
`set_source_location()` allows to set the current source location. All IR
|
||||
`set_source_location()` allows setting the current source location. All IR
|
||||
instructions created after a call to this function will be linked to the
|
||||
given source location, until another location is specified with
|
||||
`set_source_location()` or the source location is cleared with
|
||||
`clear_source_location()`. In the later case, subsequent IR instruction
|
||||
`clear_source_location()`. In the latter case, subsequent IR instructions
|
||||
will not be linked to any source location. As you can see, this is a
|
||||
stateful API (mimicking the one in LLVM), so be careful with source
|
||||
locations set by previous calls. It's probably best to not rely on any
|
||||
|
|
|
|||
|
|
@ -471,9 +471,9 @@ fn report_eval_error<'tcx>(
|
|||
span,
|
||||
inline_fluent!(
|
||||
"evaluation of `{$instance}` failed {$num_frames ->
|
||||
[0] here
|
||||
*[other] inside this call
|
||||
}"
|
||||
[0] here
|
||||
*[other] inside this call
|
||||
}"
|
||||
),
|
||||
);
|
||||
for frame in frames {
|
||||
|
|
|
|||
|
|
@ -491,10 +491,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
|||
Err(err) => throw_ub_custom!(
|
||||
inline_fluent!(
|
||||
"invalid align passed to `{$name}`: {$align} is {$err_kind ->
|
||||
[not_power_of_two] not a power of 2
|
||||
[too_large] too large
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
[not_power_of_two] not a power of 2
|
||||
[too_large] too large
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
),
|
||||
name = "const_allocate",
|
||||
err_kind = err.diag_ident(),
|
||||
|
|
@ -521,10 +521,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
|||
Err(err) => throw_ub_custom!(
|
||||
inline_fluent!(
|
||||
"invalid align passed to `{$name}`: {$align} is {$err_kind ->
|
||||
[not_power_of_two] not a power of 2
|
||||
[too_large] too large
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
[not_power_of_two] not a power of 2
|
||||
[too_large] too large
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
),
|
||||
name = "const_deallocate",
|
||||
err_kind = err.diag_ident(),
|
||||
|
|
|
|||
|
|
@ -393,16 +393,17 @@ impl Subdiagnostic for FrameNote {
|
|||
}
|
||||
let msg = diag.eagerly_translate(inline_fluent!(
|
||||
r#"{$times ->
|
||||
[0] {const_eval_frame_note_inner}
|
||||
*[other] [... {$times} additional calls {const_eval_frame_note_inner} ...]
|
||||
}
|
||||
|
||||
const_eval_frame_note_inner = inside {$where_ ->
|
||||
[closure] closure
|
||||
[instance] `{$instance}`
|
||||
*[other] {""}
|
||||
}
|
||||
"#
|
||||
[0] inside {$where_ ->
|
||||
[closure] closure
|
||||
[instance] `{$instance}`
|
||||
*[other] {""}
|
||||
}
|
||||
*[other] [... {$times} additional calls inside {$where_ ->
|
||||
[closure] closure
|
||||
[instance] `{$instance}`
|
||||
*[other] {""}
|
||||
} ...]
|
||||
}"#
|
||||
));
|
||||
diag.remove_arg("times");
|
||||
diag.remove_arg("where_");
|
||||
|
|
@ -663,89 +664,96 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
InvalidMeta(InvalidMetaKind::SliceTooBig) => "invalid metadata in wide pointer: slice is bigger than largest supported object".into(),
|
||||
InvalidMeta(InvalidMetaKind::TooBig) => "invalid metadata in wide pointer: total size is bigger than largest supported object".into(),
|
||||
UnterminatedCString(_) => "reading a null-terminated string starting at {$pointer} with no null found before end of allocation".into(),
|
||||
PointerUseAfterFree(_, _) => inline_fluent!("{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$alloc_id} has been freed, so this pointer is dangling"),
|
||||
PointerOutOfBounds { .. } => inline_fluent!("{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$operation ->
|
||||
[MemoryAccess] attempting to access {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
*[Dereferenceable] pointer must {$inbounds_size ->
|
||||
[0] point to some allocation
|
||||
[1] be dereferenceable for 1 byte
|
||||
*[x] be dereferenceable for {$inbounds_size} bytes
|
||||
}
|
||||
}, but got {$pointer} which {$ptr_offset_is_neg ->
|
||||
[true] points to before the beginning of the allocation
|
||||
*[false] {$inbounds_size_is_neg ->
|
||||
[false] {$alloc_size_minus_ptr_offset ->
|
||||
[0] is at or beyond the end of the allocation of size {$alloc_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$alloc_size} bytes
|
||||
}
|
||||
[1] is only 1 byte from the end of the allocation
|
||||
*[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation
|
||||
}
|
||||
*[true] {$ptr_offset_abs ->
|
||||
[0] is at the beginning of the allocation
|
||||
*[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation
|
||||
}
|
||||
}
|
||||
}
|
||||
"),
|
||||
DanglingIntPointer { addr: 0, .. } => inline_fluent!("{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$operation ->
|
||||
[MemoryAccess] attempting to access {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
*[Dereferenceable] pointer must {$inbounds_size ->
|
||||
[0] point to some allocation
|
||||
[1] be dereferenceable for 1 byte
|
||||
*[x] be dereferenceable for {$inbounds_size} bytes
|
||||
}
|
||||
}, but got null pointer"),
|
||||
DanglingIntPointer { .. } => inline_fluent!("{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$operation ->
|
||||
[MemoryAccess] attempting to access {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
*[Dereferenceable] pointer must {$inbounds_size ->
|
||||
[0] point to some allocation
|
||||
[1] be dereferenceable for 1 byte
|
||||
*[x] be dereferenceable for {$inbounds_size} bytes
|
||||
}
|
||||
}, but got {$pointer} which is a dangling pointer (it has no provenance)"),
|
||||
AlignmentCheckFailed { .. } => inline_fluent!("{$msg ->
|
||||
[AccessedPtr] accessing memory
|
||||
*[other] accessing memory based on pointer
|
||||
} with alignment {$has}, but alignment {$required} is required"),
|
||||
PointerUseAfterFree(_, _) => inline_fluent!(
|
||||
"{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$alloc_id} has been freed, so this pointer is dangling"
|
||||
),
|
||||
PointerOutOfBounds { .. } => inline_fluent!(
|
||||
"{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$operation ->
|
||||
[MemoryAccess] attempting to access {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
*[Dereferenceable] pointer must {$inbounds_size ->
|
||||
[0] point to some allocation
|
||||
[1] be dereferenceable for 1 byte
|
||||
*[x] be dereferenceable for {$inbounds_size} bytes
|
||||
}
|
||||
}, but got {$pointer} which {$ptr_offset_is_neg ->
|
||||
[true] points to before the beginning of the allocation
|
||||
*[false] {$inbounds_size_is_neg ->
|
||||
[false] {$alloc_size_minus_ptr_offset ->
|
||||
[0] is at or beyond the end of the allocation of size {$alloc_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$alloc_size} bytes
|
||||
}
|
||||
[1] is only 1 byte from the end of the allocation
|
||||
*[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation
|
||||
}
|
||||
*[true] {$ptr_offset_abs ->
|
||||
[0] is at the beginning of the allocation
|
||||
*[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation
|
||||
}
|
||||
}
|
||||
}"
|
||||
),
|
||||
DanglingIntPointer { addr: 0, .. } => inline_fluent!(
|
||||
"{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$operation ->
|
||||
[MemoryAccess] attempting to access {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
*[Dereferenceable] pointer must {$inbounds_size ->
|
||||
[0] point to some allocation
|
||||
[1] be dereferenceable for 1 byte
|
||||
*[x] be dereferenceable for {$inbounds_size} bytes
|
||||
}
|
||||
}, but got null pointer"),
|
||||
DanglingIntPointer { .. } => inline_fluent!(
|
||||
"{$operation ->
|
||||
[MemoryAccess] memory access failed
|
||||
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
|
||||
*[Dereferenceable] pointer not dereferenceable
|
||||
}: {$operation ->
|
||||
[MemoryAccess] attempting to access {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
|
||||
[1] 1 byte
|
||||
*[x] {$inbounds_size} bytes
|
||||
}
|
||||
*[Dereferenceable] pointer must {$inbounds_size ->
|
||||
[0] point to some allocation
|
||||
[1] be dereferenceable for 1 byte
|
||||
*[x] be dereferenceable for {$inbounds_size} bytes
|
||||
}
|
||||
}, but got {$pointer} which is a dangling pointer (it has no provenance)"),
|
||||
AlignmentCheckFailed { .. } => inline_fluent!(
|
||||
"{$msg ->
|
||||
[AccessedPtr] accessing memory
|
||||
*[other] accessing memory based on pointer
|
||||
} with alignment {$has}, but alignment {$required} is required"
|
||||
),
|
||||
WriteToReadOnly(_) => inline_fluent!("writing to {$allocation} which is read-only"),
|
||||
DerefFunctionPointer(_) => inline_fluent!("accessing {$allocation} which contains a function"),
|
||||
DerefVTablePointer(_) => inline_fluent!("accessing {$allocation} which contains a vtable"),
|
||||
|
|
@ -936,9 +944,9 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
NullFnPtr { .. } => {
|
||||
inline_fluent!(
|
||||
"{$front_matter}: encountered a {$maybe ->
|
||||
[true] maybe-null
|
||||
*[false] null
|
||||
} function pointer"
|
||||
[true] maybe-null
|
||||
*[false] null
|
||||
} function pointer"
|
||||
)
|
||||
}
|
||||
NeverVal => {
|
||||
|
|
@ -1021,17 +1029,17 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
NullPtr { ptr_kind: PointerKind::Box, .. } => {
|
||||
inline_fluent!(
|
||||
"{$front_matter}: encountered a {$maybe ->
|
||||
[true] maybe-null
|
||||
*[false] null
|
||||
} box"
|
||||
[true] maybe-null
|
||||
*[false] null
|
||||
} box"
|
||||
)
|
||||
}
|
||||
NullPtr { ptr_kind: PointerKind::Ref(_), .. } => {
|
||||
inline_fluent!(
|
||||
"{$front_matter}: encountered a {$maybe ->
|
||||
[true] maybe-null
|
||||
*[false] null
|
||||
} reference"
|
||||
[true] maybe-null
|
||||
*[false] null
|
||||
} reference"
|
||||
)
|
||||
}
|
||||
DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
|
||||
|
|
|
|||
|
|
@ -466,10 +466,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
// a < b
|
||||
if intrinsic_name == sym::ptr_offset_from_unsigned {
|
||||
throw_ub_custom!(
|
||||
inline_fluent!("`ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr ->
|
||||
[true] address
|
||||
*[false] offset
|
||||
} than second: {$a_offset} < {$b_offset}"),
|
||||
inline_fluent!(
|
||||
"`ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr ->
|
||||
[true] address
|
||||
*[false] offset
|
||||
} than second: {$a_offset} < {$b_offset}"
|
||||
),
|
||||
a_offset = a_offset,
|
||||
b_offset = b_offset,
|
||||
is_addr = is_addr,
|
||||
|
|
|
|||
|
|
@ -293,10 +293,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
throw_ub_custom!(
|
||||
inline_fluent!(
|
||||
"{$kind ->
|
||||
[dealloc] deallocating
|
||||
[realloc] reallocating
|
||||
*[other] {\"\"}
|
||||
} {$ptr} which does not point to the beginning of an object"
|
||||
[dealloc] deallocating
|
||||
[realloc] reallocating
|
||||
*[other] {\"\"}
|
||||
} {$ptr} which does not point to the beginning of an object"
|
||||
),
|
||||
ptr = format!("{ptr:?}"),
|
||||
kind = "realloc"
|
||||
|
|
@ -379,10 +379,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
throw_ub_custom!(
|
||||
inline_fluent!(
|
||||
"{$kind ->
|
||||
[dealloc] deallocating
|
||||
[realloc] reallocating
|
||||
*[other] {\"\"}
|
||||
} {$ptr} which does not point to the beginning of an object"
|
||||
[dealloc] deallocating
|
||||
[realloc] reallocating
|
||||
*[other] {\"\"}
|
||||
} {$ptr} which does not point to the beginning of an object"
|
||||
),
|
||||
ptr = format!("{ptr:?}"),
|
||||
kind = "dealloc",
|
||||
|
|
@ -396,11 +396,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
err_ub_custom!(
|
||||
inline_fluent!(
|
||||
"deallocating {$alloc_id}, which is {$kind ->
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
),
|
||||
alloc_id = alloc_id,
|
||||
kind = "fn",
|
||||
|
|
@ -410,11 +410,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
err_ub_custom!(
|
||||
inline_fluent!(
|
||||
"deallocating {$alloc_id}, which is {$kind ->
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
),
|
||||
alloc_id = alloc_id,
|
||||
kind = "vtable",
|
||||
|
|
@ -424,11 +424,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
err_ub_custom!(
|
||||
inline_fluent!(
|
||||
"deallocating {$alloc_id}, which is {$kind ->
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
),
|
||||
alloc_id = alloc_id,
|
||||
kind = "typeid",
|
||||
|
|
@ -438,11 +438,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
err_ub_custom!(
|
||||
inline_fluent!(
|
||||
"deallocating {$alloc_id}, which is {$kind ->
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
[fn] a function
|
||||
[vtable] a vtable
|
||||
[static_mem] static memory
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
),
|
||||
alloc_id = alloc_id,
|
||||
kind = "static_mem"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#![allow(rustc::potential_query_instability)]
|
||||
#![cfg_attr(bootstrap, feature(assert_matches))]
|
||||
#![cfg_attr(bootstrap, feature(cold_path))]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(ascii_char)]
|
||||
|
|
@ -30,7 +31,6 @@
|
|||
#![feature(ptr_alignment_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(sized_hierarchy)]
|
||||
#![feature(test)]
|
||||
#![feature(thread_id_value)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
|
|
|||
|
|
@ -60,11 +60,13 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
|
|||
.with_arg("cause", cause)
|
||||
}
|
||||
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
|
||||
Diag::new(dcx, level, inline_fluent!("invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind ->
|
||||
[not_power_of_two] not a power of 2
|
||||
[too_large] too large
|
||||
*[other] {\"\"}
|
||||
}"))
|
||||
Diag::new(dcx, level, inline_fluent!(
|
||||
"invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind ->
|
||||
[not_power_of_two] not a power of 2
|
||||
[too_large] too large
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
))
|
||||
.with_arg("cause", cause)
|
||||
.with_arg("err_kind", err.diag_ident())
|
||||
.with_arg("align", err.align())
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(yeet_expr)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
extern crate self as rustc_errors;
|
||||
|
|
@ -63,6 +61,7 @@ pub use rustc_error_messages::{
|
|||
use rustc_hashes::Hash128;
|
||||
use rustc_lint_defs::LintExpectationId;
|
||||
pub use rustc_lint_defs::{Applicability, listify, pluralize};
|
||||
pub use rustc_macros::inline_fluent;
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
pub use rustc_span::ErrorGuaranteed;
|
||||
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors};
|
||||
|
|
@ -1561,7 +1560,7 @@ impl DelayedDiagInner {
|
|||
let msg = match self.note.status() {
|
||||
BacktraceStatus::Captured => inline_fluent!(
|
||||
"delayed at {$emitted_at}
|
||||
{$note}"
|
||||
{$note}"
|
||||
),
|
||||
// Avoid the needless newline when no backtrace has been captured,
|
||||
// the display impl should just be a single line.
|
||||
|
|
|
|||
|
|
@ -90,14 +90,3 @@ impl Translator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This macro creates a translatable `DiagMessage` from a literal string.
|
||||
/// It should be used in places where a translatable message is needed, but struct diagnostics are undesired.
|
||||
///
|
||||
/// This is a macro because in the future we may want to globally register these messages.
|
||||
#[macro_export]
|
||||
macro_rules! inline_fluent {
|
||||
($inline: literal) => {
|
||||
rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed($inline))
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -919,7 +919,7 @@ impl SyntaxExtension {
|
|||
fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool {
|
||||
// FIXME(estebank): instead of reusing `#[rustc_diagnostic_item]` as a proxy, introduce a
|
||||
// new attribute purely for this under the `#[diagnostic]` namespace.
|
||||
ast::attr::find_by_name(attrs, sym::rustc_diagnostic_item).is_some()
|
||||
find_attr!(attrs, AttributeKind::RustcDiagnosticItem(..))
|
||||
}
|
||||
|
||||
/// Constructs a syntax extension with the given properties
|
||||
|
|
|
|||
|
|
@ -862,13 +862,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
register_tool, CrateLevel, template!(List: &["tool1, tool2, ..."]), DuplicatesOk,
|
||||
EncodeCrossCrate::No, experimental!(register_tool),
|
||||
),
|
||||
|
||||
// lang-team MCP 147
|
||||
gated!(
|
||||
deprecated_safe, Normal, template!(List: &[r#"since = "version", note = "...""#]), ErrorFollowing,
|
||||
EncodeCrossCrate::Yes, experimental!(deprecated_safe),
|
||||
),
|
||||
|
||||
// `#[cfi_encoding = ""]`
|
||||
gated!(
|
||||
cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding,
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ declare_features! (
|
|||
/// Allows default type parameters to influence type inference.
|
||||
(removed, default_type_parameter_fallback, "1.82.0", Some(27336),
|
||||
Some("never properly implemented; requires significant design work"), 127655),
|
||||
/// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait
|
||||
(removed, deprecated_safe, "CURRENT_RUSTC_VERSION", Some(94978), Some("never properly implemented, in the way of attribute refactor"), 152554),
|
||||
/// Allows deriving traits as per `SmartPointer` specification
|
||||
(removed, derive_smart_pointer, "1.84.0", Some(123430), Some("replaced by `CoercePointee`"), 131284),
|
||||
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
|
||||
|
|
|
|||
|
|
@ -454,8 +454,6 @@ declare_features! (
|
|||
/// Allows the use of default values on struct definitions and the construction of struct
|
||||
/// literals with the functional update syntax without a base.
|
||||
(unstable, default_field_values, "1.85.0", Some(132162)),
|
||||
/// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait
|
||||
(unstable, deprecated_safe, "1.61.0", Some(94978)),
|
||||
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
|
||||
(unstable, deprecated_suggestion, "1.61.0", Some(94785)),
|
||||
/// Allows deref patterns.
|
||||
|
|
|
|||
|
|
@ -1156,6 +1156,9 @@ pub enum AttributeKind {
|
|||
/// Represents `#[rustc_deprecated_safe_2024]`
|
||||
RustcDeprecatedSafe2024 { suggestion: Symbol },
|
||||
|
||||
/// Represents `#[rustc_diagnostic_item]`
|
||||
RustcDiagnosticItem(Symbol),
|
||||
|
||||
/// Represents `#[rustc_dummy]`.
|
||||
RustcDummy,
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ impl AttributeKind {
|
|||
RustcDelayedBugFromInsideQuery => No,
|
||||
RustcDenyExplicitImpl(..) => No,
|
||||
RustcDeprecatedSafe2024 { .. } => Yes,
|
||||
RustcDiagnosticItem(..) => Yes,
|
||||
RustcDummy => No,
|
||||
RustcDumpDefParents => No,
|
||||
RustcDumpItemBounds => No,
|
||||
|
|
|
|||
|
|
@ -1063,6 +1063,70 @@ fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
|
|||
)
|
||||
}
|
||||
|
||||
/// Convert `ReLateParam`s in `value` back into `ReBound`s and bind it with `bound_vars`.
|
||||
fn late_param_regions_to_bound<'tcx, T>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
scope: DefId,
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind<'tcx>>,
|
||||
value: T,
|
||||
) -> ty::Binder<'tcx, T>
|
||||
where
|
||||
T: ty::TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let value = fold_regions(tcx, value, |r, debruijn| match r.kind() {
|
||||
ty::ReLateParam(lp) => {
|
||||
// Should be in scope, otherwise inconsistency happens somewhere.
|
||||
assert_eq!(lp.scope, scope);
|
||||
|
||||
let br = match lp.kind {
|
||||
// These variants preserve the bound var index.
|
||||
kind @ (ty::LateParamRegionKind::Anon(idx)
|
||||
| ty::LateParamRegionKind::NamedAnon(idx, _)) => {
|
||||
let idx = idx as usize;
|
||||
let var = ty::BoundVar::from_usize(idx);
|
||||
|
||||
let Some(ty::BoundVariableKind::Region(kind)) = bound_vars.get(idx).copied()
|
||||
else {
|
||||
bug!("unexpected late-bound region {kind:?} for bound vars {bound_vars:?}");
|
||||
};
|
||||
|
||||
ty::BoundRegion { var, kind }
|
||||
}
|
||||
|
||||
// For named regions, look up the corresponding bound var.
|
||||
ty::LateParamRegionKind::Named(def_id) => bound_vars
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(idx, bv)| match bv {
|
||||
ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::Named(did))
|
||||
if did == def_id =>
|
||||
{
|
||||
Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap(),
|
||||
|
||||
ty::LateParamRegionKind::ClosureEnv => bound_vars
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(idx, bv)| match bv {
|
||||
ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::ClosureEnv) => {
|
||||
Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
ty::Region::new_bound(tcx, debruijn, br)
|
||||
}
|
||||
_ => r,
|
||||
});
|
||||
|
||||
ty::Binder::bind_with_vars(value, bound_vars)
|
||||
}
|
||||
|
||||
fn recover_infer_ret_ty<'tcx>(
|
||||
icx: &ItemCtxt<'tcx>,
|
||||
infer_ret_ty: &'tcx hir::Ty<'tcx>,
|
||||
|
|
@ -1138,13 +1202,22 @@ fn recover_infer_ret_ty<'tcx>(
|
|||
);
|
||||
}
|
||||
let guar = diag.emit();
|
||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
|
||||
// If we return a dummy binder here, we can ICE later in borrowck when it encounters
|
||||
// `ReLateParam` regions (e.g. in a local type annotation) which weren't registered via the
|
||||
// signature binder. See #135845.
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
let scope = def_id.to_def_id();
|
||||
|
||||
let fn_sig = tcx.mk_fn_sig(
|
||||
fn_sig.inputs().iter().copied(),
|
||||
recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
|
||||
fn_sig.c_variadic,
|
||||
fn_sig.safety,
|
||||
fn_sig.abi,
|
||||
))
|
||||
);
|
||||
|
||||
late_param_regions_to_bound(tcx, scope, bound_vars, fn_sig)
|
||||
}
|
||||
|
||||
pub fn suggest_impl_trait<'tcx>(
|
||||
|
|
|
|||
|
|
@ -2465,7 +2465,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let parent_did = tcx.parent(*def_id);
|
||||
(tcx.adt_def(parent_did), fn_args, parent_did)
|
||||
}
|
||||
_ => return non_adt_or_variant_res(),
|
||||
_ => {
|
||||
let e = self.dcx().span_err(
|
||||
span,
|
||||
"complex const arguments must be placed inside of a `const` block",
|
||||
);
|
||||
return Const::new_error(tcx, e);
|
||||
}
|
||||
};
|
||||
|
||||
let variant_def = adt_def.variant_with_id(variant_did);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// tidy-alphabetical-start
|
||||
#![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))]
|
||||
#![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))]
|
||||
#![cfg_attr(all(feature = "nightly", test), feature(test))]
|
||||
#![cfg_attr(feature = "nightly", feature(extend_one, step_trait))]
|
||||
#![cfg_attr(feature = "nightly", feature(new_range_api))]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
|
|
|
|||
|
|
@ -446,7 +446,7 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> {
|
|||
"specifically, {$num_captured ->
|
||||
[one] this lifetime is
|
||||
*[other] these lifetimes are
|
||||
} in scope but not mentioned in the type's bounds"
|
||||
} in scope but not mentioned in the type's bounds"
|
||||
),
|
||||
)
|
||||
.note(inline_fluent!(
|
||||
|
|
|
|||
|
|
@ -353,8 +353,10 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> {
|
|||
self.label,
|
||||
inline_fluent!("will not be checked at usage sites of the type alias"),
|
||||
);
|
||||
diag.note(inline_fluent!("this is a known limitation of the type checker that may be lifted in a future edition.
|
||||
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information"));
|
||||
diag.note(inline_fluent!(
|
||||
"this is a known limitation of the type checker that may be lifted in a future edition.
|
||||
see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information"
|
||||
));
|
||||
if self.enable_feat_help {
|
||||
diag.help(inline_fluent!("add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics"));
|
||||
}
|
||||
|
|
@ -1748,10 +1750,12 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
|
|||
if doctest {
|
||||
diag.help(inline_fluent!(r#"remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`"#));
|
||||
} else {
|
||||
diag.help(inline_fluent!("remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->
|
||||
[one] `{$body_name}`
|
||||
*[other] `{$body_name}` and up {$depth} bodies
|
||||
}"));
|
||||
diag.help(inline_fluent!(
|
||||
"remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->
|
||||
[one] `{$body_name}`
|
||||
*[other] `{$body_name}` and up {$depth} bodies
|
||||
}"
|
||||
));
|
||||
}
|
||||
|
||||
diag.note(inline_fluent!("a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute"));
|
||||
|
|
|
|||
|
|
@ -196,10 +196,12 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
|
|||
if let Some((open, close, del)) = find_delimiters(cx, span) {
|
||||
lint.arg("already_suggested", suggest_display || suggest_debug);
|
||||
lint.multipart_suggestion(
|
||||
inline_fluent!("{$already_suggested ->
|
||||
[true] or use
|
||||
*[false] use
|
||||
} std::panic::panic_any instead"),
|
||||
inline_fluent!(
|
||||
"{$already_suggested ->
|
||||
[true] or use
|
||||
*[false] use
|
||||
} std::panic::panic_any instead"
|
||||
),
|
||||
if del == '(' {
|
||||
vec![(span.until(open), "std::panic::panic_any".into())]
|
||||
} else {
|
||||
|
|
|
|||
10
compiler/rustc_macros/src/diagnostics/inline_fluent.rs
Normal file
10
compiler/rustc_macros/src/diagnostics/inline_fluent.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
use syn::{LitStr, parse_macro_input};
|
||||
|
||||
use crate::diagnostics::message::Message;
|
||||
|
||||
pub(crate) fn inline_fluent(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let inline = parse_macro_input!(input as LitStr);
|
||||
let message =
|
||||
Message { attr_span: inline.span(), message_span: inline.span(), value: inline.value() };
|
||||
message.diag_message(None).into()
|
||||
}
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
mod diagnostic;
|
||||
mod diagnostic_builder;
|
||||
mod error;
|
||||
mod inline_fluent;
|
||||
mod message;
|
||||
mod subdiagnostic;
|
||||
mod utils;
|
||||
|
||||
use diagnostic::{DiagnosticDerive, LintDiagnosticDerive};
|
||||
pub(super) use inline_fluent::inline_fluent;
|
||||
use proc_macro2::TokenStream;
|
||||
use subdiagnostic::SubdiagnosticDerive;
|
||||
use synstructure::Structure;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// tidy-alphabetical-start
|
||||
#![allow(rustc::default_hash_types)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(never_type)]
|
||||
#![feature(proc_macro_diagnostic)]
|
||||
#![feature(proc_macro_tracked_env)]
|
||||
|
|
@ -241,6 +240,15 @@ decl_derive!(
|
|||
applicability)] => diagnostics::subdiagnostic_derive
|
||||
);
|
||||
|
||||
/// This macro creates a translatable `DiagMessage` from a fluent format string.
|
||||
/// It should be used in places where a translatable message is needed, but struct diagnostics are undesired.
|
||||
///
|
||||
/// This macro statically checks that the message is valid Fluent, but not that variables in the Fluent message actually exist.
|
||||
#[proc_macro]
|
||||
pub fn inline_fluent(input: TokenStream) -> TokenStream {
|
||||
diagnostics::inline_fluent(input)
|
||||
}
|
||||
|
||||
decl_derive! {
|
||||
[PrintAttribute] =>
|
||||
/// Derives `PrintAttribute` for `AttributeKind`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// tidy-alphabetical-start
|
||||
#![allow(internal_features)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(error_iter)]
|
||||
#![feature(file_buffered)]
|
||||
#![feature(gen_blocks)]
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(rustc::direct_use_of_rustc_type_ir)]
|
||||
#![cfg_attr(bootstrap, feature(assert_matches))]
|
||||
#![cfg_attr(doc, feature(intra_doc_pointers))]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![feature(box_as_ptr)]
|
||||
|
|
@ -43,7 +44,6 @@
|
|||
#![feature(file_buffered)]
|
||||
#![feature(gen_blocks)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(intra_doc_pointers)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
|
|
@ -56,7 +56,6 @@
|
|||
#![feature(try_trait_v2_residual)]
|
||||
#![feature(try_trait_v2_yeet)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![feature(yeet_expr)]
|
||||
#![recursion_limit = "256"]
|
||||
// tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -128,19 +128,25 @@ pub struct Deprecated {
|
|||
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
|
||||
diag.primary_message(match &self.since_kind {
|
||||
DeprecatedSinceKind::InEffect => inline_fluent!("use of deprecated {$kind} `{$path}`{$has_note ->
|
||||
[true] : {$note}
|
||||
*[other] {\"\"}
|
||||
}"),
|
||||
DeprecatedSinceKind::InFuture => inline_fluent!("use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
|
||||
[true] : {$note}
|
||||
*[other] {\"\"}
|
||||
}"),
|
||||
DeprecatedSinceKind::InVersion(_) => {
|
||||
inline_fluent!("use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
|
||||
DeprecatedSinceKind::InEffect => inline_fluent!(
|
||||
"use of deprecated {$kind} `{$path}`{$has_note ->
|
||||
[true] : {$note}
|
||||
*[other] {\"\"}
|
||||
}")
|
||||
}"
|
||||
),
|
||||
DeprecatedSinceKind::InFuture => inline_fluent!(
|
||||
"use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
|
||||
[true] : {$note}
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
),
|
||||
DeprecatedSinceKind::InVersion(_) => {
|
||||
inline_fluent!(
|
||||
"use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
|
||||
[true] : {$note}
|
||||
*[other] {\"\"}
|
||||
}"
|
||||
)
|
||||
}
|
||||
});
|
||||
diag.arg("kind", self.kind);
|
||||
|
|
|
|||
|
|
@ -542,10 +542,12 @@ impl Subdiagnostic for LocalLabel<'_> {
|
|||
dtor.add_to_diag(diag);
|
||||
}
|
||||
let msg =
|
||||
diag.eagerly_translate(inline_fluent!("{$is_dropped_first_edition_2024 ->
|
||||
[true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024
|
||||
*[false] `{$name}` will be dropped later as of Edition 2024
|
||||
}"));
|
||||
diag.eagerly_translate(inline_fluent!(
|
||||
"{$is_dropped_first_edition_2024 ->
|
||||
[true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024
|
||||
*[false] `{$name}` will be dropped later as of Edition 2024
|
||||
}"
|
||||
));
|
||||
diag.span_label(self.span, msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(assert_matches))]
|
||||
#![cfg_attr(test, feature(iter_order_by))]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(default_field_values)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(iter_order_by)]
|
||||
#![recursion_limit = "256"]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| AttributeKind::RustcDelayedBugFromInsideQuery
|
||||
| AttributeKind::RustcDenyExplicitImpl(..)
|
||||
| AttributeKind::RustcDeprecatedSafe2024 {..}
|
||||
| AttributeKind::RustcDiagnosticItem(..)
|
||||
| AttributeKind::RustcDummy
|
||||
| AttributeKind::RustcDumpDefParents
|
||||
| AttributeKind::RustcDumpItemBounds
|
||||
|
|
@ -392,13 +393,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| sym::warn
|
||||
| sym::deny
|
||||
| sym::forbid
|
||||
// need to be fixed
|
||||
| sym::deprecated_safe // FIXME(deprecated_safe)
|
||||
// internal
|
||||
| sym::panic_handler
|
||||
| sym::lang
|
||||
| sym::default_lib_allocator
|
||||
| sym::rustc_diagnostic_item
|
||||
| sym::rustc_nonnull_optimization_guaranteed
|
||||
| sym::rustc_inherit_overflow_checks
|
||||
| sym::rustc_on_unimplemented
|
||||
|
|
|
|||
|
|
@ -9,20 +9,21 @@
|
|||
//!
|
||||
//! * Compiler internal types like `Ty` and `TyCtxt`
|
||||
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::diagnostic_items::DiagnosticItems;
|
||||
use rustc_hir::{Attribute, CRATE_OWNER_ID, OwnerId};
|
||||
use rustc_hir::{CRATE_OWNER_ID, OwnerId, find_attr};
|
||||
use rustc_middle::query::{LocalCrate, Providers};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_span::{Symbol, sym};
|
||||
|
||||
use crate::errors::DuplicateDiagnosticItemInCrate;
|
||||
|
||||
fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) {
|
||||
let attrs = tcx.hir_attrs(owner.into());
|
||||
if let Some(name) = extract(attrs) {
|
||||
if let Some(name) = find_attr!(attrs, AttributeKind::RustcDiagnosticItem(name) => name) {
|
||||
// insert into our table
|
||||
collect_item(tcx, diagnostic_items, name, owner.to_def_id());
|
||||
collect_item(tcx, diagnostic_items, *name, owner.to_def_id());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,13 +54,6 @@ fn report_duplicate_item(
|
|||
});
|
||||
}
|
||||
|
||||
/// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
|
||||
fn extract(attrs: &[Attribute]) -> Option<Symbol> {
|
||||
attrs.iter().find_map(|attr| {
|
||||
if attr.has_name(sym::rustc_diagnostic_item) { attr.value_str() } else { None }
|
||||
})
|
||||
}
|
||||
|
||||
/// Traverse and collect the diagnostic items in the current
|
||||
fn diagnostic_items(tcx: TyCtxt<'_>, _: LocalCrate) -> DiagnosticItems {
|
||||
// Initialize the collector.
|
||||
|
|
|
|||
|
|
@ -684,9 +684,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NoMainErr {
|
|||
// There were some functions named `main` though. Try to give the user a hint.
|
||||
inline_fluent!(
|
||||
"the main function must be defined at the crate level{$has_filename ->
|
||||
[true] {\" \"}(in `{$filename}`)
|
||||
*[false] {\"\"}
|
||||
}"
|
||||
[true] {\" \"}(in `{$filename}`)
|
||||
*[false] {\"\"}
|
||||
}"
|
||||
)
|
||||
} else if self.has_filename {
|
||||
inline_fluent!("consider adding a `main` function to `{$filename}`")
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@
|
|||
//!
|
||||
//! This API is completely unstable and subject to change.
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(map_try_insert)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
use rustc_middle::query::Providers;
|
||||
|
||||
pub mod abi_test;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
// tidy-alphabetical-start
|
||||
#![allow(unused_crate_dependencies)]
|
||||
#![cfg_attr(feature = "rustc", feature(if_let_guard))]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
pub(crate) mod checks;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
// tidy-alphabetical-start
|
||||
#![allow(rustc::usage_of_ty_tykind)]
|
||||
#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))]
|
||||
#![feature(sized_hierarchy)]
|
||||
#![feature(trait_alias)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
|
|
|
|||
174
compiler/rustc_query_impl/src/dep_kind_vtables.rs
Normal file
174
compiler/rustc_query_impl/src/dep_kind_vtables.rs
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::DepKindVTable;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle};
|
||||
use rustc_query_system::query::QueryCache;
|
||||
|
||||
use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner};
|
||||
use crate::{QueryCtxt, QueryDispatcherUnerased, QueryFlags};
|
||||
|
||||
/// [`DepKindVTable`] constructors for special dep kinds that aren't queries.
|
||||
#[expect(non_snake_case, reason = "use non-snake case to avoid collision with query names")]
|
||||
mod non_query {
|
||||
use super::*;
|
||||
|
||||
// We use this for most things when incr. comp. is turned off.
|
||||
pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: Some(|_, dep_node, _| {
|
||||
bug!("force_from_dep_node: encountered {dep_node:?}")
|
||||
}),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"Null",
|
||||
}
|
||||
}
|
||||
|
||||
// We use this for the forever-red node.
|
||||
pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: Some(|_, dep_node, _| {
|
||||
bug!("force_from_dep_node: encountered {dep_node:?}")
|
||||
}),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"Red",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: Some(|tcx, _, prev_index| {
|
||||
tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index);
|
||||
true
|
||||
}),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"SideEffect",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: true,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Opaque,
|
||||
force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"AnonZeroDeps",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: true,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"TraitSelect",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Opaque,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"CompileCodegenUnit",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Opaque,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"CompileMonoItem",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn Metadata<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"Metadata",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared implementation of the [`DepKindVTable`] constructor for queries.
|
||||
/// Called from macro-generated code for each query.
|
||||
pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q, Cache, const FLAGS: QueryFlags>(
|
||||
is_eval_always: bool,
|
||||
) -> DepKindVTable<'tcx>
|
||||
where
|
||||
Q: QueryDispatcherUnerased<'tcx, Cache, FLAGS>,
|
||||
Cache: QueryCache + 'tcx,
|
||||
{
|
||||
let is_anon = FLAGS.is_anon;
|
||||
let fingerprint_style = if is_anon {
|
||||
FingerprintStyle::Opaque
|
||||
} else {
|
||||
<Cache::Key as DepNodeKey<TyCtxt<'tcx>>>::fingerprint_style()
|
||||
};
|
||||
|
||||
if is_anon || !fingerprint_style.reconstructible() {
|
||||
return DepKindVTable {
|
||||
is_anon,
|
||||
is_eval_always,
|
||||
fingerprint_style,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: Q::NAME,
|
||||
};
|
||||
}
|
||||
|
||||
DepKindVTable {
|
||||
is_anon,
|
||||
is_eval_always,
|
||||
fingerprint_style,
|
||||
force_from_dep_node: Some(|tcx, dep_node, _| {
|
||||
force_from_dep_node_inner(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
try_load_from_on_disk_cache: Some(|tcx, dep_node| {
|
||||
try_load_from_on_disk_cache_inner(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
name: Q::NAME,
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper module containing a [`DepKindVTable`] constructor for each dep kind,
|
||||
/// for use with [`rustc_middle::make_dep_kind_array`].
|
||||
///
|
||||
/// That macro will check that we gave it a constructor for every known dep kind.
|
||||
mod _dep_kind_vtable_ctors {
|
||||
// Re-export all of the vtable constructors for non-query and query dep kinds.
|
||||
|
||||
// Non-query vtable constructors are defined in normal code.
|
||||
pub(crate) use super::non_query::*;
|
||||
// Query vtable constructors are defined via a macro.
|
||||
pub(crate) use crate::_dep_kind_vtable_ctors_for_queries::*;
|
||||
}
|
||||
|
||||
pub fn make_dep_kind_vtables<'tcx>(
|
||||
arena: &'tcx rustc_middle::arena::Arena<'tcx>,
|
||||
) -> &'tcx [DepKindVTable<'tcx>] {
|
||||
// Create an array of vtables, one for each dep kind (non-query and query).
|
||||
let dep_kind_vtables: [DepKindVTable<'tcx>; _] =
|
||||
rustc_middle::make_dep_kind_array!(_dep_kind_vtable_ctors);
|
||||
arena.alloc_from_iter(dep_kind_vtables)
|
||||
}
|
||||
|
|
@ -12,8 +12,7 @@
|
|||
use std::marker::ConstParamTy;
|
||||
|
||||
use rustc_data_structures::sync::AtomicU64;
|
||||
use rustc_middle::arena::Arena;
|
||||
use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNode, DepNodeIndex};
|
||||
use rustc_middle::dep_graph::{self, DepKind, DepNode, DepNodeIndex};
|
||||
use rustc_middle::queries::{
|
||||
self, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates,
|
||||
};
|
||||
|
|
@ -27,6 +26,7 @@ use rustc_query_system::query::{
|
|||
};
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
|
||||
pub use crate::dep_kind_vtables::make_dep_kind_vtables;
|
||||
pub use crate::job::{QueryJobMap, break_query_cycles, print_query_stack};
|
||||
pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all};
|
||||
use crate::plumbing::{encode_all_query_results, try_mark_green};
|
||||
|
|
@ -34,11 +34,13 @@ use crate::profiling_support::QueryKeyStringCache;
|
|||
pub use crate::profiling_support::alloc_self_profile_query_strings;
|
||||
use crate::values::Value;
|
||||
|
||||
#[macro_use]
|
||||
mod plumbing;
|
||||
|
||||
mod dep_kind_vtables;
|
||||
mod error;
|
||||
mod execution;
|
||||
mod job;
|
||||
#[macro_use]
|
||||
mod plumbing;
|
||||
mod profiling_support;
|
||||
mod values;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@ use rustc_hir::def_id::DefId;
|
|||
use rustc_hir::limit::Limit;
|
||||
use rustc_index::Idx;
|
||||
use rustc_middle::bug;
|
||||
#[expect(unused_imports, reason = "used by doc comments")]
|
||||
use rustc_middle::dep_graph::DepKindVTable;
|
||||
use rustc_middle::dep_graph::{
|
||||
self, DepContext, DepKindVTable, DepNode, DepNodeIndex, DepsType, SerializedDepNodeIndex,
|
||||
dep_kinds,
|
||||
self, DepContext, DepNode, DepNodeIndex, DepsType, SerializedDepNodeIndex, dep_kinds,
|
||||
};
|
||||
use rustc_middle::query::Key;
|
||||
use rustc_middle::query::on_disk_cache::{
|
||||
|
|
@ -26,7 +27,7 @@ use rustc_middle::ty::codec::TyEncoder;
|
|||
use rustc_middle::ty::print::with_reduced_queries;
|
||||
use rustc_middle::ty::tls::{self, ImplicitCtxt};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext};
|
||||
use rustc_query_system::dep_graph::{DepNodeKey, HasDepContext};
|
||||
use rustc_query_system::query::{
|
||||
QueryCache, QueryContext, QueryJobId, QuerySideEffect, QueryStackDeferred, QueryStackFrame,
|
||||
QueryStackFrameExtra,
|
||||
|
|
@ -447,7 +448,8 @@ pub(crate) fn query_key_hash_verify<'tcx, C: QueryCache, const FLAGS: QueryFlags
|
|||
});
|
||||
}
|
||||
|
||||
fn try_load_from_on_disk_cache<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
||||
/// Implementation of [`DepKindVTable::try_load_from_on_disk_cache`] for queries.
|
||||
pub(crate) fn try_load_from_on_disk_cache_inner<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
||||
query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
dep_node: DepNode,
|
||||
|
|
@ -496,7 +498,8 @@ where
|
|||
value
|
||||
}
|
||||
|
||||
fn force_from_dep_node<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
||||
/// Implementation of [`DepKindVTable::force_from_dep_node`] for queries.
|
||||
pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
||||
query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
dep_node: DepNode,
|
||||
|
|
@ -527,49 +530,6 @@ fn force_from_dep_node<'tcx, C: QueryCache, const FLAGS: QueryFlags>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn make_dep_kind_vtable_for_query<
|
||||
'tcx,
|
||||
Q,
|
||||
C: QueryCache + 'tcx,
|
||||
const FLAGS: QueryFlags,
|
||||
>(
|
||||
is_eval_always: bool,
|
||||
) -> DepKindVTable<'tcx>
|
||||
where
|
||||
Q: QueryDispatcherUnerased<'tcx, C, FLAGS>,
|
||||
{
|
||||
let is_anon = FLAGS.is_anon;
|
||||
let fingerprint_style = if is_anon {
|
||||
FingerprintStyle::Opaque
|
||||
} else {
|
||||
<C::Key as DepNodeKey<TyCtxt<'tcx>>>::fingerprint_style()
|
||||
};
|
||||
|
||||
if is_anon || !fingerprint_style.reconstructible() {
|
||||
return DepKindVTable {
|
||||
is_anon,
|
||||
is_eval_always,
|
||||
fingerprint_style,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: Q::NAME,
|
||||
};
|
||||
}
|
||||
|
||||
DepKindVTable {
|
||||
is_anon,
|
||||
is_eval_always,
|
||||
fingerprint_style,
|
||||
force_from_dep_node: Some(|tcx, dep_node, _| {
|
||||
force_from_dep_node(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
try_load_from_on_disk_cache: Some(|tcx, dep_node| {
|
||||
try_load_from_on_disk_cache(Q::query_dispatcher(tcx), tcx, dep_node)
|
||||
}),
|
||||
name: Q::NAME,
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros
|
||||
// invoked by `rustc_with_all_queries`.
|
||||
macro_rules! define_queries {
|
||||
|
|
@ -882,119 +842,20 @@ macro_rules! define_queries {
|
|||
for<'tcx> fn(TyCtxt<'tcx>)
|
||||
] = &[$(query_impl::$name::query_key_hash_verify),*];
|
||||
|
||||
/// Module containing a named function for each dep kind (including queries)
|
||||
/// that creates a `DepKindVTable`.
|
||||
///
|
||||
/// Consumed via `make_dep_kind_array!` to create a list of vtables.
|
||||
#[expect(non_snake_case)]
|
||||
mod _dep_kind_vtable_ctors {
|
||||
use super::*;
|
||||
use rustc_middle::bug;
|
||||
use rustc_query_system::dep_graph::FingerprintStyle;
|
||||
/// Declares a dep-kind vtable constructor for each query.
|
||||
mod _dep_kind_vtable_ctors_for_queries {
|
||||
use ::rustc_middle::dep_graph::DepKindVTable;
|
||||
use $crate::dep_kind_vtables::make_dep_kind_vtable_for_query;
|
||||
|
||||
// We use this for most things when incr. comp. is turned off.
|
||||
pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"Null",
|
||||
$(
|
||||
/// `DepKindVTable` constructor for this query.
|
||||
pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> {
|
||||
use $crate::query_impl::$name::QueryType;
|
||||
make_dep_kind_vtable_for_query::<QueryType<'tcx>, _, _>(
|
||||
is_eval_always!([$($modifiers)*]),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// We use this for the forever-red node.
|
||||
pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"Red",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: Some(|tcx, _, prev_index| {
|
||||
tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index);
|
||||
true
|
||||
}),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"SideEffect",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: true,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Opaque,
|
||||
force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")),
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"AnonZeroDeps",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: true,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"TraitSelect",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Opaque,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"CompileCodegenUnit",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Opaque,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"CompileMonoItem",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn Metadata<'tcx>() -> DepKindVTable<'tcx> {
|
||||
DepKindVTable {
|
||||
is_anon: false,
|
||||
is_eval_always: false,
|
||||
fingerprint_style: FingerprintStyle::Unit,
|
||||
force_from_dep_node: None,
|
||||
try_load_from_on_disk_cache: None,
|
||||
name: &"Metadata",
|
||||
}
|
||||
}
|
||||
|
||||
$(pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> {
|
||||
use $crate::query_impl::$name::QueryType;
|
||||
$crate::plumbing::make_dep_kind_vtable_for_query::<QueryType<'tcx>, _, _>(
|
||||
is_eval_always!([$($modifiers)*]),
|
||||
)
|
||||
})*
|
||||
}
|
||||
|
||||
pub fn make_dep_kind_vtables<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindVTable<'tcx>] {
|
||||
arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(_dep_kind_vtable_ctors))
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1425,14 +1425,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
// a note about editions
|
||||
let note = if let Some(did) = did {
|
||||
let requires_note = !did.is_local()
|
||||
&& this.tcx.get_attrs(did, sym::rustc_diagnostic_item).any(
|
||||
|attr| {
|
||||
[sym::TryInto, sym::TryFrom, sym::FromIterator]
|
||||
.map(|x| Some(x))
|
||||
.contains(&attr.value_str())
|
||||
},
|
||||
&& find_attr!(
|
||||
this.tcx.get_all_attrs(did),
|
||||
AttributeKind::RustcDiagnosticItem(
|
||||
sym::TryInto | sym::TryFrom | sym::FromIterator
|
||||
)
|
||||
);
|
||||
|
||||
requires_note.then(|| {
|
||||
format!(
|
||||
"'{}' is included in the prelude starting in Edition 2021",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use rustc_hir::attrs::AttributeKind;
|
|||
use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, MacroKinds};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
|
||||
use rustc_hir::{MissingLifetimeKind, PrimTy};
|
||||
use rustc_hir::{MissingLifetimeKind, PrimTy, find_attr};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::{Session, lint};
|
||||
use rustc_span::edit_distance::{edit_distance, find_best_match_for_name};
|
||||
|
|
@ -2446,10 +2446,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
.iter()
|
||||
.filter_map(|candidate| candidate.did)
|
||||
.find(|did| {
|
||||
self.r
|
||||
.tcx
|
||||
.get_attrs(*did, sym::rustc_diagnostic_item)
|
||||
.any(|attr| attr.value_str() == Some(sym::Default))
|
||||
find_attr!(
|
||||
self.r.tcx.get_all_attrs(*did),
|
||||
AttributeKind::RustcDiagnosticItem(sym::Default)
|
||||
)
|
||||
});
|
||||
let Some(default_trait) = default_trait else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#![feature(const_default)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(control_flow_into_value)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(default_field_values)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// tidy-alphabetical-start
|
||||
#![allow(internal_features)]
|
||||
#![allow(rustc::internal)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(min_specialization)]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ There are three main thread states:
|
|||
waiting to be awoken.
|
||||
|
||||
We sometimes refer to the final two states collectively as **inactive**.
|
||||
Threads begin as idle but transition to idle and finally sleeping when
|
||||
Threads begin as active but transition to idle and finally sleeping when
|
||||
they're unable to find work to do.
|
||||
|
||||
## Sleepy threads
|
||||
|
|
@ -160,7 +160,7 @@ not complete. It is possible -- if unlikely -- that enough activity occurs for
|
|||
Thread A to observe the same JEC value that it saw when getting sleepy. If the
|
||||
new work being published came from *inside* the thread-pool, then this race
|
||||
condition isn't too harmful. It means that we have fewer workers processing the
|
||||
work then we should, but we won't deadlock. This seems like an acceptable risk
|
||||
work than we should, but we won't deadlock. This seems like an acceptable risk
|
||||
given that this is unlikely in practice.
|
||||
|
||||
However, if the work was posted as an *external* job, that is a problem. In that
|
||||
|
|
|
|||
|
|
@ -252,10 +252,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
SubregionOrigin::RelateParamBound(span, ty, opt_span) => {
|
||||
RegionOriginNote::WithName {
|
||||
span,
|
||||
msg: inline_fluent!("...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
|
||||
[true] ...
|
||||
*[false] {\"\"}
|
||||
}"),
|
||||
msg: inline_fluent!(
|
||||
"...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
|
||||
[true] ...
|
||||
*[false] {\"\"}
|
||||
}"
|
||||
),
|
||||
name: &self.ty_to_string(ty),
|
||||
continues: opt_span.is_some(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,10 +102,16 @@ pub struct NegativePositiveConflict<'tcx> {
|
|||
impl<G: EmissionGuarantee> Diagnostic<'_, G> for NegativePositiveConflict<'_> {
|
||||
#[track_caller]
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
|
||||
let mut diag = Diag::new(dcx, level, inline_fluent!("found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
|
||||
[none] {\"\"}
|
||||
*[default] {\" \"}for type `{$self_desc}`
|
||||
}:"));
|
||||
let mut diag = Diag::new(
|
||||
dcx,
|
||||
level,
|
||||
inline_fluent!(
|
||||
"found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
|
||||
[none] {\"\"}
|
||||
*[default] {\" \"}for type `{$self_desc}`
|
||||
}:"
|
||||
),
|
||||
);
|
||||
diag.arg("trait_desc", self.trait_desc.print_only_trait_path().to_string());
|
||||
diag.arg("self_desc", self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string()));
|
||||
diag.span(self.impl_span);
|
||||
|
|
@ -157,9 +163,9 @@ impl Subdiagnostic for AdjustSignatureBorrow {
|
|||
diag.multipart_suggestion_verbose(
|
||||
inline_fluent!(
|
||||
"consider adjusting the signature so it borrows its {$borrow_len ->
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}"
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}"
|
||||
),
|
||||
to_borrow,
|
||||
Applicability::MaybeIncorrect,
|
||||
|
|
@ -170,9 +176,9 @@ impl Subdiagnostic for AdjustSignatureBorrow {
|
|||
diag.multipart_suggestion_verbose(
|
||||
inline_fluent!(
|
||||
"consider adjusting the signature so it does not borrow its {$remove_borrow_len ->
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}"
|
||||
[one] argument
|
||||
*[other] arguments
|
||||
}"
|
||||
),
|
||||
remove_borrow,
|
||||
Applicability::MaybeIncorrect,
|
||||
|
|
@ -505,18 +511,18 @@ impl Subdiagnostic for RegionOriginNote<'_> {
|
|||
span,
|
||||
inline_fluent!(
|
||||
"...so that the {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}"
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}"
|
||||
),
|
||||
);
|
||||
diag.arg("requirement", requirement);
|
||||
|
|
@ -531,18 +537,18 @@ impl Subdiagnostic for RegionOriginNote<'_> {
|
|||
span,
|
||||
inline_fluent!(
|
||||
"...so that {$requirement ->
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}"
|
||||
[method_compat] method type is compatible with trait
|
||||
[type_compat] associated type is compatible with trait
|
||||
[const_compat] const is compatible with trait
|
||||
[expr_assignable] expression is assignable
|
||||
[if_else_different] `if` and `else` have incompatible types
|
||||
[no_else] `if` missing an `else` returns `()`
|
||||
[fn_main_correct_type] `main` function has the correct type
|
||||
[fn_lang_correct_type] lang item function has the correct type
|
||||
[intrinsic_correct_type] intrinsic has the correct type
|
||||
[method_correct_type] method receiver has the correct type
|
||||
*[other] types are compatible
|
||||
}"
|
||||
),
|
||||
);
|
||||
diag.arg("requirement", requirement);
|
||||
|
|
@ -578,9 +584,9 @@ impl Subdiagnostic for LifetimeMismatchLabels {
|
|||
span,
|
||||
inline_fluent!(
|
||||
"...but data{$label_var1_exists ->
|
||||
[true] {\" \"}from `{$label_var1}`
|
||||
*[false] {\"\"}
|
||||
} is returned here"
|
||||
[true] {\" \"}from `{$label_var1}`
|
||||
*[false] {\"\"}
|
||||
} is returned here"
|
||||
),
|
||||
);
|
||||
diag.arg("label_var1_exists", label_var1.is_some());
|
||||
|
|
@ -614,12 +620,12 @@ impl Subdiagnostic for LifetimeMismatchLabels {
|
|||
span,
|
||||
inline_fluent!(
|
||||
"...but data{$label_var1_exists ->
|
||||
[true] {\" \"}from `{$label_var1}`
|
||||
*[false] {\"\"}
|
||||
} flows{$label_var2_exists ->
|
||||
[true] {\" \"}into `{$label_var2}`
|
||||
*[false] {\"\"}
|
||||
} here"
|
||||
[true] {\" \"}from `{$label_var1}`
|
||||
*[false] {\"\"}
|
||||
} flows{$label_var2_exists ->
|
||||
[true] {\" \"}into `{$label_var2}`
|
||||
*[false] {\"\"}
|
||||
} here"
|
||||
),
|
||||
);
|
||||
diag.arg("label_var1_exists", label_var1.is_some());
|
||||
|
|
@ -789,12 +795,12 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
|||
diag.multipart_suggestion_verbose(
|
||||
inline_fluent!(
|
||||
"consider {$is_reuse ->
|
||||
[true] reusing
|
||||
*[false] introducing
|
||||
} a named lifetime parameter{$is_impl ->
|
||||
[true] {\" \"}and update trait if needed
|
||||
*[false] {\"\"}
|
||||
}"
|
||||
[true] reusing
|
||||
*[false] introducing
|
||||
} a named lifetime parameter{$is_impl ->
|
||||
[true] {\" \"}and update trait if needed
|
||||
*[false] {\"\"}
|
||||
}"
|
||||
),
|
||||
visitor.suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
|
|
|
|||
|
|
@ -171,37 +171,37 @@ impl Subdiagnostic for RegionExplanation<'_> {
|
|||
|
||||
let msg = diag.eagerly_translate(inline_fluent!(
|
||||
"{$pref_kind ->
|
||||
*[should_not_happen] [{$pref_kind}]
|
||||
[ref_valid_for] ...the reference is valid for
|
||||
[content_valid_for] ...but the borrowed content is only valid for
|
||||
[type_obj_valid_for] object type is valid for
|
||||
[source_pointer_valid_for] source pointer is only valid for
|
||||
[type_satisfy] type must satisfy
|
||||
[type_outlive] type must outlive
|
||||
[lf_param_instantiated_with] lifetime parameter instantiated with
|
||||
[lf_param_must_outlive] but lifetime parameter must outlive
|
||||
[lf_instantiated_with] lifetime instantiated with
|
||||
[lf_must_outlive] but lifetime must outlive
|
||||
[pointer_valid_for] the pointer is valid for
|
||||
[data_valid_for] but the referenced data is only valid for
|
||||
[empty] {\"\"}
|
||||
}{$pref_kind ->
|
||||
[empty] {\"\"}
|
||||
*[other] {\" \"}
|
||||
}{$desc_kind ->
|
||||
*[should_not_happen] [{$desc_kind}]
|
||||
[restatic] the static lifetime
|
||||
[revar] lifetime {$desc_arg}
|
||||
[as_defined] the lifetime `{$desc_arg}` as defined here
|
||||
[as_defined_anon] the anonymous lifetime as defined here
|
||||
[defined_here] the anonymous lifetime defined here
|
||||
[defined_here_reg] the lifetime `{$desc_arg}` as defined here
|
||||
}{$suff_kind ->
|
||||
*[should_not_happen] [{$suff_kind}]
|
||||
[empty]{\"\"}
|
||||
[continues] ...
|
||||
[req_by_binding] {\" \"}as required by this binding
|
||||
}"
|
||||
*[should_not_happen] [{$pref_kind}]
|
||||
[ref_valid_for] ...the reference is valid for
|
||||
[content_valid_for] ...but the borrowed content is only valid for
|
||||
[type_obj_valid_for] object type is valid for
|
||||
[source_pointer_valid_for] source pointer is only valid for
|
||||
[type_satisfy] type must satisfy
|
||||
[type_outlive] type must outlive
|
||||
[lf_param_instantiated_with] lifetime parameter instantiated with
|
||||
[lf_param_must_outlive] but lifetime parameter must outlive
|
||||
[lf_instantiated_with] lifetime instantiated with
|
||||
[lf_must_outlive] but lifetime must outlive
|
||||
[pointer_valid_for] the pointer is valid for
|
||||
[data_valid_for] but the referenced data is only valid for
|
||||
[empty] {\"\"}
|
||||
}{$pref_kind ->
|
||||
[empty] {\"\"}
|
||||
*[other] {\" \"}
|
||||
}{$desc_kind ->
|
||||
*[should_not_happen] [{$desc_kind}]
|
||||
[restatic] the static lifetime
|
||||
[revar] lifetime {$desc_arg}
|
||||
[as_defined] the lifetime `{$desc_arg}` as defined here
|
||||
[as_defined_anon] the anonymous lifetime as defined here
|
||||
[defined_here] the anonymous lifetime defined here
|
||||
[defined_here_reg] the lifetime `{$desc_arg}` as defined here
|
||||
}{$suff_kind ->
|
||||
*[should_not_happen] [{$suff_kind}]
|
||||
[empty]{\"\"}
|
||||
[continues] ...
|
||||
[req_by_binding] {\" \"}as required by this binding
|
||||
}"
|
||||
));
|
||||
diag.restore_args();
|
||||
if let Some(span) = self.desc.span {
|
||||
|
|
|
|||
|
|
@ -430,7 +430,16 @@ pub(crate) fn supertrait_vtable_slot<'tcx>(
|
|||
}
|
||||
};
|
||||
|
||||
prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap()
|
||||
prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap_or_else(|| {
|
||||
// This can happen if the trait hierarchy is malformed (e.g., due to
|
||||
// missing generics on a supertrait bound). There should already be an error
|
||||
// emitted for this, so we just delay the ICE.
|
||||
tcx.dcx().delayed_bug(format!(
|
||||
"could not find the supertrait vtable slot for `{}` -> `{}`",
|
||||
source, target
|
||||
));
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn provide(providers: &mut Providers) {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@
|
|||
#![allow(rustc::usage_of_type_ir_inherent)]
|
||||
#![allow(rustc::usage_of_type_ir_traits)]
|
||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||
#![cfg_attr(
|
||||
feature = "nightly",
|
||||
feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
|
||||
)]
|
||||
#![cfg_attr(feature = "nightly", feature(associated_type_defaults, rustc_attrs, negative_impls))]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
extern crate self as rustc_type_ir;
|
||||
|
|
|
|||
|
|
@ -1514,7 +1514,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
|||
/// Recreate a `Box` which was previously converted to a `NonNull` pointer
|
||||
/// using [`Box::into_non_null_with_allocator`]:
|
||||
/// ```
|
||||
/// #![feature(allocator_api, box_vec_non_null)]
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
|
|
@ -1524,7 +1524,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
|||
/// ```
|
||||
/// Manually create a `Box` from scratch by using the system allocator:
|
||||
/// ```
|
||||
/// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)]
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::alloc::{Allocator, Layout, System};
|
||||
///
|
||||
|
|
@ -1629,7 +1629,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
|||
/// Converting the `NonNull` pointer back into a `Box` with
|
||||
/// [`Box::from_non_null_in`] for automatic cleanup:
|
||||
/// ```
|
||||
/// #![feature(allocator_api, box_vec_non_null)]
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
|
|
@ -1640,7 +1640,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
|||
/// Manual cleanup by explicitly running the destructor and deallocating
|
||||
/// the memory:
|
||||
/// ```
|
||||
/// #![feature(allocator_api, box_vec_non_null)]
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::alloc::{Allocator, Layout, System};
|
||||
///
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
//! [`Rc`]: rc
|
||||
//! [`RefCell`]: core::cell
|
||||
|
||||
#![allow(unused_features)]
|
||||
#![allow(incomplete_features)]
|
||||
#![allow(unused_attributes)]
|
||||
#![stable(feature = "alloc", since = "1.36.0")]
|
||||
|
|
@ -85,13 +86,11 @@
|
|||
//
|
||||
// Library features:
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(not(no_global_oom_handling), feature(string_replace_in_place))]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(array_into_iter_constructors)]
|
||||
#![feature(ascii_char)]
|
||||
#![feature(async_fn_traits)]
|
||||
#![feature(async_iterator)]
|
||||
#![feature(box_vec_non_null)]
|
||||
#![feature(bstr)]
|
||||
#![feature(bstr_internals)]
|
||||
#![feature(cast_maybe_uninit)]
|
||||
|
|
@ -148,7 +147,6 @@
|
|||
#![feature(slice_ptr_get)]
|
||||
#![feature(slice_range)]
|
||||
#![feature(std_internals)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(temporary_niche_types)]
|
||||
#![feature(transmutability)]
|
||||
#![feature(trivial_clone)]
|
||||
|
|
@ -158,7 +156,6 @@
|
|||
#![feature(try_blocks)]
|
||||
#![feature(try_trait_v2)]
|
||||
#![feature(try_trait_v2_residual)]
|
||||
#![feature(try_with_capacity)]
|
||||
#![feature(tuple_trait)]
|
||||
#![feature(ub_checks)]
|
||||
#![feature(unicode_internals)]
|
||||
|
|
@ -176,10 +173,8 @@
|
|||
#![feature(const_trait_impl)]
|
||||
#![feature(coroutine_trait)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(derive_const)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(fundamental)]
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(intrinsics)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(min_specialization)]
|
||||
|
|
|
|||
|
|
@ -1238,7 +1238,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(allocator_api, box_vec_non_null)]
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
|
|
@ -1265,7 +1265,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// Using memory that was allocated elsewhere:
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(allocator_api, box_vec_non_null)]
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::alloc::{AllocError, Allocator, Global, Layout};
|
||||
///
|
||||
|
|
@ -1365,7 +1365,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(allocator_api, box_vec_non_null)]
|
||||
/// #![feature(allocator_api)]
|
||||
///
|
||||
/// use std::alloc::System;
|
||||
///
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
// tidy-alphabetical-start
|
||||
#![feature(allocator_api)]
|
||||
#![feature(array_into_iter_constructors)]
|
||||
#![feature(box_vec_non_null)]
|
||||
#![feature(char_internals)]
|
||||
#![feature(const_alloc_error)]
|
||||
#![feature(const_cmp)]
|
||||
|
|
@ -55,16 +54,12 @@
|
|||
//
|
||||
// Language features:
|
||||
// tidy-alphabetical-start
|
||||
#![feature(cfg_sanitize)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
#![feature(optimize_attribute)]
|
||||
#![feature(prelude_import)]
|
||||
#![feature(rustc_allow_const_fn_unstable)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(test)]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#![feature(const_heap)]
|
||||
#![feature(deque_extend_front)]
|
||||
#![feature(iter_array_chunks)]
|
||||
#![feature(wtf8_internals)]
|
||||
#![feature(cow_is_borrowed)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(downcast_unchecked)]
|
||||
|
|
@ -30,8 +29,6 @@
|
|||
#![feature(string_remove_matches)]
|
||||
#![feature(const_btree_len)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(panic_update_hook)]
|
||||
#![feature(pointer_is_aligned_to)]
|
||||
#![feature(test)]
|
||||
#![feature(thin_box)]
|
||||
#![feature(drain_keep_rest)]
|
||||
|
|
|
|||
|
|
@ -878,7 +878,7 @@ impl AsciiChar {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ascii_char, ascii_char_variants, is_ascii_octdigit)]
|
||||
/// #![feature(ascii_char, ascii_char_variants)]
|
||||
///
|
||||
/// use std::ascii;
|
||||
///
|
||||
|
|
|
|||
|
|
@ -774,7 +774,6 @@ impl<T, const N: usize> Cell<[T; N]> {
|
|||
/// following is unsound:
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(cell_get_cloned)]
|
||||
/// # use std::cell::Cell;
|
||||
///
|
||||
/// #[derive(Copy, Debug)]
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ impl_float_from_bool!(
|
|||
f16;
|
||||
doctest_prefix:
|
||||
// rustdoc doesn't remove the conventional space after the `///`
|
||||
///# #![allow(unused_features)]
|
||||
///#![feature(f16)]
|
||||
///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
///
|
||||
|
|
@ -230,6 +231,7 @@ impl_float_from_bool!(f64);
|
|||
impl_float_from_bool!(
|
||||
f128;
|
||||
doctest_prefix:
|
||||
///# #![allow(unused_features)]
|
||||
///#![feature(f128)]
|
||||
///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
|
||||
///
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
#![allow(incomplete_features)]
|
||||
#![warn(multiple_supertrait_upcastable)]
|
||||
#![allow(internal_features)]
|
||||
#![allow(unused_features)]
|
||||
#![deny(ffi_unwind_calls)]
|
||||
#![warn(unreachable_pub)]
|
||||
// Do not check link redundancy on bootstrapping phase
|
||||
|
|
@ -95,9 +96,7 @@
|
|||
//
|
||||
// Library features:
|
||||
// tidy-alphabetical-start
|
||||
#![feature(array_ptr_get)]
|
||||
#![feature(asm_experimental_arch)]
|
||||
#![feature(bstr)]
|
||||
#![feature(bstr_internals)]
|
||||
#![feature(cfg_select)]
|
||||
#![feature(cfg_target_has_reliable_f16_f128)]
|
||||
|
|
@ -106,31 +105,15 @@
|
|||
#![feature(const_destruct)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(const_select_unpredictable)]
|
||||
#![feature(const_unsigned_bigint_helpers)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(coverage_attribute)]
|
||||
#![feature(disjoint_bitor)]
|
||||
#![feature(internal_impls_macro)]
|
||||
#![feature(ip)]
|
||||
#![feature(is_ascii_octdigit)]
|
||||
#![feature(link_cfg)]
|
||||
#![feature(offset_of_enum)]
|
||||
#![feature(panic_internals)]
|
||||
#![feature(pattern_type_macro)]
|
||||
#![feature(ptr_alignment_type)]
|
||||
#![feature(ptr_metadata)]
|
||||
#![feature(set_ptr_value)]
|
||||
#![feature(signed_bigint_helpers)]
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(str_split_inclusive_remainder)]
|
||||
#![feature(str_split_remainder)]
|
||||
#![feature(type_info)]
|
||||
#![feature(ub_checks)]
|
||||
#![feature(unsafe_pinned)]
|
||||
#![feature(utf16_extra)]
|
||||
#![feature(variant_count)]
|
||||
#![feature(widening_mul)]
|
||||
// tidy-alphabetical-end
|
||||
//
|
||||
// Language features:
|
||||
|
|
@ -175,7 +158,6 @@
|
|||
#![feature(optimize_attribute)]
|
||||
#![feature(pattern_types)]
|
||||
#![feature(prelude_import)]
|
||||
#![feature(reborrow)]
|
||||
#![feature(repr_simd)]
|
||||
#![feature(rustc_allow_const_fn_unstable)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
|
|
|||
|
|
@ -148,7 +148,10 @@ pub mod consts {
|
|||
pub const LN_10: f128 = 2.30258509299404568401799145468436420760110148862877297603333_f128;
|
||||
}
|
||||
|
||||
#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), allow(internal_features))))]
|
||||
#[doc(test(attr(
|
||||
feature(cfg_target_has_reliable_f16_f128),
|
||||
allow(internal_features, unused_features)
|
||||
)))]
|
||||
impl f128 {
|
||||
/// The radix or base of the internal representation of `f128`.
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
|
|
@ -1470,7 +1473,11 @@ impl f128 {
|
|||
// Functions in this module fall into `core_float_math`
|
||||
// #[unstable(feature = "core_float_math", issue = "137578")]
|
||||
#[cfg(not(test))]
|
||||
#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
|
||||
#[doc(test(attr(
|
||||
feature(cfg_target_has_reliable_f16_f128),
|
||||
expect(internal_features),
|
||||
allow(unused_features)
|
||||
)))]
|
||||
impl f128 {
|
||||
/// Returns the largest integer less than or equal to `self`.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -142,7 +142,10 @@ pub mod consts {
|
|||
pub const LN_10: f16 = 2.30258509299404568401799145468436421_f16;
|
||||
}
|
||||
|
||||
#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), allow(internal_features))))]
|
||||
#[doc(test(attr(
|
||||
feature(cfg_target_has_reliable_f16_f128),
|
||||
allow(internal_features, unused_features)
|
||||
)))]
|
||||
impl f16 {
|
||||
/// The radix or base of the internal representation of `f16`.
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
|
|
|
|||
|
|
@ -1821,6 +1821,7 @@ pub mod math {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(unused_features)]
|
||||
/// #![feature(core_float_math)]
|
||||
///
|
||||
/// # // FIXME(#140515): mingw has an incorrect fma
|
||||
|
|
|
|||
|
|
@ -1819,6 +1819,7 @@ pub mod math {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(unused_features)]
|
||||
/// #![feature(core_float_math)]
|
||||
///
|
||||
/// # // FIXME(#140515): mingw has an incorrect fma
|
||||
|
|
|
|||
|
|
@ -3072,7 +3072,6 @@ macro_rules! uint_impl {
|
|||
/// implementing it for wider-than-native types.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(const_unsigned_bigint_helpers)]
|
||||
/// fn scalar_mul_eq(little_endian_digits: &mut Vec<u16>, multiplicand: u16) {
|
||||
/// let mut carry = 0;
|
||||
/// for d in little_endian_digits.iter_mut() {
|
||||
|
|
@ -3097,6 +3096,7 @@ macro_rules! uint_impl {
|
|||
/// except that it gives the value of the overflow instead of just whether one happened:
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(unused_features)]
|
||||
/// #![feature(const_unsigned_bigint_helpers)]
|
||||
/// let r = u8::carrying_mul(7, 13, 0);
|
||||
/// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13));
|
||||
|
|
@ -3109,6 +3109,7 @@ macro_rules! uint_impl {
|
|||
/// [`wrapping_add`](Self::wrapping_add) methods:
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(unused_features)]
|
||||
/// #![feature(const_unsigned_bigint_helpers)]
|
||||
/// assert_eq!(
|
||||
/// 789_u16.carrying_mul(456, 123).0,
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ impl Alignment {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(ptr_alignment_type)]
|
||||
/// #![feature(layout_for_ptr)]
|
||||
/// use std::ptr::Alignment;
|
||||
///
|
||||
/// assert_eq!(unsafe { Alignment::of_val_raw(&5i32) }.as_usize(), 4);
|
||||
|
|
|
|||
|
|
@ -1800,7 +1800,6 @@ impl<T> *mut [T] {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(raw_slice_split)]
|
||||
/// #![feature(slice_ptr_get)]
|
||||
///
|
||||
/// let mut v = [1, 0, 3, 0, 5, 6];
|
||||
/// let ptr = &mut v as *mut [_];
|
||||
|
|
|
|||
|
|
@ -690,7 +690,6 @@ impl Duration {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(duration_constants)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1));
|
||||
|
|
@ -801,7 +800,6 @@ impl Duration {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(duration_constants)]
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2));
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#![feature(cfg_target_has_reliable_f16_f128)]
|
||||
#![feature(char_internals)]
|
||||
#![feature(char_max_len)]
|
||||
#![feature(clamp_magnitude)]
|
||||
#![feature(clone_to_uninit)]
|
||||
#![feature(const_array)]
|
||||
#![feature(const_bool)]
|
||||
|
|
@ -35,7 +34,6 @@
|
|||
#![feature(const_trait_impl)]
|
||||
#![feature(const_unsigned_bigint_helpers)]
|
||||
#![feature(control_flow_ok)]
|
||||
#![feature(core_float_math)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_intrinsics_fallbacks)]
|
||||
#![feature(core_io_borrowed_buf)]
|
||||
|
|
@ -47,7 +45,6 @@
|
|||
#![feature(drop_guard)]
|
||||
#![feature(duration_constants)]
|
||||
#![feature(duration_constructors)]
|
||||
#![feature(error_generic_member_access)]
|
||||
#![feature(exact_div)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(extend_one)]
|
||||
|
|
@ -55,7 +52,6 @@
|
|||
#![feature(f16)]
|
||||
#![feature(f128)]
|
||||
#![feature(float_algebraic)]
|
||||
#![feature(float_gamma)]
|
||||
#![feature(float_minimum_maximum)]
|
||||
#![feature(flt2dec)]
|
||||
#![feature(fmt_internals)]
|
||||
|
|
@ -94,7 +90,6 @@
|
|||
#![feature(nonzero_from_str_radix)]
|
||||
#![feature(numfmt)]
|
||||
#![feature(one_sided_range)]
|
||||
#![feature(option_reduce)]
|
||||
#![feature(pattern)]
|
||||
#![feature(pointer_is_aligned_to)]
|
||||
#![feature(portable_simd)]
|
||||
|
|
@ -114,7 +109,6 @@
|
|||
#![feature(step_trait)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(strict_provenance_lints)]
|
||||
#![feature(test)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(trusted_random_access)]
|
||||
#![feature(try_blocks)]
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
#![feature(cfg_emscripten_wasm_eh)]
|
||||
#![feature(cfg_select)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(panic_unwind)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(std_internals)]
|
||||
|
|
@ -25,6 +24,7 @@
|
|||
#![panic_runtime]
|
||||
#![feature(panic_runtime)]
|
||||
#![allow(internal_features)]
|
||||
#![allow(unused_features)]
|
||||
#![warn(unreachable_pub)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use crate::intrinsics;
|
|||
use crate::sys::cmath;
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[doc(test(attr(allow(unused_features))))]
|
||||
impl f128 {
|
||||
/// Raises a number to a floating point power.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -916,7 +916,6 @@ impl f16 {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(f16)]
|
||||
/// #![feature(float_gamma)]
|
||||
/// # #[cfg(not(miri))]
|
||||
/// # #[cfg(target_has_reliable_f16_math)] {
|
||||
///
|
||||
|
|
@ -952,7 +951,6 @@ impl f16 {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(f16)]
|
||||
/// #![feature(float_gamma)]
|
||||
/// # #[cfg(not(miri))]
|
||||
/// # #[cfg(target_has_reliable_f16_math)] {
|
||||
///
|
||||
|
|
@ -988,7 +986,6 @@ impl f16 {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(f16)]
|
||||
/// #![feature(float_erf)]
|
||||
/// # #[cfg(not(miri))]
|
||||
/// # #[cfg(target_has_reliable_f16_math)] {
|
||||
/// /// The error function relates what percent of a normal distribution lies
|
||||
|
|
@ -1028,7 +1025,6 @@ impl f16 {
|
|||
///
|
||||
/// ```
|
||||
/// #![feature(f16)]
|
||||
/// #![feature(float_erf)]
|
||||
/// # #[cfg(not(miri))]
|
||||
/// # #[cfg(target_has_reliable_f16_math)] {
|
||||
/// let x: f16 = 0.123;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(f16, f128, float_gamma, float_minimum_maximum, cfg_target_has_reliable_f16_f128)]
|
||||
#![feature(f16, f128, float_gamma, cfg_target_has_reliable_f16_f128)]
|
||||
#![expect(internal_features)] // for reliable_f16_f128
|
||||
|
||||
use std::fmt;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![allow(stable_features)]
|
||||
#![feature(volatile)]
|
||||
|
||||
use std::ptr::{read_volatile, write_volatile};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(internal_features, unused_features)]
|
||||
#![feature(stdarch_internal)]
|
||||
#![cfg_attr(target_arch = "arm", feature(stdarch_arm_feature_detection))]
|
||||
#![cfg_attr(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(internal_features, unused_features)]
|
||||
#![cfg_attr(
|
||||
any(
|
||||
target_arch = "arm",
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#![feature(staged_api)]
|
||||
#![feature(process_exitcode_internals)]
|
||||
#![feature(panic_can_unwind)]
|
||||
#![feature(test)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![feature(thread_spawn_hook)]
|
||||
#![allow(internal_features)]
|
||||
#![warn(rustdoc::unescaped_backticks)]
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
#![feature(cfg_select)]
|
||||
#![feature(link_cfg)]
|
||||
#![feature(staged_api)]
|
||||
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
|
||||
#![cfg_attr(
|
||||
all(target_family = "wasm", any(not(target_os = "emscripten"), emscripten_wasm_eh)),
|
||||
feature(link_llvm_intrinsics, simd_wasm64)
|
||||
)]
|
||||
#![allow(internal_features)]
|
||||
#![allow(unused_features)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
// Force libc to be included even if unused. This is required by many platforms.
|
||||
|
|
|
|||
|
|
@ -175,8 +175,8 @@ When you use bootstrap, you'll call it through the entry point script
|
|||
(`x`, `x.ps1`, or `x.py`). However, most of the code lives in `src/bootstrap`.
|
||||
`bootstrap` has a difficult problem: it is written in Rust, but yet it is run
|
||||
before the Rust compiler is built! To work around this, there are two components
|
||||
of bootstrap: the main one written in rust, and `bootstrap.py`. `bootstrap.py`
|
||||
is what gets run by entry point script. It takes care of downloading the prebuilt
|
||||
of bootstrap: the main one written in Rust, and `bootstrap.py`. `bootstrap.py`
|
||||
is what gets run by the entry point script. It takes care of downloading the prebuilt
|
||||
stage 0 compiler, std and Cargo binaries, which are then used to build the
|
||||
bootstrap binary.
|
||||
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ def default_build_triple(verbose):
|
|||
@contextlib.contextmanager
|
||||
def output(filepath):
|
||||
tmp = filepath + ".tmp"
|
||||
with open(tmp, "w") as f:
|
||||
with open(tmp, "w", encoding="utf-8") as f:
|
||||
yield f
|
||||
try:
|
||||
if os.path.exists(filepath):
|
||||
|
|
@ -778,7 +778,7 @@ class RustBuild(object):
|
|||
# Use `/etc/os-release` instead of `/etc/NIXOS`.
|
||||
# The latter one does not exist on NixOS when using tmpfs as root.
|
||||
try:
|
||||
with open("/etc/os-release", "r") as f:
|
||||
with open("/etc/os-release", "r", encoding="utf-8") as f:
|
||||
is_nixos = any(
|
||||
ln.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"')
|
||||
for ln in f
|
||||
|
|
@ -863,7 +863,8 @@ class RustBuild(object):
|
|||
if ".so" not in fname:
|
||||
# Finally, set the correct .interp for binaries
|
||||
with open(
|
||||
"{}/nix-support/dynamic-linker".format(nix_deps_dir)
|
||||
"{}/nix-support/dynamic-linker".format(nix_deps_dir),
|
||||
encoding="utf-8",
|
||||
) as dynamic_linker:
|
||||
patchelf_args += ["--set-interpreter", dynamic_linker.read().rstrip()]
|
||||
|
||||
|
|
@ -888,7 +889,7 @@ class RustBuild(object):
|
|||
"""Check if the given program stamp is out of date"""
|
||||
if not os.path.exists(stamp_path) or self.clean:
|
||||
return True
|
||||
with open(stamp_path, "r") as stamp:
|
||||
with open(stamp_path, "r", encoding="utf-8") as stamp:
|
||||
return key != stamp.read()
|
||||
|
||||
def bin_root(self):
|
||||
|
|
@ -1276,7 +1277,7 @@ def parse_args(args):
|
|||
|
||||
def parse_stage0_file(path):
|
||||
result = {}
|
||||
with open(path, "r") as file:
|
||||
with open(path, "r", encoding="utf-8") as file:
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#"):
|
||||
|
|
@ -1346,7 +1347,7 @@ def bootstrap(args):
|
|||
|
||||
# HACK: This works because `self.get_toml()` returns the first match it finds for a
|
||||
# specific key, so appending our defaults at the end allows the user to override them
|
||||
with open(include_path) as included_toml:
|
||||
with open(include_path, encoding="utf-8") as included_toml:
|
||||
config_toml += os.linesep + included_toml.read()
|
||||
|
||||
# Configure initial bootstrap
|
||||
|
|
@ -1384,7 +1385,9 @@ def main():
|
|||
if len(sys.argv) == 1 or sys.argv[1] in ["-h", "--help"]:
|
||||
try:
|
||||
with open(
|
||||
os.path.join(os.path.dirname(__file__), "../etc/xhelp"), "r"
|
||||
os.path.join(os.path.dirname(__file__), "../etc/xhelp"),
|
||||
"r",
|
||||
encoding="utf-8",
|
||||
) as f:
|
||||
# The file from bootstrap func already has newline.
|
||||
print(f.read(), end="")
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ Refer to the [dev guide](https://rustc-dev-guide.rust-lang.org/tests/docker.html
|
|||
## Docker Toolbox on Windows
|
||||
|
||||
For Windows before Windows 10, the docker images can be run on Windows via
|
||||
[Docker Toolbox]. There are several preparation needs to be made before running
|
||||
[Docker Toolbox]. There are several preparations that need to be made before running
|
||||
a Docker image.
|
||||
|
||||
1. Stop the virtual machine from the terminal with `docker-machine stop`
|
||||
|
|
@ -92,7 +92,7 @@ To run the image,
|
|||
A number of these images take quite a long time to compile as they're building
|
||||
whole gcc toolchains to do cross builds with. Much of this is relatively
|
||||
self-explanatory but some images use [crosstool-ng] which isn't quite as self
|
||||
explanatory. Below is a description of where these `*.defconfig` files come form,
|
||||
explanatory. Below is a description of where these `*.defconfig` files come from,
|
||||
how to generate them, and how the existing ones were generated.
|
||||
|
||||
[crosstool-ng]: https://github.com/crosstool-ng/crosstool-ng
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ target | std | notes
|
|||
[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA)
|
||||
[`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA)
|
||||
[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA)
|
||||
[`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39)
|
||||
[`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | ✓ |RISC-V Linux (kernel 4.20+, musl 1.2.5)
|
||||
`riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA)
|
||||
[`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA)
|
||||
|
|
@ -406,7 +407,6 @@ target | std | host | notes
|
|||
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
|
||||
[`riscv64gc-unknown-redox`](platform-support/redox.md) | ✓ | | RISC-V 64bit Redox OS
|
||||
[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX
|
||||
[`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39)
|
||||
[`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.5)
|
||||
`sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux
|
||||
[`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+
|
||||
|
|
|
|||
|
|
@ -6,12 +6,10 @@
|
|||
)]
|
||||
#![feature(ascii_char)]
|
||||
#![feature(ascii_char_variants)]
|
||||
#![feature(box_into_inner)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(file_buffered)]
|
||||
#![feature(formatting_options)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_advance_by)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(iter_order_by)]
|
||||
#![feature(rustc_private)]
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
//@ known-bug: #135845
|
||||
struct S<'a, T: ?Sized>(&'a T);
|
||||
|
||||
fn b<'a>() -> S<'static, _> {
|
||||
S::<'a>(&0)
|
||||
}
|
||||
|
|
@ -4,9 +4,10 @@
|
|||
|
||||
fn foo<T>() {
|
||||
[0; size_of::<*mut T>()];
|
||||
//~^ ERROR: tuple constructor with invalid base path
|
||||
//~^ ERROR: complex const arguments must be placed inside of a `const` block
|
||||
[0; const { size_of::<*mut T>() }];
|
||||
//~^ ERROR: generic parameters may not be used in const operations
|
||||
[0; const { size_of::<*mut i32>() }];
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: tuple constructor with invalid base path
|
||||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/size-of-generic-ptr-in-array-len.rs:6:9
|
||||
|
|
||||
LL | [0; size_of::<*mut T>()];
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ fn test_errors<const N: usize>() {
|
|||
//~| ERROR tuple constructor with invalid base path
|
||||
|
||||
accepts_point::<{ non_ctor(N, N) }>();
|
||||
//~^ ERROR tuple constructor with invalid base path
|
||||
//~^ ERROR complex const arguments must be placed inside of a `const` block
|
||||
|
||||
accepts_point::<{ CONST_ITEM(N, N) }>();
|
||||
//~^ ERROR tuple constructor with invalid base path
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ error: tuple constructor with invalid base path
|
|||
LL | accepts_point::<{ UnresolvedIdent(N, N) }>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: tuple constructor with invalid base path
|
||||
error: complex const arguments must be placed inside of a `const` block
|
||||
--> $DIR/tuple_ctor_erroneous.rs:34:23
|
||||
|
|
||||
LL | accepts_point::<{ non_ctor(N, N) }>();
|
||||
|
|
|
|||
31
tests/ui/const-generics/mgca/type-const-ctor-148953.rs
Normal file
31
tests/ui/const-generics/mgca/type-const-ctor-148953.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//! Regression test for <https://github.com/rust-lang/rust/issues/148953>
|
||||
//!
|
||||
//! Unit struct constructors used as the RHS of a `type const` associated
|
||||
//! const used to ICE during normalization because they were lowered as
|
||||
//! `Const::new_unevaluated` with a Ctor def_id. Fixed by adding proper const
|
||||
//! constructor support that produces a concrete ValTree value instead.
|
||||
|
||||
//@ check-pass
|
||||
|
||||
#![feature(min_generic_const_args, adt_const_params)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
use std::marker::ConstParamTy;
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
struct S;
|
||||
|
||||
impl S {
|
||||
type const N: S = S;
|
||||
}
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
enum E {
|
||||
V,
|
||||
}
|
||||
|
||||
impl E {
|
||||
type const M: E = { E::V };
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#[deprecated_safe(since = "TBD", note = "...")] //~ ERROR: the `#[deprecated_safe]` attribute is an experimental feature
|
||||
unsafe fn deprecated_safe_fn() {}
|
||||
|
||||
#[deprecated_safe(since = "TBD", note = "...")] //~ ERROR: the `#[deprecated_safe]` attribute is an experimental feature
|
||||
unsafe trait DeprecatedSafeTrait {}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
error[E0658]: the `#[deprecated_safe]` attribute is an experimental feature
|
||||
--> $DIR/feature-gate-deprecated_safe.rs:1:1
|
||||
|
|
||||
LL | #[deprecated_safe(since = "TBD", note = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #94978 <https://github.com/rust-lang/rust/issues/94978> for more information
|
||||
= help: add `#![feature(deprecated_safe)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: the `#[deprecated_safe]` attribute is an experimental feature
|
||||
--> $DIR/feature-gate-deprecated_safe.rs:4:1
|
||||
|
|
||||
LL | #[deprecated_safe(since = "TBD", note = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #94978 <https://github.com/rust-lang/rust/issues/94978> for more information
|
||||
= help: add `#![feature(deprecated_safe)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
11
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs
Normal file
11
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Regression test for #135845.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
fn b<'a>() -> _ {
|
||||
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
|
||||
let _: PhantomData<&'a ()> = PhantomData;
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
15
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr
Normal file
15
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||
--> $DIR/recover-infer-ret-ty-issue-135845.rs:5:15
|
||||
|
|
||||
LL | fn b<'a>() -> _ {
|
||||
| ^ not allowed in type signatures
|
||||
|
|
||||
help: replace with the correct return type
|
||||
|
|
||||
LL - fn b<'a>() -> _ {
|
||||
LL + fn b<'a>() -> i32 {
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0121`.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
//@ check-pass
|
||||
//@ compile-flags: -Znext-solver
|
||||
|
||||
// Regression test for trait-system-refactor-initiative#264.
|
||||
//
|
||||
// Some defining uses of opaque types can't constrain captured regions to universals.
|
||||
// Previouly, we eagerly report error in this case.
|
||||
// Now we report error only if there's no fully defining use from all bodies of the typeck root.
|
||||
|
||||
struct Inv<'a>(*mut &'a ());
|
||||
|
||||
fn mk_static() -> Inv<'static> { todo!() }
|
||||
|
||||
fn guide_closure_sig<'a>(f: impl FnOnce() -> Inv<'a>) {}
|
||||
|
||||
fn unconstrained_in_closure() -> impl Sized {
|
||||
guide_closure_sig(|| unconstrained_in_closure());
|
||||
mk_static()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
//@ compile-flags: -Znext-solver
|
||||
|
||||
// Just for diagnostics completeness.
|
||||
// This is probably unimportant as we only report one error for such case in HIR typeck.
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
struct Invar<'a>(*mut &'a ());
|
||||
|
||||
fn mk_invar<'a>(a: &'a i32) -> Invar<'a> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
type MultiUse = impl Sized;
|
||||
|
||||
#[define_opaque(MultiUse)]
|
||||
fn capture_different_universals_not_on_bounds<'a, 'b, 'c>(a: &'a i32, b: &'b i32, c: &'c i32) {
|
||||
let _ = || -> MultiUse {
|
||||
//~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700]
|
||||
mk_invar(a)
|
||||
};
|
||||
let _ = || -> MultiUse {
|
||||
//~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700]
|
||||
mk_invar(b)
|
||||
};
|
||||
let _ = || {
|
||||
let _ = || -> MultiUse {
|
||||
//~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700]
|
||||
mk_invar(c)
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds
|
||||
--> $DIR/report-all-unexpected-hidden-errors.rs:18:19
|
||||
|
|
||||
LL | type MultiUse = impl Sized;
|
||||
| ---------- opaque type defined here
|
||||
...
|
||||
LL | let _ = || -> MultiUse {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: hidden type `Invar<'_>` captures lifetime `'_`
|
||||
|
||||
error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds
|
||||
--> $DIR/report-all-unexpected-hidden-errors.rs:22:19
|
||||
|
|
||||
LL | type MultiUse = impl Sized;
|
||||
| ---------- opaque type defined here
|
||||
...
|
||||
LL | let _ = || -> MultiUse {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: hidden type `Invar<'_>` captures lifetime `'_`
|
||||
|
||||
error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds
|
||||
--> $DIR/report-all-unexpected-hidden-errors.rs:27:23
|
||||
|
|
||||
LL | type MultiUse = impl Sized;
|
||||
| ---------- opaque type defined here
|
||||
...
|
||||
LL | let _ = || -> MultiUse {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: hidden type `Invar<'_>` captures lifetime `'_`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0700`.
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue