Auto merge of #132317 - workingjubilee:rollup-x21ncea, r=workingjubilee

Rollup of 12 pull requests

Successful merges:

 - #131375 (compiler: apply clippy::clone_on_ref_ptr for CI)
 - #131520 (Mark `str::is_char_boundary` and `str::split_at*` unstably `const`.)
 - #132119 (Hack out effects support for old solver)
 - #132194 (Collect item bounds for RPITITs from trait where clauses just like associated types)
 - #132216 (correct LLVMRustCreateThinLTOData arg types)
 - #132233 (Split `boxed.rs` into a few modules)
 - #132266 (riscv-soft-abi-with-float-features.rs: adapt for LLVM 20)
 - #132270 (clarified doc for `std::fs::OpenOptions.truncate()`)
 - #132284 (Remove my ping for rustdoc/clean/types.rs)
 - #132293 (Remove myself from mentions inside `tests/ui/check-cfg` directory)
 - #132312 (Delete `tests/crashes/23707.rs` because it's flaky)
 - #132313 (compiletest: Rename `command-list.rs` to `directive-list.rs`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-10-29 12:29:43 +00:00
commit 2dece5bb62
90 changed files with 1489 additions and 1413 deletions

View File

@ -3301,6 +3301,7 @@ version = "0.0.0"
dependencies = [
"itertools",
"rustc_ast",
"rustc_data_structures",
"rustc_lexer",
"rustc_span",
"thin-vec",

View File

@ -368,7 +368,7 @@ fn clone(&self) -> Self {
// a copy. This is faster than the `derive(Clone)` version which has a
// separate path for every variant.
match self {
Interpolated(nt) => Interpolated(nt.clone()),
Interpolated(nt) => Interpolated(Lrc::clone(nt)),
_ => unsafe { std::ptr::read(self) },
}
}

View File

@ -3,6 +3,7 @@
use rustc_ast::ptr::P as AstP;
use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
use rustc_hir as hir;
use rustc_hir::HirId;
use rustc_hir::def::{DefKind, Res};
@ -143,7 +144,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
ExprKind::IncludedBytes(bytes) => {
let lit = self.arena.alloc(respan(
self.lower_span(e.span),
LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
LitKind::ByteStr(Lrc::clone(bytes), StrStyle::Cooked),
));
hir::ExprKind::Lit(lit)
}
@ -536,7 +537,7 @@ fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> {
this.mark_span_with_reason(
DesugaringKind::TryBlock,
expr.span,
Some(this.allow_try_trait.clone()),
Some(Lrc::clone(&this.allow_try_trait)),
),
expr,
)
@ -544,7 +545,7 @@ fn lower_expr_try_block(&mut self, body: &Block) -> hir::ExprKind<'hir> {
let try_span = this.mark_span_with_reason(
DesugaringKind::TryBlock,
this.tcx.sess.source_map().end_point(body.span),
Some(this.allow_try_trait.clone()),
Some(Lrc::clone(&this.allow_try_trait)),
);
(try_span, this.expr_unit(try_span))
@ -653,7 +654,7 @@ pub(super) fn make_desugared_coroutine_expr(
let unstable_span = self.mark_span_with_reason(
DesugaringKind::Async,
self.lower_span(span),
Some(self.allow_gen_future.clone()),
Some(Lrc::clone(&self.allow_gen_future)),
);
let resume_ty =
self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None);
@ -739,7 +740,7 @@ pub(super) fn maybe_forward_track_caller(
let unstable_span = self.mark_span_with_reason(
DesugaringKind::Async,
span,
Some(self.allow_gen_future.clone()),
Some(Lrc::clone(&self.allow_gen_future)),
);
self.lower_attrs(inner_hir_id, &[Attribute {
kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
@ -815,13 +816,13 @@ fn make_lowered_await(
let features = match await_kind {
FutureKind::Future => None,
FutureKind::AsyncIterator => Some(self.allow_for_await.clone()),
FutureKind::AsyncIterator => Some(Lrc::clone(&self.allow_for_await)),
};
let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, features);
let gen_future_span = self.mark_span_with_reason(
DesugaringKind::Await,
full_span,
Some(self.allow_gen_future.clone()),
Some(Lrc::clone(&self.allow_gen_future)),
);
let expr_hir_id = expr.hir_id;
@ -1841,13 +1842,13 @@ fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir>
let unstable_span = self.mark_span_with_reason(
DesugaringKind::QuestionMark,
span,
Some(self.allow_try_trait.clone()),
Some(Lrc::clone(&self.allow_try_trait)),
);
let try_span = self.tcx.sess.source_map().end_point(span);
let try_span = self.mark_span_with_reason(
DesugaringKind::QuestionMark,
try_span,
Some(self.allow_try_trait.clone()),
Some(Lrc::clone(&self.allow_try_trait)),
);
// `Try::branch(<expr>)`
@ -1941,7 +1942,7 @@ fn lower_expr_yeet(&mut self, span: Span, sub_expr: Option<&Expr>) -> hir::ExprK
let unstable_span = self.mark_span_with_reason(
DesugaringKind::YeetExpr,
span,
Some(self.allow_try_trait.clone()),
Some(Lrc::clone(&self.allow_try_trait)),
);
let from_yeet_expr = self.wrap_in_try_constructor(

View File

@ -1878,7 +1878,7 @@ fn lower_coroutine_fn_ret_ty(
CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
(return_impl_trait_id, Some(self.allow_async_iterator.clone()))
(return_impl_trait_id, Some(Lrc::clone(&self.allow_async_iterator)))
}
};

View File

@ -73,7 +73,7 @@ pub(crate) fn lower_qpath(
let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res
&& self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some()
{
Some(self.allow_async_fn_traits.clone())
Some(Lrc::clone(&self.allow_async_fn_traits))
} else {
None
};

View File

@ -7,6 +7,7 @@ edition = "2021"
# tidy-alphabetical-start
itertools = "0.12"
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_span = { path = "../rustc_span" }
thin-vec = "0.2.12"

View File

@ -21,6 +21,7 @@
GenericBound, InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass,
InlineAsmTemplatePiece, PatKind, RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr,
};
use rustc_data_structures::sync::Lrc;
use rustc_span::edition::Edition;
use rustc_span::source_map::{SourceMap, Spanned};
use rustc_span::symbol::{Ident, IdentPrinter, Symbol, kw, sym};
@ -105,7 +106,7 @@ fn split_block_comment_into_lines(text: &str, col: CharPos) -> Vec<String> {
fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comment> {
let sm = SourceMap::new(sm.path_mapping().clone());
let source_file = sm.new_source_file(path, src);
let text = (*source_file.src.as_ref().unwrap()).clone();
let text = Lrc::clone(&(*source_file.src.as_ref().unwrap()));
let text: &str = text.as_str();
let start_bpos = source_file.start_pos;

View File

@ -107,13 +107,13 @@ pub(crate) fn compute_regions<'a, 'tcx>(
param_env,
body,
promoted,
universal_regions.clone(),
Rc::clone(&universal_regions),
location_table,
borrow_set,
&mut all_facts,
flow_inits,
move_data,
elements.clone(),
Rc::clone(&elements),
upvars,
);

View File

@ -733,7 +733,7 @@ fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex) {
}
// Now take member constraints into account.
let member_constraints = self.member_constraints.clone();
let member_constraints = Rc::clone(&self.member_constraints);
for m_c_i in member_constraints.indices(scc_a) {
self.apply_member_constraint(scc_a, m_c_i, member_constraints.choice_regions(m_c_i));
}
@ -1679,7 +1679,7 @@ fn check_member_constraints(
infcx: &InferCtxt<'tcx>,
errors_buffer: &mut RegionErrors<'tcx>,
) {
let member_constraints = self.member_constraints.clone();
let member_constraints = Rc::clone(&self.member_constraints);
for m_c_i in member_constraints.all_indices() {
debug!(?m_c_i);
let m_c = &member_constraints[m_c_i];

View File

@ -134,7 +134,7 @@ pub(crate) fn type_check<'a, 'tcx>(
let mut constraints = MirTypeckRegionConstraints {
placeholder_indices: PlaceholderIndices::default(),
placeholder_index_to_region: IndexVec::default(),
liveness_constraints: LivenessValues::with_specific_points(elements.clone()),
liveness_constraints: LivenessValues::with_specific_points(Rc::clone(&elements)),
outlives_constraints: OutlivesConstraintSet::default(),
member_constraints: MemberConstraintSet::default(),
type_tests: Vec::default(),
@ -150,7 +150,7 @@ pub(crate) fn type_check<'a, 'tcx>(
infcx,
param_env,
implicit_region_bound,
universal_regions.clone(),
Rc::clone(&universal_regions),
&mut constraints,
);

View File

@ -503,9 +503,9 @@ fn thin_lto(
// upstream...
let data = llvm::LLVMRustCreateThinLTOData(
thin_modules.as_ptr(),
thin_modules.len() as u32,
thin_modules.len(),
symbols_below_threshold.as_ptr(),
symbols_below_threshold.len() as u32,
symbols_below_threshold.len(),
)
.ok_or_else(|| write::llvm_err(dcx, LlvmError::PrepareThinLtoContext))?;
@ -570,7 +570,7 @@ fn thin_lto(
info!(" - {}: re-compiled", module_name);
opt_jobs.push(LtoModuleCodegen::Thin(ThinModule {
shared: shared.clone(),
shared: Arc::clone(&shared),
idx: module_index,
}));
}

View File

@ -2385,9 +2385,9 @@ pub fn LLVMRustThinLTOBufferCreate(
pub fn LLVMRustThinLTOBufferThinLinkDataLen(M: &ThinLTOBuffer) -> size_t;
pub fn LLVMRustCreateThinLTOData(
Modules: *const ThinLTOModule,
NumModules: c_uint,
NumModules: size_t,
PreservedSymbols: *const *const c_char,
PreservedSymbolsLen: c_uint,
PreservedSymbolsLen: size_t,
) -> Option<&'static mut ThinLTOData>;
pub fn LLVMRustPrepareThinLTORename(
Data: &ThinLTOData,

View File

@ -514,7 +514,7 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
future: Some(coordinator_thread),
phantom: PhantomData,
},
output_filenames: tcx.output_filenames(()).clone(),
output_filenames: Arc::clone(tcx.output_filenames(())),
}
}
@ -1203,7 +1203,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
coordinator_send,
expanded_args: tcx.sess.expanded_args.clone(),
diag_emitter: shared_emitter.clone(),
output_filenames: tcx.output_filenames(()).clone(),
output_filenames: Arc::clone(tcx.output_filenames(())),
regular_module_config: regular_config,
metadata_module_config: metadata_config,
allocator_module_config: allocator_config,

View File

@ -7,7 +7,7 @@
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::par_map;
use rustc_data_structures::sync::{Lrc, par_map};
use rustc_data_structures::unord::UnordMap;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
@ -923,7 +923,7 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
crate_name: UnordMap::with_capacity(n_crates),
used_crates,
used_crate_source: UnordMap::with_capacity(n_crates),
dependency_formats: tcx.dependency_formats(()).clone(),
dependency_formats: Lrc::clone(tcx.dependency_formats(())),
windows_subsystem,
natvis_debugger_visualizers: Default::default(),
};
@ -936,7 +936,7 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
info.crate_name.insert(cnum, tcx.crate_name(cnum));
let used_crate_source = tcx.used_crate_source(cnum);
info.used_crate_source.insert(cnum, used_crate_source.clone());
info.used_crate_source.insert(cnum, Lrc::clone(used_crate_source));
if tcx.is_profiler_runtime(cnum) {
info.profiler_runtime = Some(cnum);
}

View File

@ -1395,7 +1395,7 @@ pub fn install_ice_hook(
}
let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
let using_internal_features_hook = using_internal_features.clone();
let using_internal_features_hook = Arc::clone(&using_internal_features);
panic::update_hook(Box::new(
move |default_hook: &(dyn Fn(&PanicHookInfo<'_>) + Send + Sync + 'static),
info: &PanicHookInfo<'_>| {

View File

@ -173,7 +173,7 @@ fn emit_messages_default(
source_map.ensure_source_file_source_present(&file);
(
format!("{}", source_map.filename_for_diagnostics(&file.name)),
source_string(file.clone(), &line),
source_string(Lrc::clone(&file), &line),
line.line_index,
line.annotations,
)

View File

@ -1555,7 +1555,7 @@ fn emit_messages_default_inner(
// Get the left-side margin to remove it
let mut whitespace_margin = usize::MAX;
for line_idx in 0..annotated_file.lines.len() {
let file = annotated_file.file.clone();
let file = Lrc::clone(&annotated_file.file);
let line = &annotated_file.lines[line_idx];
if let Some(source_string) =
line.line_index.checked_sub(1).and_then(|l| file.get_line(l))
@ -1646,7 +1646,7 @@ fn emit_messages_default_inner(
let depths = self.render_source_line(
&mut buffer,
annotated_file.file.clone(),
Lrc::clone(&annotated_file.file),
&annotated_file.lines[line_idx],
width_offset,
code_offset,
@ -2529,7 +2529,12 @@ fn add_annotation_to_file(
// | | |
// | |______foo
// | baz
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
add_annotation_to_file(
&mut output,
Lrc::clone(&file),
ann.line_start,
ann.as_start(),
);
// 4 is the minimum vertical length of a multiline span when presented: two lines
// of code and two lines of underline. This is not true for the special case where
// the beginning doesn't have an underline, but the current logic seems to be
@ -2545,11 +2550,11 @@ fn add_annotation_to_file(
.unwrap_or(ann.line_start);
for line in ann.line_start + 1..until {
// Every `|` that joins the beginning of the span (`___^`) to the end (`|__^`).
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
add_annotation_to_file(&mut output, Lrc::clone(&file), line, ann.as_line());
}
let line_end = ann.line_end - 1;
if middle < line_end {
add_annotation_to_file(&mut output, file.clone(), line_end, ann.as_line());
add_annotation_to_file(&mut output, Lrc::clone(&file), line_end, ann.as_line());
}
} else {
end_ann.annotation_type = AnnotationType::Singleline;

View File

@ -367,9 +367,9 @@ fn reset(&mut self) -> io::Result<()> {
ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)),
ColorConfig::Never => {}
}
HumanEmitter::new(dst, je.fallback_bundle.clone())
HumanEmitter::new(dst, Lrc::clone(&je.fallback_bundle))
.short_message(short)
.sm(Some(je.sm.clone()))
.sm(Some(Lrc::clone(&je.sm)))
.fluent_bundle(je.fluent_bundle.clone())
.diagnostic_width(je.diagnostic_width)
.macro_backtrace(je.macro_backtrace)

View File

@ -622,7 +622,7 @@ pub(super) fn parse_tt<'matcher, T: Tracker<'matcher>>(
// possible next positions into `next_mps`. After some post-processing, the contents of
// `next_mps` replenish `cur_mps` and we start over again.
self.cur_mps.clear();
self.cur_mps.push(MatcherPos { idx: 0, matches: self.empty_matches.clone() });
self.cur_mps.push(MatcherPos { idx: 0, matches: Rc::clone(&self.empty_matches) });
loop {
self.next_mps.clear();

View File

@ -5,6 +5,7 @@
use rustc_ast::token::{self, Delimiter, IdentIsRaw, Lit, LitKind, Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
use rustc_parse::lexer::nfc_normalize;
use rustc_parse::parser::ParseNtResult;
@ -293,7 +294,7 @@ pub(super) fn transcribe<'a>(
// `Delimiter::Invisible` to maintain parsing priorities.
// `Interpolated` is currently used for such groups in rustc parser.
marker.visit_span(&mut sp);
TokenTree::token_alone(token::Interpolated(nt.clone()), sp)
TokenTree::token_alone(token::Interpolated(Lrc::clone(nt)), sp)
}
MatchedSeq(..) => {
// We were unable to descend far enough. This is an error.

View File

@ -149,10 +149,6 @@ hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported
hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice
.label = parameter captured again here
hir_analysis_effects_without_next_solver = using `#![feature(effects)]` without enabling next trait solver globally
.note = the next trait solver must be enabled globally for the effects feature to work correctly
.help = use `-Znext-solver` to enable
hir_analysis_empty_specialization = specialization impl does not specialize any associated items
.note = impl is a specialization of this impl

View File

@ -367,20 +367,8 @@ pub(super) fn explicit_item_bounds_with_filter(
// a projection self type.
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
let opaque_ty = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_opaque_ty();
let item_ty = Ty::new_projection_from_args(
tcx,
def_id.to_def_id(),
ty::GenericArgs::identity_for_item(tcx, def_id),
);
let bounds = opaque_type_bounds(
tcx,
opaque_def_id.expect_local(),
opaque_ty.bounds,
item_ty,
opaque_ty.span,
filter,
);
assert_only_contains_predicates_from(filter, bounds, item_ty);
let bounds =
associated_type_bounds(tcx, def_id, opaque_ty.bounds, opaque_ty.span, filter);
return ty::EarlyBinder::bind(bounds);
}
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(

View File

@ -1623,12 +1623,6 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
pub receiver_ty: Ty<'tcx>,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_effects_without_next_solver)]
#[note]
#[help]
pub(crate) struct EffectsWithoutNextSolver;
#[derive(Diagnostic)]
#[diag(hir_analysis_cmse_inputs_stack_spill, code = E0798)]
#[note]

View File

@ -153,12 +153,6 @@ pub fn provide(providers: &mut Providers) {
pub fn check_crate(tcx: TyCtxt<'_>) {
let _prof_timer = tcx.sess.timer("type_check_crate");
// FIXME(effects): remove once effects is implemented in old trait solver
// or if the next solver is stabilized.
if tcx.features().effects() && !tcx.next_trait_solver_globally() {
tcx.dcx().emit_err(errors::EffectsWithoutNextSolver);
}
tcx.sess.time("coherence_checking", || {
tcx.hir().par_for_each_module(|module| {
let _ = tcx.ensure().check_mod_type_wf(module);

View File

@ -364,7 +364,7 @@ pub fn register_member_constraints(
span,
concrete_ty,
r,
choice_regions.clone(),
Lrc::clone(&choice_regions),
)
},
});

View File

@ -142,7 +142,7 @@ pub fn codegen_and_build_linker(
Ok(Linker {
dep_graph: tcx.dep_graph.clone(),
output_filenames: tcx.output_filenames(()).clone(),
output_filenames: Arc::clone(tcx.output_filenames(())),
crate_hash: if tcx.needs_crate_hash() {
Some(tcx.crate_hash(LOCAL_CRATE))
} else {

View File

@ -1251,12 +1251,12 @@ getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
// here is basically the same as before threads are spawned in the `run`
// function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
extern "C" LLVMRustThinLTOData *
LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules,
const char **preserved_symbols, int num_symbols) {
LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, size_t num_modules,
const char **preserved_symbols, size_t num_symbols) {
auto Ret = std::make_unique<LLVMRustThinLTOData>();
// Load each module's summary and merge it into one combined index
for (int i = 0; i < num_modules; i++) {
for (size_t i = 0; i < num_modules; i++) {
auto module = &modules[i];
auto buffer = StringRef(module->data, module->len);
auto mem_buffer = MemoryBufferRef(buffer, module->identifier);
@ -1275,7 +1275,7 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules,
// Convert the preserved symbols set from string to GUID, this is then needed
// for internalization.
for (int i = 0; i < num_symbols; i++) {
for (size_t i = 0; i < num_symbols; i++) {
auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
Ret->GUIDPreservedSymbols.insert(GUID);
}

View File

@ -1231,7 +1231,7 @@ extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
return dwarf::DW_OP_plus_uconst;
}
extern "C" int64_t LLVMRustDIBuilderCreateOpLLVMFragment() {
extern "C" uint64_t LLVMRustDIBuilderCreateOpLLVMFragment() {
return dwarf::DW_OP_LLVM_fragment;
}

View File

@ -278,7 +278,7 @@ fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
let source_map = s.tcx.sess.source_map();
let source_file_index = source_map.lookup_source_file_idx(self.lo);
s.source_file_cache =
(source_map.files()[source_file_index].clone(), source_file_index);
(Lrc::clone(&source_map.files()[source_file_index]), source_file_index);
}
let (ref source_file, source_file_index) = s.source_file_cache;
debug_assert!(source_file.contains(self.lo));
@ -2275,7 +2275,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
encoder.emit_raw_bytes(&0u64.to_le_bytes());
let source_map_files = tcx.sess.source_map().files();
let source_file_cache = (source_map_files[0].clone(), 0);
let source_file_cache = (Lrc::clone(&source_map_files[0]), 0);
let required_source_files = Some(FxIndexSet::default());
drop(source_map_files);

View File

@ -32,7 +32,7 @@ pub fn new(src: Lrc<[u8]>, visualizer_type: DebuggerVisualizerType, path: PathBu
pub fn path_erased(&self) -> Self {
DebuggerVisualizerFile {
src: self.src.clone(),
src: Lrc::clone(&self.src),
visualizer_type: self.visualizer_type,
path: None,
}

View File

@ -472,13 +472,9 @@ fn file_index_to_file(&self, index: SourceFileIndex) -> Lrc<SourceFile> {
let CacheDecoder { tcx, file_index_to_file, file_index_to_stable_id, source_map, .. } =
*self;
file_index_to_file
.borrow_mut()
.entry(index)
.or_insert_with(|| {
Lrc::clone(file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
let source_file_id = &file_index_to_stable_id[&index];
let source_file_cnum =
tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
let source_file_cnum = tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
// If this `SourceFile` is from a foreign crate, then make sure
// that we've imported all of the source files from that crate.
@ -496,8 +492,7 @@ fn file_index_to_file(&self, index: SourceFileIndex) -> Lrc<SourceFile> {
source_map
.source_file_by_stable_id(source_file_id.stable_source_file_id)
.expect("failed to lookup `SourceFile` in new context")
})
.clone()
}))
}
}

View File

@ -14,6 +14,7 @@
};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult, Subdiagnostic,
Suggestions, pluralize,
@ -2437,7 +2438,7 @@ pub(super) fn expected_expression_found(&self) -> Diag<'a> {
let mut labels = vec![];
while let TokenKind::Interpolated(nt) = &tok.kind {
let tokens = nt.tokens();
labels.push(nt.clone());
labels.push(Lrc::clone(nt));
if let Some(tokens) = tokens
&& let tokens = tokens.to_attr_token_stream()
&& let tokens = tokens.0.deref()

View File

@ -134,7 +134,7 @@ pub fn new(
encoder,
record_graph,
record_stats,
prev_graph.clone(),
Arc::clone(&prev_graph),
);
let colors = DepNodeColorMap::new(prev_graph_node_count);

View File

@ -237,7 +237,7 @@ fn wait_on_inner(&self, waiter: &Arc<QueryWaiter>) {
// the `wait` call below, by 1) the `set` method or 2) by deadlock detection.
// Both of these will remove it from the `waiters` list before resuming
// this thread.
info.waiters.push(waiter.clone());
info.waiters.push(Arc::clone(waiter));
// If this detects a deadlock and the deadlock handler wants to resume this thread
// we have to be in the `wait` call. This is ensured by the deadlock handler

View File

@ -1694,9 +1694,9 @@ fn cstore(&self) -> FreezeReadGuard<'_, CStore> {
fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> {
match macro_kind {
MacroKind::Bang => self.dummy_ext_bang.clone(),
MacroKind::Derive => self.dummy_ext_derive.clone(),
MacroKind::Attr => self.non_macro_attr.ext.clone(),
MacroKind::Bang => Lrc::clone(&self.dummy_ext_bang),
MacroKind::Derive => Lrc::clone(&self.dummy_ext_derive),
MacroKind::Attr => Lrc::clone(&self.non_macro_attr.ext),
}
}

View File

@ -826,7 +826,7 @@ fn resolve_macro_or_delegation_path(
}
_ => None,
},
None => self.get_macro(res).map(|macro_data| macro_data.ext.clone()),
None => self.get_macro(res).map(|macro_data| Lrc::clone(&macro_data.ext)),
};
Ok((ext, res))
}

View File

@ -241,7 +241,7 @@ pub fn new(locale_resources: Vec<&'static str>) -> Self {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let emitter = Box::new(
HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle)
.sm(Some(sm.clone())),
.sm(Some(Lrc::clone(&sm))),
);
let dcx = DiagCtxt::new(emitter);
ParseSess::with_dcx(dcx, sm)
@ -278,7 +278,7 @@ pub fn with_silent_emitter(
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let emitter = Box::new(HumanEmitter::new(
stderr_destination(ColorConfig::Auto),
fallback_bundle.clone(),
Lrc::clone(&fallback_bundle),
));
let fatal_dcx = DiagCtxt::new(emitter);
let dcx = DiagCtxt::new(Box::new(SilentEmitter {
@ -297,7 +297,7 @@ pub fn source_map(&self) -> &SourceMap {
}
pub fn clone_source_map(&self) -> Lrc<SourceMap> {
self.source_map.clone()
Lrc::clone(&self.source_map)
}
pub fn buffer_lint(

View File

@ -1036,7 +1036,8 @@ pub fn build_session(
sopts.unstable_opts.translate_directionality_markers,
);
let source_map = rustc_span::source_map::get_source_map().unwrap();
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
let emitter =
default_emitter(&sopts, registry, Lrc::clone(&source_map), bundle, fallback_bundle);
let mut dcx =
DiagCtxt::new(emitter).with_flags(sopts.unstable_opts.dcx_flags(can_emit_warnings));
@ -1079,7 +1080,7 @@ pub fn build_session(
let target_tlib_path = if host_triple == target_triple {
// Use the same `SearchPath` if host and target triple are identical to avoid unnecessary
// rescanning of the target lib path and an unnecessary allocation.
host_tlib_path.clone()
Lrc::clone(&host_tlib_path)
} else {
Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
};

View File

@ -63,7 +63,7 @@ pub struct CachingSourceMapView<'sm> {
impl<'sm> CachingSourceMapView<'sm> {
pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> {
let files = source_map.files();
let first_file = files[0].clone();
let first_file = Lrc::clone(&files[0]);
let entry = CacheEntry {
time_stamp: 0,
line_number: 0,
@ -92,7 +92,7 @@ pub fn byte_pos_to_line_and_col(
cache_entry.touch(self.time_stamp);
let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32());
return Some((cache_entry.file.clone(), cache_entry.line_number, col));
return Some((Lrc::clone(&cache_entry.file), cache_entry.line_number, col));
}
// No cache hit ...
@ -109,7 +109,7 @@ pub fn byte_pos_to_line_and_col(
cache_entry.update(new_file_and_idx, pos, self.time_stamp);
let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32());
Some((cache_entry.file.clone(), cache_entry.line_number, col))
Some((Lrc::clone(&cache_entry.file), cache_entry.line_number, col))
}
pub fn span_data_to_lines_and_cols(
@ -133,7 +133,7 @@ pub fn span_data_to_lines_and_cols(
}
(
lo.file.clone(),
Lrc::clone(&lo.file),
lo.line_number,
span_data.lo - lo.line.start,
hi.line_number,
@ -181,7 +181,7 @@ pub fn span_data_to_lines_and_cols(
lo.update(new_file_and_idx, span_data.lo, self.time_stamp);
if !lo.line.contains(&span_data.hi) {
let new_file_and_idx = Some((lo.file.clone(), lo.file_index));
let new_file_and_idx = Some((Lrc::clone(&lo.file), lo.file_index));
let next_oldest = self.oldest_cache_entry_index_avoid(oldest);
let hi = &mut self.line_cache[next_oldest];
hi.update(new_file_and_idx, span_data.hi, self.time_stamp);
@ -227,7 +227,7 @@ pub fn span_data_to_lines_and_cols(
assert_eq!(lo.file_index, hi.file_index);
Some((
lo.file.clone(),
Lrc::clone(&lo.file),
lo.line_number,
span_data.lo - lo.line.start,
hi.line_number,
@ -277,7 +277,7 @@ fn file_for_position(&self, pos: BytePos) -> Option<(Lrc<SourceFile>, usize)> {
let file = &self.source_map.files()[file_idx];
if file_contains(file, pos) {
return Some((file.clone(), file_idx));
return Some((Lrc::clone(file), file_idx));
}
}

View File

@ -286,8 +286,8 @@ fn register_source_file(
});
let file = Lrc::new(file);
files.source_files.push(file.clone());
files.stable_id_to_source_file.insert(file_id, file.clone());
files.source_files.push(Lrc::clone(&file));
files.stable_id_to_source_file.insert(file_id, Lrc::clone(&file));
Ok(file)
}
@ -386,7 +386,7 @@ pub fn doctest_offset_line(&self, file: &FileName, orig: usize) -> usize {
/// Return the SourceFile that contains the given `BytePos`
pub fn lookup_source_file(&self, pos: BytePos) -> Lrc<SourceFile> {
let idx = self.lookup_source_file_idx(pos);
(*self.files.borrow().source_files)[idx].clone()
Lrc::clone(&(*self.files.borrow().source_files)[idx])
}
/// Looks up source information about a `BytePos`.
@ -468,7 +468,7 @@ pub fn is_multiline(&self, sp: Span) -> bool {
if lo != hi {
return true;
}
let f = (*self.files.borrow().source_files)[lo].clone();
let f = Lrc::clone(&(*self.files.borrow().source_files)[lo]);
let lo = f.relative_position(sp.lo());
let hi = f.relative_position(sp.hi());
f.lookup_line(lo) != f.lookup_line(hi)
@ -994,7 +994,7 @@ pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
let filename = self.path_mapping().map_filename_prefix(filename).0;
for sf in self.files.borrow().source_files.iter() {
if filename == sf.name {
return Some(sf.clone());
return Some(Lrc::clone(&sf));
}
}
None
@ -1003,7 +1003,7 @@ pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
/// For a global `BytePos`, computes the local offset within the containing `SourceFile`.
pub fn lookup_byte_offset(&self, bpos: BytePos) -> SourceFileAndBytePos {
let idx = self.lookup_source_file_idx(bpos);
let sf = (*self.files.borrow().source_files)[idx].clone();
let sf = Lrc::clone(&(*self.files.borrow().source_files)[idx]);
let offset = bpos - sf.start_pos;
SourceFileAndBytePos { sf, pos: offset }
}

View File

@ -0,0 +1,152 @@
use rustc_hir as hir;
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt};
use rustc_infer::traits::{ImplSource, Obligation, PredicateObligation};
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
use rustc_middle::{span_bug, ty};
use rustc_type_ir::solve::NoSolution;
use thin_vec::ThinVec;
use super::SelectionContext;
pub type HostEffectObligation<'tcx> = Obligation<'tcx, ty::HostEffectPredicate<'tcx>>;
pub enum EvaluationFailure {
Ambiguous,
NoSolution,
}
pub fn evaluate_host_effect_obligation<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
if selcx.infcx.intercrate {
span_bug!(
obligation.cause.span,
"should not select host obligation in old solver in intercrate mode"
);
}
match evaluate_host_effect_from_bounds(selcx, obligation) {
Ok(result) => return Ok(result),
Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
Err(EvaluationFailure::NoSolution) => {}
}
match evaluate_host_effect_from_selection_candiate(selcx, obligation) {
Ok(result) => return Ok(result),
Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
Err(EvaluationFailure::NoSolution) => {}
}
Err(EvaluationFailure::NoSolution)
}
fn match_candidate<'tcx>(
infcx: &InferCtxt<'tcx>,
obligation: &HostEffectObligation<'tcx>,
candidate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, NoSolution> {
if !candidate.skip_binder().host.satisfies(obligation.predicate.host) {
return Err(NoSolution);
}
let candidate = infcx.instantiate_binder_with_fresh_vars(
obligation.cause.span,
BoundRegionConversionTime::HigherRankedType,
candidate,
);
let mut nested = infcx
.at(&obligation.cause, obligation.param_env)
.eq(DefineOpaqueTypes::Yes, obligation.predicate.trait_ref, candidate.trait_ref)?
.into_obligations();
for nested in &mut nested {
nested.set_depth_from_parent(obligation.recursion_depth);
}
Ok(nested)
}
fn evaluate_host_effect_from_bounds<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
let infcx = selcx.infcx;
let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx());
let mut candidate = None;
for predicate in obligation.param_env.caller_bounds() {
let bound_predicate = predicate.kind();
if let ty::ClauseKind::HostEffect(data) = predicate.kind().skip_binder() {
let data = bound_predicate.rebind(data);
if data.skip_binder().trait_ref.def_id != obligation.predicate.trait_ref.def_id {
continue;
}
if !drcx.args_may_unify(
obligation.predicate.trait_ref.args,
data.skip_binder().trait_ref.args,
) {
continue;
}
let is_match = infcx.probe(|_| match_candidate(infcx, obligation, data).is_ok());
if is_match {
if candidate.is_some() {
return Err(EvaluationFailure::Ambiguous);
} else {
candidate = Some(data);
}
}
}
}
if let Some(data) = candidate {
Ok(match_candidate(infcx, obligation, data)
.expect("candidate matched before, so it should match again"))
} else {
Err(EvaluationFailure::NoSolution)
}
}
fn evaluate_host_effect_from_selection_candiate<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
let tcx = selcx.tcx();
selcx.infcx.commit_if_ok(|_| {
match selcx.select(&obligation.with(tcx, obligation.predicate.trait_ref)) {
Ok(None) => Err(EvaluationFailure::Ambiguous),
Err(_) => Err(EvaluationFailure::NoSolution),
Ok(Some(source)) => match source {
ImplSource::UserDefined(impl_) => {
if tcx.constness(impl_.impl_def_id) != hir::Constness::Const {
return Err(EvaluationFailure::NoSolution);
}
let mut nested = impl_.nested;
nested.extend(
tcx.const_conditions(impl_.impl_def_id)
.instantiate(tcx, impl_.args)
.into_iter()
.map(|(trait_ref, _)| {
obligation.with(
tcx,
trait_ref.to_host_effect_clause(tcx, obligation.predicate.host),
)
}),
);
for nested in &mut nested {
nested.set_depth_from_parent(obligation.recursion_depth);
}
Ok(nested)
}
_ => Err(EvaluationFailure::NoSolution),
},
}
})
}

View File

@ -17,6 +17,7 @@
use thin_vec::ThinVec;
use tracing::{debug, debug_span, instrument};
use super::effects::{self, HostEffectObligation};
use super::project::{self, ProjectAndUnifyResult};
use super::select::SelectionContext;
use super::{
@ -402,8 +403,13 @@ fn process_obligation(
)
}
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
ProcessResult::Changed(Default::default())
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
let host_obligation = obligation.with(infcx.tcx, data);
self.process_host_obligation(
host_obligation,
&mut pending_obligation.stalled_on,
)
}
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
@ -854,6 +860,27 @@ fn process_projection_obligation(
}
}
}
fn process_host_obligation(
&mut self,
host_obligation: HostEffectObligation<'tcx>,
stalled_on: &mut Vec<TyOrConstInferVar>,
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
match effects::evaluate_host_effect_obligation(&mut self.selcx, &host_obligation) {
Ok(nested) => ProcessResult::Changed(mk_pending(nested)),
Err(effects::EvaluationFailure::Ambiguous) => {
stalled_on.clear();
stalled_on.extend(args_infer_vars(
&self.selcx,
ty::Binder::dummy(host_obligation.predicate.trait_ref.args),
));
ProcessResult::Unchanged
}
Err(effects::EvaluationFailure::NoSolution) => {
ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::Unimplemented))
}
}
}
}
/// Returns the set of inference variables contained in `args`.

View File

@ -6,6 +6,7 @@
pub(crate) mod coherence;
pub mod const_evaluatable;
mod dyn_compatibility;
pub mod effects;
mod engine;
mod fulfill;
pub mod misc;

View File

@ -49,7 +49,7 @@
use crate::solve::InferCtxtSelectExt as _;
use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt};
use crate::traits::{ProjectionCacheKey, Unimplemented};
use crate::traits::{ProjectionCacheKey, Unimplemented, effects};
mod _match;
mod candidate_assembly;
@ -645,11 +645,19 @@ fn evaluate_predicate_recursively<'o>(
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
}
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
// FIXME(effects): It should be relatively straightforward to implement
// old trait solver support for `HostEffect` bounds; or at least basic
// support for them.
todo!()
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
self.infcx.enter_forall(bound_predicate.rebind(data), |data| {
match effects::evaluate_host_effect_obligation(
self,
&obligation.with(self.tcx(), data),
) {
Ok(nested) => {
self.evaluate_predicates_recursively(previous_stack, nested)
}
Err(effects::EvaluationFailure::Ambiguous) => Ok(EvaluatedToAmbig),
Err(effects::EvaluationFailure::NoSolution) => Ok(EvaluatedToErr),
}
})
}
ty::PredicateKind::Subtype(p) => {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,747 @@
use core::any::Any;
use core::error::Error;
use core::mem;
use core::pin::Pin;
#[cfg(not(no_global_oom_handling))]
use core::{fmt, ptr};
use crate::alloc::Allocator;
#[cfg(not(no_global_oom_handling))]
use crate::borrow::Cow;
use crate::boxed::Box;
#[cfg(not(no_global_oom_handling))]
use crate::raw_vec::RawVec;
#[cfg(not(no_global_oom_handling))]
use crate::str::from_boxed_utf8_unchecked;
#[cfg(not(no_global_oom_handling))]
use crate::string::String;
#[cfg(not(no_global_oom_handling))]
use crate::vec::Vec;
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "from_for_ptrs", since = "1.6.0")]
impl<T> From<T> for Box<T> {
/// Converts a `T` into a `Box<T>`
///
/// The conversion allocates on the heap and moves `t`
/// from the stack into it.
///
/// # Examples
///
/// ```rust
/// let x = 5;
/// let boxed = Box::new(5);
///
/// assert_eq!(Box::from(x), boxed);
/// ```
fn from(t: T) -> Self {
Box::new(t)
}
}
#[stable(feature = "pin", since = "1.33.0")]
impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
where
A: 'static,
{
/// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
/// `*boxed` will be pinned in memory and unable to be moved.
///
/// This conversion does not allocate on the heap and happens in place.
///
/// This is also available via [`Box::into_pin`].
///
/// Constructing and pinning a `Box` with <code><Pin<Box\<T>>>::from([Box::new]\(x))</code>
/// can also be written more concisely using <code>[Box::pin]\(x)</code>.
/// This `From` implementation is useful if you already have a `Box<T>`, or you are
/// constructing a (pinned) `Box` in a different way than with [`Box::new`].
fn from(boxed: Box<T, A>) -> Self {
Box::into_pin(boxed)
}
}
/// Specialization trait used for `From<&[T]>`.
#[cfg(not(no_global_oom_handling))]
trait BoxFromSlice<T> {
fn from_slice(slice: &[T]) -> Self;
}
#[cfg(not(no_global_oom_handling))]
impl<T: Clone> BoxFromSlice<T> for Box<[T]> {
#[inline]
default fn from_slice(slice: &[T]) -> Self {
slice.to_vec().into_boxed_slice()
}
}
#[cfg(not(no_global_oom_handling))]
impl<T: Copy> BoxFromSlice<T> for Box<[T]> {
#[inline]
fn from_slice(slice: &[T]) -> Self {
let len = slice.len();
let buf = RawVec::with_capacity(len);
unsafe {
ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len);
buf.into_box(slice.len()).assume_init()
}
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<T: Clone> From<&[T]> for Box<[T]> {
/// Converts a `&[T]` into a `Box<[T]>`
///
/// This conversion allocates on the heap
/// and performs a copy of `slice` and its contents.
///
/// # Examples
/// ```rust
/// // create a &[u8] which will be used to create a Box<[u8]>
/// let slice: &[u8] = &[104, 101, 108, 108, 111];
/// let boxed_slice: Box<[u8]> = Box::from(slice);
///
/// println!("{boxed_slice:?}");
/// ```
#[inline]
fn from(slice: &[T]) -> Box<[T]> {
<Self as BoxFromSlice<T>>::from_slice(slice)
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_cow", since = "1.45.0")]
impl<T: Clone> From<Cow<'_, [T]>> for Box<[T]> {
/// Converts a `Cow<'_, [T]>` into a `Box<[T]>`
///
/// When `cow` is the `Cow::Borrowed` variant, this
/// conversion allocates on the heap and copies the
/// underlying slice. Otherwise, it will try to reuse the owned
/// `Vec`'s allocation.
#[inline]
fn from(cow: Cow<'_, [T]>) -> Box<[T]> {
match cow {
Cow::Borrowed(slice) => Box::from(slice),
Cow::Owned(slice) => Box::from(slice),
}
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_slice", since = "1.17.0")]
impl From<&str> for Box<str> {
/// Converts a `&str` into a `Box<str>`
///
/// This conversion allocates on the heap
/// and performs a copy of `s`.
///
/// # Examples
///
/// ```rust
/// let boxed: Box<str> = Box::from("hello");
/// println!("{boxed}");
/// ```
#[inline]
fn from(s: &str) -> Box<str> {
unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) }
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_cow", since = "1.45.0")]
impl From<Cow<'_, str>> for Box<str> {
/// Converts a `Cow<'_, str>` into a `Box<str>`
///
/// When `cow` is the `Cow::Borrowed` variant, this
/// conversion allocates on the heap and copies the
/// underlying `str`. Otherwise, it will try to reuse the owned
/// `String`'s allocation.
///
/// # Examples
///
/// ```rust
/// use std::borrow::Cow;
///
/// let unboxed = Cow::Borrowed("hello");
/// let boxed: Box<str> = Box::from(unboxed);
/// println!("{boxed}");
/// ```
///
/// ```rust
/// # use std::borrow::Cow;
/// let unboxed = Cow::Owned("hello".to_string());
/// let boxed: Box<str> = Box::from(unboxed);
/// println!("{boxed}");
/// ```
#[inline]
fn from(cow: Cow<'_, str>) -> Box<str> {
match cow {
Cow::Borrowed(s) => Box::from(s),
Cow::Owned(s) => Box::from(s),
}
}
}
#[stable(feature = "boxed_str_conv", since = "1.19.0")]
impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
/// Converts a `Box<str>` into a `Box<[u8]>`
///
/// This conversion does not allocate on the heap and happens in place.
///
/// # Examples
/// ```rust
/// // create a Box<str> which will be used to create a Box<[u8]>
/// let boxed: Box<str> = Box::from("hello");
/// let boxed_str: Box<[u8]> = Box::from(boxed);
///
/// // create a &[u8] which will be used to create a Box<[u8]>
/// let slice: &[u8] = &[104, 101, 108, 108, 111];
/// let boxed_slice = Box::from(slice);
///
/// assert_eq!(boxed_slice, boxed_str);
/// ```
#[inline]
fn from(s: Box<str, A>) -> Self {
let (raw, alloc) = Box::into_raw_with_allocator(s);
unsafe { Box::from_raw_in(raw as *mut [u8], alloc) }
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_from_array", since = "1.45.0")]
impl<T, const N: usize> From<[T; N]> for Box<[T]> {
/// Converts a `[T; N]` into a `Box<[T]>`
///
/// This conversion moves the array to newly heap-allocated memory.
///
/// # Examples
///
/// ```rust
/// let boxed: Box<[u8]> = Box::from([4, 2]);
/// println!("{boxed:?}");
/// ```
fn from(array: [T; N]) -> Box<[T]> {
Box::new(array)
}
}
/// Casts a boxed slice to a boxed array.
///
/// # Safety
///
/// `boxed_slice.len()` must be exactly `N`.
unsafe fn boxed_slice_as_array_unchecked<T, A: Allocator, const N: usize>(
boxed_slice: Box<[T], A>,
) -> Box<[T; N], A> {
debug_assert_eq!(boxed_slice.len(), N);
let (ptr, alloc) = Box::into_raw_with_allocator(boxed_slice);
// SAFETY: Pointer and allocator came from an existing box,
// and our safety condition requires that the length is exactly `N`
unsafe { Box::from_raw_in(ptr as *mut [T; N], alloc) }
}
#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
type Error = Box<[T]>;
/// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
///
/// The conversion occurs in-place and does not require a
/// new memory allocation.
///
/// # Errors
///
/// Returns the old `Box<[T]>` in the `Err` variant if
/// `boxed_slice.len()` does not equal `N`.
fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
if boxed_slice.len() == N {
Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
} else {
Err(boxed_slice)
}
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_array_try_from_vec", since = "1.66.0")]
impl<T, const N: usize> TryFrom<Vec<T>> for Box<[T; N]> {
type Error = Vec<T>;
/// Attempts to convert a `Vec<T>` into a `Box<[T; N]>`.
///
/// Like [`Vec::into_boxed_slice`], this is in-place if `vec.capacity() == N`,
/// but will require a reallocation otherwise.
///
/// # Errors
///
/// Returns the original `Vec<T>` in the `Err` variant if
/// `boxed_slice.len()` does not equal `N`.
///
/// # Examples
///
/// This can be used with [`vec!`] to create an array on the heap:
///
/// ```
/// let state: Box<[f32; 100]> = vec![1.0; 100].try_into().unwrap();
/// assert_eq!(state.len(), 100);
/// ```
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
if vec.len() == N {
let boxed_slice = vec.into_boxed_slice();
Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) })
} else {
Err(vec)
}
}
}
impl<A: Allocator> Box<dyn Any, A> {
/// Attempts to downcast the box to a concrete type.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn print_if_string(value: Box<dyn Any>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
/// }
///
/// let my_string = "Hello World".to_string();
/// print_if_string(Box::new(my_string));
/// print_if_string(Box::new(0i8));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
}
/// Downcasts the box to a concrete type.
///
/// For a safe alternative see [`downcast`].
///
/// # Examples
///
/// ```
/// #![feature(downcast_unchecked)]
///
/// use std::any::Any;
///
/// let x: Box<dyn Any> = Box::new(1_usize);
///
/// unsafe {
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
/// }
/// ```
///
/// # Safety
///
/// The contained value must be of type `T`. Calling this method
/// with the incorrect type is *undefined behavior*.
///
/// [`downcast`]: Self::downcast
#[inline]
#[unstable(feature = "downcast_unchecked", issue = "90850")]
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
debug_assert!(self.is::<T>());
unsafe {
let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self);
Box::from_raw_in(raw as *mut T, alloc)
}
}
}
impl<A: Allocator> Box<dyn Any + Send, A> {
/// Attempts to downcast the box to a concrete type.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn print_if_string(value: Box<dyn Any + Send>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
/// }
///
/// let my_string = "Hello World".to_string();
/// print_if_string(Box::new(my_string));
/// print_if_string(Box::new(0i8));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
}
/// Downcasts the box to a concrete type.
///
/// For a safe alternative see [`downcast`].
///
/// # Examples
///
/// ```
/// #![feature(downcast_unchecked)]
///
/// use std::any::Any;
///
/// let x: Box<dyn Any + Send> = Box::new(1_usize);
///
/// unsafe {
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
/// }
/// ```
///
/// # Safety
///
/// The contained value must be of type `T`. Calling this method
/// with the incorrect type is *undefined behavior*.
///
/// [`downcast`]: Self::downcast
#[inline]
#[unstable(feature = "downcast_unchecked", issue = "90850")]
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
debug_assert!(self.is::<T>());
unsafe {
let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self);
Box::from_raw_in(raw as *mut T, alloc)
}
}
}
impl<A: Allocator> Box<dyn Any + Send + Sync, A> {
/// Attempts to downcast the box to a concrete type.
///
/// # Examples
///
/// ```
/// use std::any::Any;
///
/// fn print_if_string(value: Box<dyn Any + Send + Sync>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
/// }
///
/// let my_string = "Hello World".to_string();
/// print_if_string(Box::new(my_string));
/// print_if_string(Box::new(0i8));
/// ```
#[inline]
#[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")]
pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
if self.is::<T>() { unsafe { Ok(self.downcast_unchecked::<T>()) } } else { Err(self) }
}
/// Downcasts the box to a concrete type.
///
/// For a safe alternative see [`downcast`].
///
/// # Examples
///
/// ```
/// #![feature(downcast_unchecked)]
///
/// use std::any::Any;
///
/// let x: Box<dyn Any + Send + Sync> = Box::new(1_usize);
///
/// unsafe {
/// assert_eq!(*x.downcast_unchecked::<usize>(), 1);
/// }
/// ```
///
/// # Safety
///
/// The contained value must be of type `T`. Calling this method
/// with the incorrect type is *undefined behavior*.
///
/// [`downcast`]: Self::downcast
#[inline]
#[unstable(feature = "downcast_unchecked", issue = "90850")]
pub unsafe fn downcast_unchecked<T: Any>(self) -> Box<T, A> {
debug_assert!(self.is::<T>());
unsafe {
let (raw, alloc): (*mut (dyn Any + Send + Sync), _) =
Box::into_raw_with_allocator(self);
Box::from_raw_in(raw as *mut T, alloc)
}
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
/// Converts a type of [`Error`] into a box of dyn [`Error`].
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::fmt;
/// use std::mem;
///
/// #[derive(Debug)]
/// struct AnError;
///
/// impl fmt::Display for AnError {
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// write!(f, "An error")
/// }
/// }
///
/// impl Error for AnError {}
///
/// let an_error = AnError;
/// assert!(0 == mem::size_of_val(&an_error));
/// let a_boxed_error = Box::<dyn Error>::from(an_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: E) -> Box<dyn Error + 'a> {
Box::new(err)
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of
/// dyn [`Error`] + [`Send`] + [`Sync`].
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::fmt;
/// use std::mem;
///
/// #[derive(Debug)]
/// struct AnError;
///
/// impl fmt::Display for AnError {
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// write!(f, "An error")
/// }
/// }
///
/// impl Error for AnError {}
///
/// unsafe impl Send for AnError {}
///
/// unsafe impl Sync for AnError {}
///
/// let an_error = AnError;
/// assert!(0 == mem::size_of_val(&an_error));
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
Box::new(err)
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<String> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::mem;
///
/// let a_string_error = "a string error".to_string();
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
#[inline]
fn from(err: String) -> Box<dyn Error + Send + Sync + 'a> {
struct StringError(String);
impl Error for StringError {
#[allow(deprecated)]
fn description(&self) -> &str {
&self.0
}
}
impl fmt::Display for StringError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
// Purposefully skip printing "StringError(..)"
impl fmt::Debug for StringError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
Box::new(StringError(err))
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "string_box_error", since = "1.6.0")]
impl<'a> From<String> for Box<dyn Error + 'a> {
/// Converts a [`String`] into a box of dyn [`Error`].
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::mem;
///
/// let a_string_error = "a string error".to_string();
/// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(str_err: String) -> Box<dyn Error + 'a> {
let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
let err2: Box<dyn Error> = err1;
err2
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
/// [`str`]: prim@str
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::mem;
///
/// let a_str_error = "a str error";
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
#[inline]
fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
From::from(String::from(err))
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "string_box_error", since = "1.6.0")]
impl<'a> From<&str> for Box<dyn Error + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`].
///
/// [`str`]: prim@str
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::mem;
///
/// let a_str_error = "a str error";
/// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: &str) -> Box<dyn Error + 'a> {
From::from(String::from(err))
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "cow_box_error", since = "1.22.0")]
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::mem;
/// use std::borrow::Cow;
///
/// let a_cow_str_error = Cow::from("a str error");
/// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
From::from(String::from(err))
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "cow_box_error", since = "1.22.0")]
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + 'a> {
/// Converts a [`Cow`] into a box of dyn [`Error`].
///
/// # Examples
///
/// ```
/// use std::error::Error;
/// use std::mem;
/// use std::borrow::Cow;
///
/// let a_cow_str_error = Cow::from("a str error");
/// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: Cow<'b, str>) -> Box<dyn Error + 'a> {
From::from(String::from(err))
}
}
impl dyn Error {
/// Attempts to downcast the box to a concrete type.
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[rustc_allow_incoherent_impl]
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
if self.is::<T>() {
unsafe {
let raw: *mut dyn Error = Box::into_raw(self);
Ok(Box::from_raw(raw as *mut T))
}
} else {
Err(self)
}
}
}
impl dyn Error + Send {
/// Attempts to downcast the box to a concrete type.
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[rustc_allow_incoherent_impl]
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error + Send>> {
let err: Box<dyn Error> = self;
<dyn Error>::downcast(err).map_err(|s| unsafe {
// Reapply the `Send` marker.
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
})
}
}
impl dyn Error + Send + Sync {
/// Attempts to downcast the box to a concrete type.
#[inline]
#[stable(feature = "error_downcast", since = "1.3.0")]
#[rustc_allow_incoherent_impl]
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
let err: Box<dyn Error> = self;
<dyn Error>::downcast(err).map_err(|s| unsafe {
// Reapply the `Send + Sync` markers.
mem::transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
})
}
}

View File

@ -0,0 +1,194 @@
use core::async_iter::AsyncIterator;
use core::iter::FusedIterator;
use core::pin::Pin;
use core::slice;
use core::task::{Context, Poll};
use crate::alloc::Allocator;
#[cfg(not(no_global_oom_handling))]
use crate::borrow::Cow;
use crate::boxed::Box;
#[cfg(not(no_global_oom_handling))]
use crate::string::String;
use crate::vec;
#[cfg(not(no_global_oom_handling))]
use crate::vec::Vec;
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator + ?Sized, A: Allocator> Iterator for Box<I, A> {
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
(**self).next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
fn nth(&mut self, n: usize) -> Option<I::Item> {
(**self).nth(n)
}
fn last(self) -> Option<I::Item> {
BoxIter::last(self)
}
}
trait BoxIter {
type Item;
fn last(self) -> Option<Self::Item>;
}
impl<I: Iterator + ?Sized, A: Allocator> BoxIter for Box<I, A> {
type Item = I::Item;
default fn last(self) -> Option<I::Item> {
#[inline]
fn some<T>(_: Option<T>, x: T) -> Option<T> {
Some(x)
}
self.fold(None, some)
}
}
/// Specialization for sized `I`s that uses `I`s implementation of `last()`
/// instead of the default.
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator, A: Allocator> BoxIter for Box<I, A> {
fn last(self) -> Option<I::Item> {
(*self).last()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: DoubleEndedIterator + ?Sized, A: Allocator> DoubleEndedIterator for Box<I, A> {
fn next_back(&mut self) -> Option<I::Item> {
(**self).next_back()
}
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
(**self).nth_back(n)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator + ?Sized, A: Allocator> ExactSizeIterator for Box<I, A> {
fn len(&self) -> usize {
(**self).len()
}
fn is_empty(&self) -> bool {
(**self).is_empty()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl<I: FusedIterator + ?Sized, A: Allocator> FusedIterator for Box<I, A> {}
#[unstable(feature = "async_iterator", issue = "79024")]
impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for Box<S> {
type Item = S::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Pin::new(&mut **self).poll_next(cx)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
/// This implementation is required to make sure that the `Box<[I]>: IntoIterator`
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
impl<I, A: Allocator> !Iterator for Box<[I], A> {}
/// This implementation is required to make sure that the `&Box<[I]>: IntoIterator`
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
impl<'a, I, A: Allocator> !Iterator for &'a Box<[I], A> {}
/// This implementation is required to make sure that the `&mut Box<[I]>: IntoIterator`
/// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket.
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
impl<'a, I, A: Allocator> !Iterator for &'a mut Box<[I], A> {}
// Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator`
// hides this implementation from explicit `.into_iter()` calls on editions < 2024,
// so those calls will still resolve to the slice implementation, by reference.
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
impl<I, A: Allocator> IntoIterator for Box<[I], A> {
type IntoIter = vec::IntoIter<I, A>;
type Item = I;
fn into_iter(self) -> vec::IntoIter<I, A> {
self.into_vec().into_iter()
}
}
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
impl<'a, I, A: Allocator> IntoIterator for &'a Box<[I], A> {
type IntoIter = slice::Iter<'a, I>;
type Item = &'a I;
fn into_iter(self) -> slice::Iter<'a, I> {
self.iter()
}
}
#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")]
impl<'a, I, A: Allocator> IntoIterator for &'a mut Box<[I], A> {
type IntoIter = slice::IterMut<'a, I>;
type Item = &'a mut I;
fn into_iter(self) -> slice::IterMut<'a, I> {
self.iter_mut()
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_slice_from_iter", since = "1.32.0")]
impl<I> FromIterator<I> for Box<[I]> {
fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
iter.into_iter().collect::<Vec<_>>().into_boxed_slice()
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
impl FromIterator<char> for Box<str> {
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
String::from_iter(iter).into_boxed_str()
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
impl<'a> FromIterator<&'a char> for Box<str> {
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
String::from_iter(iter).into_boxed_str()
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
impl<'a> FromIterator<&'a str> for Box<str> {
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
String::from_iter(iter).into_boxed_str()
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
impl FromIterator<String> for Box<str> {
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
String::from_iter(iter).into_boxed_str()
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
impl<A: Allocator> FromIterator<Box<str, A>> for Box<str> {
fn from_iter<T: IntoIterator<Item = Box<str, A>>>(iter: T) -> Self {
String::from_iter(iter).into_boxed_str()
}
}
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "boxed_str_from_iter", since = "1.80.0")]
impl<'a> FromIterator<Cow<'a, str>> for Box<str> {
fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
String::from_iter(iter).into_boxed_str()
}
}

View File

@ -185,7 +185,9 @@
#![feature(cfg_target_has_atomic_equal_alignment)]
#![feature(cfg_ub_checks)]
#![feature(const_for)]
#![feature(const_is_char_boundary)]
#![feature(const_precise_live_drops)]
#![feature(const_str_split_at)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(doc_cfg)]

View File

@ -185,8 +185,9 @@ pub const fn is_empty(&self) -> bool {
/// ```
#[must_use]
#[stable(feature = "is_char_boundary", since = "1.9.0")]
#[rustc_const_unstable(feature = "const_is_char_boundary", issue = "131516")]
#[inline]
pub fn is_char_boundary(&self, index: usize) -> bool {
pub const fn is_char_boundary(&self, index: usize) -> bool {
// 0 is always ok.
// Test for 0 explicitly so that it can optimize out the check
// easily and skip reading string data for that case.
@ -195,8 +196,8 @@ pub fn is_char_boundary(&self, index: usize) -> bool {
return true;
}
match self.as_bytes().get(index) {
// For `None` we have two options:
if index >= self.len() {
// For `true` we have two options:
//
// - index == self.len()
// Empty strings are valid, so return true
@ -205,9 +206,9 @@ pub fn is_char_boundary(&self, index: usize) -> bool {
//
// The check is placed exactly here, because it improves generated
// code on higher opt-levels. See PR #84751 for more details.
None => index == self.len(),
Some(&b) => b.is_utf8_char_boundary(),
index == self.len()
} else {
self.as_bytes()[index].is_utf8_char_boundary()
}
}
@ -637,7 +638,8 @@ pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut s
#[inline]
#[must_use]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at(&self, mid: usize) -> (&str, &str) {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
pub const fn split_at(&self, mid: usize) -> (&str, &str) {
match self.split_at_checked(mid) {
None => slice_error_fail(self, 0, mid),
Some(pair) => pair,
@ -677,7 +679,8 @@ pub fn split_at(&self, mid: usize) -> (&str, &str) {
#[inline]
#[must_use]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
pub const fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary.
@ -716,11 +719,12 @@ pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
#[inline]
#[must_use]
#[stable(feature = "split_at_checked", since = "1.80.0")]
pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary.
Some(unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) })
Some(unsafe { self.split_at_unchecked(mid) })
} else {
None
}
@ -756,7 +760,9 @@ pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
#[inline]
#[must_use]
#[stable(feature = "split_at_checked", since = "1.80.0")]
pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
#[rustc_allow_const_fn_unstable(const_is_char_boundary)]
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary.
@ -772,7 +778,25 @@ pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str
///
/// The caller must ensure that `mid` is a valid byte offset from the start
/// of the string and falls on the boundary of a UTF-8 code point.
unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
let len = self.len();
let ptr = self.as_ptr();
// SAFETY: caller guarantees `mid` is on a char boundary.
unsafe {
(
from_utf8_unchecked(slice::from_raw_parts(ptr, mid)),
from_utf8_unchecked(slice::from_raw_parts(ptr.add(mid), len - mid)),
)
}
}
/// Divides one string slice into two at an index.
///
/// # Safety
///
/// The caller must ensure that `mid` is a valid byte offset from the start
/// of the string and falls on the boundary of a UTF-8 code point.
const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
let len = self.len();
let ptr = self.as_mut_ptr();
// SAFETY: caller guarantees `mid` is on a char boundary.

View File

@ -1197,7 +1197,7 @@ pub fn append(&mut self, append: bool) -> &mut Self {
/// Sets the option for truncating a previous file.
///
/// If a file is successfully opened with this option set it will truncate
/// If a file is successfully opened with this option set to true, it will truncate
/// the file to 0 length if it already exists.
///
/// The file must be opened with write access for truncate to work.

View File

@ -51,7 +51,8 @@ ENV SCRIPT \
/scripts/check-default-config-profiles.sh && \
python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
python3 ../x.py clippy bootstrap -Dwarnings && \
python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \
python3 ../x.py clippy library -Aclippy::all -Dclippy::correctness && \
python3 ../x.py clippy compiler -Aclippy::all -Dclippy::correctness -Dclippy::clone_on_ref_ptr && \
python3 ../x.py build --stage 0 src/tools/build-manifest && \
python3 ../x.py test --stage 0 src/tools/compiletest && \
python3 ../x.py test --stage 0 core alloc std test proc_macro && \

View File

@ -250,7 +250,7 @@ def get_known_directive_names():
os.path.join(
# We go back to `src`.
os.path.dirname(os.path.dirname(__file__)),
"tools/compiletest/src/command-list.rs",
"tools/compiletest/src/directive-list.rs",
),
"r",
encoding="utf8"

View File

@ -709,11 +709,11 @@ fn line_directive<'line>(
Some(DirectiveLine { line_number, revision, raw_directive })
}
// To prevent duplicating the list of commmands between `compiletest`,`htmldocck` and `jsondocck`,
// To prevent duplicating the list of directives between `compiletest`,`htmldocck` and `jsondocck`,
// we put it into a common file which is included in rust code and parsed here.
// FIXME: This setup is temporary until we figure out how to improve this situation.
// See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
include!("command-list.rs");
include!("directive-list.rs");
const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[
"count",

View File

@ -123,7 +123,7 @@ fn print_err(msg: &str, lineno: usize) {
// FIXME: This setup is temporary until we figure out how to improve this situation.
// See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/command-list.rs"));
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/directive-list.rs"));
/// Get a list of commands from a file. Does the work of ensuring the commands
/// are syntactically valid.

View File

@ -23,7 +23,7 @@ note: inside `<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-p
|
LL | match me.resume(()) {
| ^^^^^^^^^^^^^
= note: inside `<std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-pinned-moved.rs:LL:CC}>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC
= note: inside `std::boxed::iter::<impl std::iter::Iterator for std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-pinned-moved.rs:LL:CC}>>>::next` at RUSTLIB/alloc/src/boxed/iter.rs:LL:CC
note: inside `main`
--> tests/fail/coroutine-pinned-moved.rs:LL:CC
|

View File

@ -1,6 +1,9 @@
//@ assembly-output: emit-asm
//@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d
//@ needs-llvm-components: riscv
//@ revisions: LLVM-PRE-20 LLVM-POST-20
//@ [LLVM-PRE-20] ignore-llvm-version: 20 - 99
//@ [LLVM-POST-20] min-llvm-version: 20
#![feature(no_core, lang_items, f16)]
#![crate_type = "lib"]
@ -31,9 +34,11 @@ pub extern "C" fn read_f16(x: &f16) -> f16 {
// CHECK-LABEL: read_f32
#[no_mangle]
pub extern "C" fn read_f32(x: &f32) -> f32 {
// CHECK: flw fa5, 0(a0)
// CHECK-NEXT: fmv.x.w a0, fa5
// CHECK-NEXT: ret
// LLVM-PRE-20: flw fa5, 0(a0)
// LLVM-PRE-20-NEXT: fmv.x.w a0, fa5
// LLVM-PRE-20-NEXT: ret
// LLVM-POST-20: lw a0, 0(a0)
// LLVM-POST-20-NEXT: ret
*x
}

View File

@ -1,109 +0,0 @@
//@ known-bug: #23707
//@ compile-flags: -Copt-level=0 --edition=2021
//@ only-x86_64
#![recursion_limit="2048"]
use std::marker::PhantomData;
use std::fmt;
use std::fmt::Debug;
pub struct Z( () );
pub struct S<T> (PhantomData<T>);
pub trait Nat {
fn sing() -> Self;
fn get(&self) -> usize;
}
impl Nat for Z {
fn sing() -> Z { Z( () ) }
#[inline(always)]
fn get(&self) -> usize {
0
}
}
impl<T : Nat> Nat for S<T> {
fn sing() -> S<T> { S::<T>( PhantomData::<T> ) }
#[inline(always)]
fn get(&self) -> usize {
let prd : T = Nat::sing();
1 + prd.get()
}
}
pub type N0 = Z;
pub type N1 = S<N0>;
pub type N2 = S<N1>;
pub type N3 = S<N2>;
pub type N4 = S<N3>;
pub type N5 = S<N4>;
pub struct Node<D : Nat>(usize,PhantomData<D>);
impl<D:Nat> Node<D> {
pub fn push(&self, c : usize) -> Node<S<D>> {
let Node(i,_) = *self;
Node(10*i+c, PhantomData::<S<D>>)
}
}
impl<D:Nat> Node<S<D>> {
pub fn pop(&self) -> (Node<D>,usize) {
let Node(i,_) = *self;
(Node(i/10, PhantomData::<D>), i-10*(i/10))
}
}
impl<D:Nat> Debug for Node<D> {
fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
let s : D = Nat::sing();
write!(f, "Node<{}>: i= {}",
s.get(), self.0)
}
}
pub trait Step {
fn step(&self, usize) -> Self;
}
impl Step for Node<N0> {
#[inline(always)]
fn step(&self, n : usize) -> Node<N0> {
println!("base case");
Node(n,PhantomData::<N0>)
}
}
impl<D:Nat> Step for Node<S<D>>
where Node<D> : Step {
#[inline(always)]
fn step(&self, n : usize) -> Node<S<D>> {
println!("rec");
let (par,c) = self.pop();
let cnew = c+n;
par.step(c).push(cnew)
}
}
fn tst<D:Nat>(ref p : &Node<D>, c : usize) -> usize
where Node<D> : Step {
let Node(i,_) = p.step(c);
i
}
fn main() {
let nd : Node<N3> = Node(555,PhantomData::<N3>);
// overflow...core::marker::Size
let Node(g,_) = tst(nd,1);
// ok
//let Node(g,_) = nd.step(1);
println!("{:?}", g);
}

View File

@ -0,0 +1,21 @@
// Make sure that, like associated type where clauses on traits, we gather item
// bounds for RPITITs from RTN where clauses.
//@ check-pass
#![feature(return_type_notation)]
trait Foo
where
Self::method(..): Send,
{
fn method() -> impl Sized;
}
fn is_send(_: impl Send) {}
fn test<T: Foo>() {
is_send(T::method());
}
fn main() {}

View File

@ -1,14 +1,15 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
error[E0277]: the trait bound `T: const Tr` is not satisfied
--> $DIR/constifconst-call-in-const-position.rs:17:38
|
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
| ^^^^^^ calling non-const function `<() as Tr>::a`
| ^^^^^^
error[E0277]: the trait bound `T: const Tr` is not satisfied
--> $DIR/constifconst-call-in-const-position.rs:18:9
|
LL | [0; T::a()]
| ^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,8 +1,3 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:26:5: 26:24>::{synthetic#0}`
--> $DIR/unsupported.rs:27:25
|
@ -89,7 +84,7 @@ LL | reuse Trait::foo;
|
= note: cannot satisfy `_: effects::Trait`
error: aborting due to 5 previous errors; 2 warnings emitted
error: aborting due to 4 previous errors; 2 warnings emitted
Some errors have detailed explanations: E0283, E0391.
For more information about an error, try `rustc --explain E0283`.

View File

@ -17,11 +17,6 @@ LL | #![feature(effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
--> $DIR/const_drop_is_valid.rs:6:12
|
@ -39,7 +34,7 @@ LL | impl const Drop for A {}
|
= help: implement the missing item: `fn drop(&mut self) { todo!() }`
error: aborting due to 4 previous errors; 1 warning emitted
error: aborting due to 3 previous errors; 1 warning emitted
Some errors have detailed explanations: E0046, E0658.
For more information about an error, try `rustc --explain E0046`.

View File

@ -1,8 +1,3 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
--> $DIR/safe-intrinsic-mismatch.rs:11:5
|
@ -47,6 +42,6 @@ LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
= note: expected signature `unsafe fn(_, _, _)`
found signature `fn(_, _, _)`
error: aborting due to 7 previous errors
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -7,11 +7,6 @@ LL | #![feature(const_trait_impl, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-bounds-non-const-trait.rs:6:21
|
@ -32,5 +27,5 @@ error: `const` can only be applied to `#[const_trait]` traits
LL | fn operate<T: const NonConst>() {}
| ^^^^^
error: aborting due to 4 previous errors; 1 warning emitted
error: aborting due to 3 previous errors; 1 warning emitted

View File

@ -48,6 +48,30 @@ LL | const fn a<T: ~const Destruct>(_: T) {}
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
--> $DIR/const-drop.rs:67:46
|
LL | impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
| ^^^^^^^^^^^^^^^^^^^^^
|
note: required by a bound in `t::ConstDropWithBound`
--> $DIR/const-drop.rs:65:38
|
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
| ^^^^^ required by this bound in `ConstDropWithBound`
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
--> $DIR/const-drop.rs:68:22
|
LL | fn drop(&mut self) {
| ^^^^
|
note: required by a bound in `t::ConstDropWithBound`
--> $DIR/const-drop.rs:65:38
|
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
| ^^^^^ required by this bound in `ConstDropWithBound`
error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/const-drop.rs:18:32
|
@ -66,7 +90,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
LL + #![feature(effects)]
|
error: aborting due to 8 previous errors
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0015, E0493.
Some errors have detailed explanations: E0015, E0277, E0493.
For more information about an error, try `rustc --explain E0015`.

View File

@ -48,6 +48,30 @@ LL | const fn a<T: ~const Destruct>(_: T) {}
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
--> $DIR/const-drop.rs:67:46
|
LL | impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
| ^^^^^^^^^^^^^^^^^^^^^
|
note: required by a bound in `t::ConstDropWithBound`
--> $DIR/const-drop.rs:65:38
|
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
| ^^^^^ required by this bound in `ConstDropWithBound`
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
--> $DIR/const-drop.rs:68:22
|
LL | fn drop(&mut self) {
| ^^^^
|
note: required by a bound in `t::ConstDropWithBound`
--> $DIR/const-drop.rs:65:38
|
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
| ^^^^^ required by this bound in `ConstDropWithBound`
error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/const-drop.rs:18:32
|
@ -68,7 +92,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
LL + #![feature(effects)]
|
error: aborting due to 8 previous errors
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0015, E0493.
Some errors have detailed explanations: E0015, E0277, E0493.
For more information about an error, try `rustc --explain E0015`.

View File

@ -7,11 +7,6 @@ LL | #![feature(derive_const, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
--> $DIR/derive-const-non-const-type.rs:10:16
|
@ -33,6 +28,6 @@ LL | pub struct S(A);
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors; 1 warning emitted
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0015`.

View File

@ -19,11 +19,6 @@ error[E0635]: unknown feature `const_default_impls`
LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
| ^^^^^^^^^^^^^^^^^^^
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
--> $DIR/derive-const-use.rs:7:12
|
@ -122,7 +117,7 @@ LL | pub struct S((), A);
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 13 previous errors; 1 warning emitted
error: aborting due to 12 previous errors; 1 warning emitted
Some errors have detailed explanations: E0015, E0635.
For more information about an error, try `rustc --explain E0015`.

View File

@ -7,11 +7,6 @@ LL | #![feature(const_trait_impl, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
--> $DIR/derive-const-with-params.rs:7:16
|
@ -43,6 +38,6 @@ LL | a == b
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 5 previous errors; 1 warning emitted
error: aborting due to 4 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0015`.

View File

@ -17,11 +17,6 @@ LL | #![feature(const_trait_impl, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
@ -54,7 +49,7 @@ LL | assert_eq!(first, &b'f');
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 5 previous errors; 1 warning emitted
Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`.

View File

@ -23,4 +23,5 @@ fn main() {
//~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
<() as Bar<false>>::bar();
//~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
//~| ERROR the trait bound `(): const Bar` is not satisfied
};

View File

@ -7,11 +7,6 @@ LL | #![feature(const_trait_impl, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/no-explicit-const-params.rs:22:5
|
@ -40,6 +35,12 @@ note: trait defined here, with 0 generic parameters
LL | trait Bar {
| ^^^
error[E0277]: the trait bound `(): const Bar` is not satisfied
--> $DIR/no-explicit-const-params.rs:24:5
|
LL | <() as Bar<false>>::bar();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/no-explicit-const-params.rs:15:5
|
@ -70,4 +71,5 @@ LL | trait Bar {
error: aborting due to 5 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0107`.
Some errors have detailed explanations: E0107, E0277.
For more information about an error, try `rustc --explain E0107`.

View File

@ -17,11 +17,6 @@ LL | #![feature(effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0308]: mismatched types
--> $DIR/span-bug-issue-121418.rs:9:27
|
@ -44,7 +39,7 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>`
--> $SRC_DIR/std/src/sync/mutex.rs:LL:COL
= note: the return type of a function must have a statically known size
error: aborting due to 4 previous errors; 1 warning emitted
error: aborting due to 3 previous errors; 1 warning emitted
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.

View File

@ -7,11 +7,6 @@ LL | #![feature(effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
--> $DIR/spec-effectvar-ice.rs:11:15
|
@ -60,5 +55,5 @@ error: cannot specialize on trait `Specialize`
LL | impl<T> const Foo for T where T: const Specialize {}
| ^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 5 previous errors; 1 warning emitted

View File

@ -63,11 +63,6 @@ LL | #![feature(const_trait_impl, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: aborting due to 5 previous errors; 1 warning emitted
error: aborting due to 4 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0379`.

View File

@ -1,7 +0,0 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: aborting due to 1 previous error

View File

@ -1,10 +0,0 @@
// test that we error correctly when effects is used without the next-solver flag.
//@ revisions: stock coherence full
//@[coherence] compile-flags: -Znext-solver=coherence
//@[full] compile-flags: -Znext-solver
//@[full] check-pass
#![feature(effects)]
#![allow(incomplete_features)]
fn main() {}

View File

@ -1,7 +0,0 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: aborting due to 1 previous error

View File

@ -1,8 +1,3 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
--> $DIR/ice-119717-constant-lifetime.rs:6:15
|
@ -32,7 +27,7 @@ help: try replacing `_` with the type in the corresponding trait method signatur
LL | fn from_residual(t: T) -> T {
| ~
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0121, E0210.
For more information about an error, try `rustc --explain E0121`.

View File

@ -55,11 +55,6 @@ LL | #![feature(effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0425]: cannot find function `main8` in this scope
--> $DIR/ice-120503-async-const-method.rs:12:9
|
@ -69,7 +64,7 @@ LL | main8().await;
LL | fn main() {}
| --------- similarly named function `main` defined here
error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 5 previous errors; 1 warning emitted
Some errors have detailed explanations: E0379, E0407, E0425.
For more information about an error, try `rustc --explain E0379`.

View File

@ -23,11 +23,6 @@ LL | #![feature(const_trait_impl, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0379`.

View File

@ -1,8 +1,3 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/ice-123664-unexpected-bound-var.rs:4:27
|
@ -17,5 +12,5 @@ LL | const fn with_positive<F: ~const Fn()>() {}
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

View File

@ -1,8 +1,3 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0119]: conflicting implementations of trait `Foo` for type `i32`
--> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1
|
@ -12,6 +7,6 @@ LL |
LL | impl<T> const Foo for T where T: ~const Foo {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0119`.

View File

@ -1,8 +1,3 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
--> $DIR/ice-126148-failed-to-normalize.rs:8:12
|
@ -54,7 +49,7 @@ LL | TryMe?;
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 7 previous errors
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0015, E0046.
For more information about an error, try `rustc --explain E0015`.

View File

@ -1,8 +1,3 @@
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error[E0046]: not all trait items implemented, missing: `req`
--> $DIR/impl-with-default-fn-fail.rs:13:1
|
@ -12,6 +7,6 @@ LL | fn req(&self);
LL | impl const Tr for u16 {
| ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0046`.

View File

@ -7,16 +7,11 @@ LL | #![feature(const_trait_impl, effects)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: cannot specialize on const impl with non-const impl
--> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1
|
LL | impl Value for FortyTwo {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted

View File

@ -7,16 +7,11 @@ LL | #![feature(const_trait_impl, effects, min_specialization, rustc_attrs)]
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
error: cannot specialize on const impl with non-const impl
--> $DIR/specializing-constness.rs:23:1
|
LL | impl<T: Spec + Sup> A for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted

View File

@ -8,6 +8,7 @@
impl<const N: usize> Foo<N> {
fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
//~^ ERROR `~const` is not allowed here
//~| ERROR the trait bound `A: const Add42` is not satisfied
Foo
}
}
@ -25,6 +26,7 @@ fn add(a: usize) -> usize {
fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
//~^ ERROR `~const` is not allowed here
//~| ERROR the trait bound `A: const Add42` is not satisfied
Foo
}

View File

@ -11,21 +11,29 @@ LL | fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
| ^^^
error: `~const` is not allowed here
--> $DIR/tilde-const-and-const-params.rs:26:11
--> $DIR/tilde-const-and-const-params.rs:27:11
|
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
| ^^^^^^
|
note: this function is not `const`, so it cannot have `~const` trait bounds
--> $DIR/tilde-const-and-const-params.rs:26:4
--> $DIR/tilde-const-and-const-params.rs:27:4
|
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
| ^^^
error: using `#![feature(effects)]` without enabling next trait solver globally
error[E0277]: the trait bound `A: const Add42` is not satisfied
--> $DIR/tilde-const-and-const-params.rs:27:61
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
= help: use `-Znext-solver` to enable
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
| ^^^^^^^^^
error: aborting due to 3 previous errors
error[E0277]: the trait bound `A: const Add42` is not satisfied
--> $DIR/tilde-const-and-const-params.rs:9:44
|
LL | fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
| ^^^^^^^^^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -725,9 +725,6 @@ please modify the tool then regenerate the library source file with the tool
instead of editing the library source file manually.
"""
[mentions."src/librustdoc/clean/types.rs"]
cc = ["@camelid"]
[mentions."src/librustdoc/html/static"]
message = "Some changes occurred in HTML/CSS/JS."
cc = [
@ -938,9 +935,6 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
[mentions."tests/ui/stack-protector"]
cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
[mentions."tests/ui/check-cfg"]
cc = ["@Urgau"]
[mentions."compiler/rustc_middle/src/mir/coverage.rs"]
message = "Some changes occurred in coverage instrumentation."
cc = ["@Zalathar"]