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 = [ dependencies = [
"itertools", "itertools",
"rustc_ast", "rustc_ast",
"rustc_data_structures",
"rustc_lexer", "rustc_lexer",
"rustc_span", "rustc_span",
"thin-vec", "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 // a copy. This is faster than the `derive(Clone)` version which has a
// separate path for every variant. // separate path for every variant.
match self { match self {
Interpolated(nt) => Interpolated(nt.clone()), Interpolated(nt) => Interpolated(Lrc::clone(nt)),
_ => unsafe { std::ptr::read(self) }, _ => unsafe { std::ptr::read(self) },
} }
} }

View File

@ -3,6 +3,7 @@
use rustc_ast::ptr::P as AstP; use rustc_ast::ptr::P as AstP;
use rustc_ast::*; use rustc_ast::*;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_hir::def::{DefKind, Res}; 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) => { ExprKind::IncludedBytes(bytes) => {
let lit = self.arena.alloc(respan( let lit = self.arena.alloc(respan(
self.lower_span(e.span), self.lower_span(e.span),
LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), LitKind::ByteStr(Lrc::clone(bytes), StrStyle::Cooked),
)); ));
hir::ExprKind::Lit(lit) 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( this.mark_span_with_reason(
DesugaringKind::TryBlock, DesugaringKind::TryBlock,
expr.span, expr.span,
Some(this.allow_try_trait.clone()), Some(Lrc::clone(&this.allow_try_trait)),
), ),
expr, 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( let try_span = this.mark_span_with_reason(
DesugaringKind::TryBlock, DesugaringKind::TryBlock,
this.tcx.sess.source_map().end_point(body.span), 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)) (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( let unstable_span = self.mark_span_with_reason(
DesugaringKind::Async, DesugaringKind::Async,
self.lower_span(span), self.lower_span(span),
Some(self.allow_gen_future.clone()), Some(Lrc::clone(&self.allow_gen_future)),
); );
let resume_ty = let resume_ty =
self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None); 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( let unstable_span = self.mark_span_with_reason(
DesugaringKind::Async, DesugaringKind::Async,
span, span,
Some(self.allow_gen_future.clone()), Some(Lrc::clone(&self.allow_gen_future)),
); );
self.lower_attrs(inner_hir_id, &[Attribute { self.lower_attrs(inner_hir_id, &[Attribute {
kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new( kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
@ -815,13 +816,13 @@ fn make_lowered_await(
let features = match await_kind { let features = match await_kind {
FutureKind::Future => None, 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 span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, features);
let gen_future_span = self.mark_span_with_reason( let gen_future_span = self.mark_span_with_reason(
DesugaringKind::Await, DesugaringKind::Await,
full_span, full_span,
Some(self.allow_gen_future.clone()), Some(Lrc::clone(&self.allow_gen_future)),
); );
let expr_hir_id = expr.hir_id; 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( let unstable_span = self.mark_span_with_reason(
DesugaringKind::QuestionMark, DesugaringKind::QuestionMark,
span, 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.tcx.sess.source_map().end_point(span);
let try_span = self.mark_span_with_reason( let try_span = self.mark_span_with_reason(
DesugaringKind::QuestionMark, DesugaringKind::QuestionMark,
try_span, try_span,
Some(self.allow_try_trait.clone()), Some(Lrc::clone(&self.allow_try_trait)),
); );
// `Try::branch(<expr>)` // `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( let unstable_span = self.mark_span_with_reason(
DesugaringKind::YeetExpr, DesugaringKind::YeetExpr,
span, span,
Some(self.allow_try_trait.clone()), Some(Lrc::clone(&self.allow_try_trait)),
); );
let from_yeet_expr = self.wrap_in_try_constructor( 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::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
CoroutineKind::Gen { 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, .. } => { 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 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() && 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 { } else {
None None
}; };

View File

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

View File

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

View File

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

View File

@ -733,7 +733,7 @@ fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex) {
} }
// Now take member constraints into account. // 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) { 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)); 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>, infcx: &InferCtxt<'tcx>,
errors_buffer: &mut RegionErrors<'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() { for m_c_i in member_constraints.all_indices() {
debug!(?m_c_i); debug!(?m_c_i);
let m_c = &member_constraints[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 { let mut constraints = MirTypeckRegionConstraints {
placeholder_indices: PlaceholderIndices::default(), placeholder_indices: PlaceholderIndices::default(),
placeholder_index_to_region: IndexVec::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(), outlives_constraints: OutlivesConstraintSet::default(),
member_constraints: MemberConstraintSet::default(), member_constraints: MemberConstraintSet::default(),
type_tests: Vec::default(), type_tests: Vec::default(),
@ -150,7 +150,7 @@ pub(crate) fn type_check<'a, 'tcx>(
infcx, infcx,
param_env, param_env,
implicit_region_bound, implicit_region_bound,
universal_regions.clone(), Rc::clone(&universal_regions),
&mut constraints, &mut constraints,
); );

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
use rustc_attr as attr; use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; 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_data_structures::unord::UnordMap;
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem; 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), crate_name: UnordMap::with_capacity(n_crates),
used_crates, used_crates,
used_crate_source: UnordMap::with_capacity(n_crates), used_crate_source: UnordMap::with_capacity(n_crates),
dependency_formats: tcx.dependency_formats(()).clone(), dependency_formats: Lrc::clone(tcx.dependency_formats(())),
windows_subsystem, windows_subsystem,
natvis_debugger_visualizers: Default::default(), 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)); info.crate_name.insert(cnum, tcx.crate_name(cnum));
let used_crate_source = tcx.used_crate_source(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) { if tcx.is_profiler_runtime(cnum) {
info.profiler_runtime = Some(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 = 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( panic::update_hook(Box::new(
move |default_hook: &(dyn Fn(&PanicHookInfo<'_>) + Send + Sync + 'static), move |default_hook: &(dyn Fn(&PanicHookInfo<'_>) + Send + Sync + 'static),
info: &PanicHookInfo<'_>| { info: &PanicHookInfo<'_>| {

View File

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

View File

@ -1555,7 +1555,7 @@ fn emit_messages_default_inner(
// Get the left-side margin to remove it // Get the left-side margin to remove it
let mut whitespace_margin = usize::MAX; let mut whitespace_margin = usize::MAX;
for line_idx in 0..annotated_file.lines.len() { 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]; let line = &annotated_file.lines[line_idx];
if let Some(source_string) = if let Some(source_string) =
line.line_index.checked_sub(1).and_then(|l| file.get_line(l)) 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( let depths = self.render_source_line(
&mut buffer, &mut buffer,
annotated_file.file.clone(), Lrc::clone(&annotated_file.file),
&annotated_file.lines[line_idx], &annotated_file.lines[line_idx],
width_offset, width_offset,
code_offset, code_offset,
@ -2529,7 +2529,12 @@ fn add_annotation_to_file(
// | | | // | | |
// | |______foo // | |______foo
// | baz // | 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 // 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 // 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 // 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); .unwrap_or(ann.line_start);
for line in ann.line_start + 1..until { for line in ann.line_start + 1..until {
// Every `|` that joins the beginning of the span (`___^`) to the end (`|__^`). // 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; let line_end = ann.line_end - 1;
if middle < line_end { 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 { } else {
end_ann.annotation_type = AnnotationType::Singleline; 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::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)),
ColorConfig::Never => {} ColorConfig::Never => {}
} }
HumanEmitter::new(dst, je.fallback_bundle.clone()) HumanEmitter::new(dst, Lrc::clone(&je.fallback_bundle))
.short_message(short) .short_message(short)
.sm(Some(je.sm.clone())) .sm(Some(Lrc::clone(&je.sm)))
.fluent_bundle(je.fluent_bundle.clone()) .fluent_bundle(je.fluent_bundle.clone())
.diagnostic_width(je.diagnostic_width) .diagnostic_width(je.diagnostic_width)
.macro_backtrace(je.macro_backtrace) .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 // possible next positions into `next_mps`. After some post-processing, the contents of
// `next_mps` replenish `cur_mps` and we start over again. // `next_mps` replenish `cur_mps` and we start over again.
self.cur_mps.clear(); 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 { loop {
self.next_mps.clear(); 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::token::{self, Delimiter, IdentIsRaw, Lit, LitKind, Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize}; use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
use rustc_parse::lexer::nfc_normalize; use rustc_parse::lexer::nfc_normalize;
use rustc_parse::parser::ParseNtResult; use rustc_parse::parser::ParseNtResult;
@ -293,7 +294,7 @@ pub(super) fn transcribe<'a>(
// `Delimiter::Invisible` to maintain parsing priorities. // `Delimiter::Invisible` to maintain parsing priorities.
// `Interpolated` is currently used for such groups in rustc parser. // `Interpolated` is currently used for such groups in rustc parser.
marker.visit_span(&mut sp); marker.visit_span(&mut sp);
TokenTree::token_alone(token::Interpolated(nt.clone()), sp) TokenTree::token_alone(token::Interpolated(Lrc::clone(nt)), sp)
} }
MatchedSeq(..) => { MatchedSeq(..) => {
// We were unable to descend far enough. This is an error. // 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 hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice
.label = parameter captured again here .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 hir_analysis_empty_specialization = specialization impl does not specialize any associated items
.note = impl is a specialization of this impl .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. // a projection self type.
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { 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 opaque_ty = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_opaque_ty();
let item_ty = Ty::new_projection_from_args( let bounds =
tcx, associated_type_bounds(tcx, def_id, opaque_ty.bounds, opaque_ty.span, filter);
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);
return ty::EarlyBinder::bind(bounds); return ty::EarlyBinder::bind(bounds);
} }
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!( Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(

View File

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

View File

@ -153,12 +153,6 @@ pub fn provide(providers: &mut Providers) {
pub fn check_crate(tcx: TyCtxt<'_>) { pub fn check_crate(tcx: TyCtxt<'_>) {
let _prof_timer = tcx.sess.timer("type_check_crate"); 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.sess.time("coherence_checking", || {
tcx.hir().par_for_each_module(|module| { tcx.hir().par_for_each_module(|module| {
let _ = tcx.ensure().check_mod_type_wf(module); let _ = tcx.ensure().check_mod_type_wf(module);

View File

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

View File

@ -142,7 +142,7 @@ pub fn codegen_and_build_linker(
Ok(Linker { Ok(Linker {
dep_graph: tcx.dep_graph.clone(), 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() { crate_hash: if tcx.needs_crate_hash() {
Some(tcx.crate_hash(LOCAL_CRATE)) Some(tcx.crate_hash(LOCAL_CRATE))
} else { } else {

View File

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

View File

@ -1231,7 +1231,7 @@ extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
return dwarf::DW_OP_plus_uconst; return dwarf::DW_OP_plus_uconst;
} }
extern "C" int64_t LLVMRustDIBuilderCreateOpLLVMFragment() { extern "C" uint64_t LLVMRustDIBuilderCreateOpLLVMFragment() {
return dwarf::DW_OP_LLVM_fragment; 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_map = s.tcx.sess.source_map();
let source_file_index = source_map.lookup_source_file_idx(self.lo); let source_file_index = source_map.lookup_source_file_idx(self.lo);
s.source_file_cache = 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; let (ref source_file, source_file_index) = s.source_file_cache;
debug_assert!(source_file.contains(self.lo)); 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()); encoder.emit_raw_bytes(&0u64.to_le_bytes());
let source_map_files = tcx.sess.source_map().files(); 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()); let required_source_files = Some(FxIndexSet::default());
drop(source_map_files); 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 { pub fn path_erased(&self) -> Self {
DebuggerVisualizerFile { DebuggerVisualizerFile {
src: self.src.clone(), src: Lrc::clone(&self.src),
visualizer_type: self.visualizer_type, visualizer_type: self.visualizer_type,
path: None, 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, .. } = let CacheDecoder { tcx, file_index_to_file, file_index_to_stable_id, source_map, .. } =
*self; *self;
file_index_to_file Lrc::clone(file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
.borrow_mut()
.entry(index)
.or_insert_with(|| {
let source_file_id = &file_index_to_stable_id[&index]; let source_file_id = &file_index_to_stable_id[&index];
let source_file_cnum = let source_file_cnum = tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
// If this `SourceFile` is from a foreign crate, then make sure // If this `SourceFile` is from a foreign crate, then make sure
// that we've imported all of the source files from that crate. // 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_map
.source_file_by_stable_id(source_file_id.stable_source_file_id) .source_file_by_stable_id(source_file_id.stable_source_file_id)
.expect("failed to lookup `SourceFile` in new context") .expect("failed to lookup `SourceFile` in new context")
}) }))
.clone()
} }
} }

View File

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

View File

@ -134,7 +134,7 @@ pub fn new(
encoder, encoder,
record_graph, record_graph,
record_stats, record_stats,
prev_graph.clone(), Arc::clone(&prev_graph),
); );
let colors = DepNodeColorMap::new(prev_graph_node_count); 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. // 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 // Both of these will remove it from the `waiters` list before resuming
// this thread. // 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 // 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 // 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> { fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> {
match macro_kind { match macro_kind {
MacroKind::Bang => self.dummy_ext_bang.clone(), MacroKind::Bang => Lrc::clone(&self.dummy_ext_bang),
MacroKind::Derive => self.dummy_ext_derive.clone(), MacroKind::Derive => Lrc::clone(&self.dummy_ext_derive),
MacroKind::Attr => self.non_macro_attr.ext.clone(), MacroKind::Attr => Lrc::clone(&self.non_macro_attr.ext),
} }
} }

View File

@ -826,7 +826,7 @@ fn resolve_macro_or_delegation_path(
} }
_ => None, _ => 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)) 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 sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let emitter = Box::new( let emitter = Box::new(
HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle) HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle)
.sm(Some(sm.clone())), .sm(Some(Lrc::clone(&sm))),
); );
let dcx = DiagCtxt::new(emitter); let dcx = DiagCtxt::new(emitter);
ParseSess::with_dcx(dcx, sm) ParseSess::with_dcx(dcx, sm)
@ -278,7 +278,7 @@ pub fn with_silent_emitter(
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let emitter = Box::new(HumanEmitter::new( let emitter = Box::new(HumanEmitter::new(
stderr_destination(ColorConfig::Auto), stderr_destination(ColorConfig::Auto),
fallback_bundle.clone(), Lrc::clone(&fallback_bundle),
)); ));
let fatal_dcx = DiagCtxt::new(emitter); let fatal_dcx = DiagCtxt::new(emitter);
let dcx = DiagCtxt::new(Box::new(SilentEmitter { 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> { pub fn clone_source_map(&self) -> Lrc<SourceMap> {
self.source_map.clone() Lrc::clone(&self.source_map)
} }
pub fn buffer_lint( pub fn buffer_lint(

View File

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

View File

@ -63,7 +63,7 @@ pub struct CachingSourceMapView<'sm> {
impl<'sm> CachingSourceMapView<'sm> { impl<'sm> CachingSourceMapView<'sm> {
pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> { pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> {
let files = source_map.files(); let files = source_map.files();
let first_file = files[0].clone(); let first_file = Lrc::clone(&files[0]);
let entry = CacheEntry { let entry = CacheEntry {
time_stamp: 0, time_stamp: 0,
line_number: 0, line_number: 0,
@ -92,7 +92,7 @@ pub fn byte_pos_to_line_and_col(
cache_entry.touch(self.time_stamp); cache_entry.touch(self.time_stamp);
let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32()); 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 ... // 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); cache_entry.update(new_file_and_idx, pos, self.time_stamp);
let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32()); 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( 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, lo.line_number,
span_data.lo - lo.line.start, span_data.lo - lo.line.start,
hi.line_number, 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); lo.update(new_file_and_idx, span_data.lo, self.time_stamp);
if !lo.line.contains(&span_data.hi) { 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 next_oldest = self.oldest_cache_entry_index_avoid(oldest);
let hi = &mut self.line_cache[next_oldest]; let hi = &mut self.line_cache[next_oldest];
hi.update(new_file_and_idx, span_data.hi, self.time_stamp); 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); assert_eq!(lo.file_index, hi.file_index);
Some(( Some((
lo.file.clone(), Lrc::clone(&lo.file),
lo.line_number, lo.line_number,
span_data.lo - lo.line.start, span_data.lo - lo.line.start,
hi.line_number, 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]; let file = &self.source_map.files()[file_idx];
if file_contains(file, pos) { 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); let file = Lrc::new(file);
files.source_files.push(file.clone()); files.source_files.push(Lrc::clone(&file));
files.stable_id_to_source_file.insert(file_id, file.clone()); files.stable_id_to_source_file.insert(file_id, Lrc::clone(&file));
Ok(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` /// Return the SourceFile that contains the given `BytePos`
pub fn lookup_source_file(&self, pos: BytePos) -> Lrc<SourceFile> { pub fn lookup_source_file(&self, pos: BytePos) -> Lrc<SourceFile> {
let idx = self.lookup_source_file_idx(pos); 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`. /// Looks up source information about a `BytePos`.
@ -468,7 +468,7 @@ pub fn is_multiline(&self, sp: Span) -> bool {
if lo != hi { if lo != hi {
return true; 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 lo = f.relative_position(sp.lo());
let hi = f.relative_position(sp.hi()); let hi = f.relative_position(sp.hi());
f.lookup_line(lo) != f.lookup_line(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; let filename = self.path_mapping().map_filename_prefix(filename).0;
for sf in self.files.borrow().source_files.iter() { for sf in self.files.borrow().source_files.iter() {
if filename == sf.name { if filename == sf.name {
return Some(sf.clone()); return Some(Lrc::clone(&sf));
} }
} }
None 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`. /// For a global `BytePos`, computes the local offset within the containing `SourceFile`.
pub fn lookup_byte_offset(&self, bpos: BytePos) -> SourceFileAndBytePos { pub fn lookup_byte_offset(&self, bpos: BytePos) -> SourceFileAndBytePos {
let idx = self.lookup_source_file_idx(bpos); 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; let offset = bpos - sf.start_pos;
SourceFileAndBytePos { sf, pos: offset } 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 thin_vec::ThinVec;
use tracing::{debug, debug_span, instrument}; use tracing::{debug, debug_span, instrument};
use super::effects::{self, HostEffectObligation};
use super::project::{self, ProjectAndUnifyResult}; use super::project::{self, ProjectAndUnifyResult};
use super::select::SelectionContext; use super::select::SelectionContext;
use super::{ use super::{
@ -402,8 +403,13 @@ fn process_obligation(
) )
} }
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
ProcessResult::Changed(Default::default()) 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)) => { 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`. /// Returns the set of inference variables contained in `args`.

View File

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

View File

@ -49,7 +49,7 @@
use crate::solve::InferCtxtSelectExt as _; use crate::solve::InferCtxtSelectExt as _;
use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt}; use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt};
use crate::traits::{ProjectionCacheKey, Unimplemented}; use crate::traits::{ProjectionCacheKey, Unimplemented, effects};
mod _match; mod _match;
mod candidate_assembly; mod candidate_assembly;
@ -645,11 +645,19 @@ fn evaluate_predicate_recursively<'o>(
self.evaluate_trait_predicate_recursively(previous_stack, obligation) self.evaluate_trait_predicate_recursively(previous_stack, obligation)
} }
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => { ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
// FIXME(effects): It should be relatively straightforward to implement self.infcx.enter_forall(bound_predicate.rebind(data), |data| {
// old trait solver support for `HostEffect` bounds; or at least basic match effects::evaluate_host_effect_obligation(
// support for them. self,
todo!() &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) => { 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_target_has_atomic_equal_alignment)]
#![feature(cfg_ub_checks)] #![feature(cfg_ub_checks)]
#![feature(const_for)] #![feature(const_for)]
#![feature(const_is_char_boundary)]
#![feature(const_precise_live_drops)] #![feature(const_precise_live_drops)]
#![feature(const_str_split_at)]
#![feature(decl_macro)] #![feature(decl_macro)]
#![feature(deprecated_suggestion)] #![feature(deprecated_suggestion)]
#![feature(doc_cfg)] #![feature(doc_cfg)]

View File

@ -185,8 +185,9 @@ pub const fn is_empty(&self) -> bool {
/// ``` /// ```
#[must_use] #[must_use]
#[stable(feature = "is_char_boundary", since = "1.9.0")] #[stable(feature = "is_char_boundary", since = "1.9.0")]
#[rustc_const_unstable(feature = "const_is_char_boundary", issue = "131516")]
#[inline] #[inline]
pub fn is_char_boundary(&self, index: usize) -> bool { pub const fn is_char_boundary(&self, index: usize) -> bool {
// 0 is always ok. // 0 is always ok.
// Test for 0 explicitly so that it can optimize out the check // Test for 0 explicitly so that it can optimize out the check
// easily and skip reading string data for that case. // easily and skip reading string data for that case.
@ -195,8 +196,8 @@ pub fn is_char_boundary(&self, index: usize) -> bool {
return true; return true;
} }
match self.as_bytes().get(index) { if index >= self.len() {
// For `None` we have two options: // For `true` we have two options:
// //
// - index == self.len() // - index == self.len()
// Empty strings are valid, so return true // 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 // The check is placed exactly here, because it improves generated
// code on higher opt-levels. See PR #84751 for more details. // code on higher opt-levels. See PR #84751 for more details.
None => index == self.len(), index == self.len()
} else {
Some(&b) => b.is_utf8_char_boundary(), 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] #[inline]
#[must_use] #[must_use]
#[stable(feature = "str_split_at", since = "1.4.0")] #[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) { match self.split_at_checked(mid) {
None => slice_error_fail(self, 0, mid), None => slice_error_fail(self, 0, mid),
Some(pair) => pair, Some(pair) => pair,
@ -677,7 +679,8 @@ pub fn split_at(&self, mid: usize) -> (&str, &str) {
#[inline] #[inline]
#[must_use] #[must_use]
#[stable(feature = "str_split_at", since = "1.4.0")] #[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()] // is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) { if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary. // 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] #[inline]
#[must_use] #[must_use]
#[stable(feature = "split_at_checked", since = "1.80.0")] #[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()] // is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) { if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary. // 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 { } else {
None None
} }
@ -756,7 +760,9 @@ pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
#[inline] #[inline]
#[must_use] #[must_use]
#[stable(feature = "split_at_checked", since = "1.80.0")] #[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()] // is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) { if self.is_char_boundary(mid) {
// SAFETY: just checked that `mid` is on a char boundary. // 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 /// 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. /// 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 len = self.len();
let ptr = self.as_mut_ptr(); let ptr = self.as_mut_ptr();
// SAFETY: caller guarantees `mid` is on a char boundary. // 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. /// 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 to 0 length if it already exists.
/// ///
/// The file must be opened with write access for truncate to work. /// 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 && \ /scripts/check-default-config-profiles.sh && \
python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
python3 ../x.py clippy bootstrap -Dwarnings && \ 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 build --stage 0 src/tools/build-manifest && \
python3 ../x.py test --stage 0 src/tools/compiletest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \
python3 ../x.py test --stage 0 core alloc std test proc_macro && \ 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( os.path.join(
# We go back to `src`. # We go back to `src`.
os.path.dirname(os.path.dirname(__file__)), os.path.dirname(os.path.dirname(__file__)),
"tools/compiletest/src/command-list.rs", "tools/compiletest/src/directive-list.rs",
), ),
"r", "r",
encoding="utf8" encoding="utf8"

View File

@ -709,11 +709,11 @@ fn line_directive<'line>(
Some(DirectiveLine { line_number, revision, raw_directive }) 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. // 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. // 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>. // 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] = &[ const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[
"count", "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. // 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>. // 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 /// Get a list of commands from a file. Does the work of ensuring the commands
/// are syntactically valid. /// are syntactically valid.

View File

@ -23,7 +23,7 @@ note: inside `<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-p
| |
LL | match me.resume(()) { 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` note: inside `main`
--> tests/fail/coroutine-pinned-moved.rs:LL:CC --> tests/fail/coroutine-pinned-moved.rs:LL:CC
| |

View File

@ -1,6 +1,9 @@
//@ assembly-output: emit-asm //@ assembly-output: emit-asm
//@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d //@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d
//@ needs-llvm-components: riscv //@ 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)] #![feature(no_core, lang_items, f16)]
#![crate_type = "lib"] #![crate_type = "lib"]
@ -31,9 +34,11 @@ pub extern "C" fn read_f16(x: &f16) -> f16 {
// CHECK-LABEL: read_f32 // CHECK-LABEL: read_f32
#[no_mangle] #[no_mangle]
pub extern "C" fn read_f32(x: &f32) -> f32 { pub extern "C" fn read_f32(x: &f32) -> f32 {
// CHECK: flw fa5, 0(a0) // LLVM-PRE-20: flw fa5, 0(a0)
// CHECK-NEXT: fmv.x.w a0, fa5 // LLVM-PRE-20-NEXT: fmv.x.w a0, fa5
// CHECK-NEXT: ret // LLVM-PRE-20-NEXT: ret
// LLVM-POST-20: lw a0, 0(a0)
// LLVM-POST-20-NEXT: ret
*x *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 error[E0277]: the trait bound `T: const Tr` is not satisfied
|
= 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
--> $DIR/constifconst-call-in-const-position.rs:17:38 --> $DIR/constifconst-call-in-const-position.rs:17:38
| |
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] { 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 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}` 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 --> $DIR/unsupported.rs:27:25
| |
@ -89,7 +84,7 @@ LL | reuse Trait::foo;
| |
= note: cannot satisfy `_: effects::Trait` = 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. Some errors have detailed explanations: E0283, E0391.
For more information about an error, try `rustc --explain E0283`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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]` error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
--> $DIR/const_drop_is_valid.rs:6:12 --> $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!() }` = 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. Some errors have detailed explanations: E0046, E0658.
For more information about an error, try `rustc --explain E0046`. 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` 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 --> $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(_, _, _)` = note: expected signature `unsafe fn(_, _, _)`
found signature `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`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const-bounds-non-const-trait.rs:6:21 --> $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>() {} 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` = 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 error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/const-drop.rs:18:32 --> $DIR/const-drop.rs:18:32
| |
@ -66,7 +90,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
LL + #![feature(effects)] 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`. 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` = 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 error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/const-drop.rs:18:32 --> $DIR/const-drop.rs:18:32
| |
@ -68,7 +92,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
LL + #![feature(effects)] 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`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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]` error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
--> $DIR/derive-const-non-const-type.rs:10:16 --> $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: 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) = 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`. 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)] 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]` error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
--> $DIR/derive-const-use.rs:7:12 --> $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: 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) = 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. Some errors have detailed explanations: E0015, E0635.
For more information about an error, try `rustc --explain E0015`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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]` error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
--> $DIR/derive-const-with-params.rs:7:16 --> $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 = 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`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/ice-112822-expected-type-for-param.rs:3:25 --> $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: 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) = 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. Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`. 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 //~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
<() as Bar<false>>::bar(); <() as Bar<false>>::bar();
//~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied //~^ 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/no-explicit-const-params.rs:22:5 --> $DIR/no-explicit-const-params.rs:22:5
| |
@ -40,6 +35,12 @@ note: trait defined here, with 0 generic parameters
LL | trait Bar { 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 error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/no-explicit-const-params.rs:15:5 --> $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 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 error[E0308]: mismatched types
--> $DIR/span-bug-issue-121418.rs:9:27 --> $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 --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL
= note: the return type of a function must have a statically known size = 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. Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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]` error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
--> $DIR/spec-effectvar-ice.rs:11:15 --> $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 {} 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally error: aborting due to 4 previous errors; 1 warning emitted
|
= 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
For more information about this error, try `rustc --explain E0379`. 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]` error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
--> $DIR/ice-119717-constant-lifetime.rs:6:15 --> $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 { 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. Some errors have detailed explanations: E0121, E0210.
For more information about an error, try `rustc --explain E0121`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 error[E0425]: cannot find function `main8` in this scope
--> $DIR/ice-120503-async-const-method.rs:12:9 --> $DIR/ice-120503-async-const-method.rs:12:9
| |
@ -69,7 +64,7 @@ LL | main8().await;
LL | fn main() {} LL | fn main() {}
| --------- similarly named function `main` defined here | --------- 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. Some errors have detailed explanations: E0379, E0407, E0425.
For more information about an error, try `rustc --explain E0379`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error: using `#![feature(effects)]` without enabling next trait solver globally error: aborting due to 1 previous error; 1 warning emitted
|
= 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
For more information about this error, try `rustc --explain E0379`. 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 error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/ice-123664-unexpected-bound-var.rs:4:27 --> $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` = 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` error[E0119]: conflicting implementations of trait `Foo` for type `i32`
--> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1 --> $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 {} LL | impl<T> const Foo for T where T: ~const Foo {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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`. 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]` error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
--> $DIR/ice-126148-failed-to-normalize.rs:8:12 --> $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 = 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. Some errors have detailed explanations: E0015, E0046.
For more information about an error, try `rustc --explain E0015`. 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` error[E0046]: not all trait items implemented, missing: `req`
--> $DIR/impl-with-default-fn-fail.rs:13:1 --> $DIR/impl-with-default-fn-fail.rs:13:1
| |
@ -12,6 +7,6 @@ LL | fn req(&self);
LL | impl const Tr for u16 { LL | impl const Tr for u16 {
| ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation | ^^^^^^^^^^^^^^^^^^^^^ 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`. 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 error: cannot specialize on const impl with non-const impl
--> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1 --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1
| |
LL | impl Value for FortyTwo { 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: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 error: cannot specialize on const impl with non-const impl
--> $DIR/specializing-constness.rs:23:1 --> $DIR/specializing-constness.rs:23:1
| |
LL | impl<T: Spec + Sup> A for T { 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> { impl<const N: usize> Foo<N> {
fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> { fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
//~^ ERROR `~const` is not allowed here //~^ ERROR `~const` is not allowed here
//~| ERROR the trait bound `A: const Add42` is not satisfied
Foo Foo
} }
} }
@ -25,6 +26,7 @@ fn add(a: usize) -> usize {
fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> { fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
//~^ ERROR `~const` is not allowed here //~^ ERROR `~const` is not allowed here
//~| ERROR the trait bound `A: const Add42` is not satisfied
Foo Foo
} }

View File

@ -11,21 +11,29 @@ LL | fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
| ^^^ | ^^^
error: `~const` is not allowed here 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) }> { 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 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) }> { 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 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
= help: use `-Znext-solver` to enable | ^^^^^^^^^
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. instead of editing the library source file manually.
""" """
[mentions."src/librustdoc/clean/types.rs"]
cc = ["@camelid"]
[mentions."src/librustdoc/html/static"] [mentions."src/librustdoc/html/static"]
message = "Some changes occurred in HTML/CSS/JS." message = "Some changes occurred in HTML/CSS/JS."
cc = [ cc = [
@ -938,9 +935,6 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
[mentions."tests/ui/stack-protector"] [mentions."tests/ui/stack-protector"]
cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
[mentions."tests/ui/check-cfg"]
cc = ["@Urgau"]
[mentions."compiler/rustc_middle/src/mir/coverage.rs"] [mentions."compiler/rustc_middle/src/mir/coverage.rs"]
message = "Some changes occurred in coverage instrumentation." message = "Some changes occurred in coverage instrumentation."
cc = ["@Zalathar"] cc = ["@Zalathar"]