mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
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:
commit
2dece5bb62
@ -3301,6 +3301,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_lexer",
|
||||
"rustc_span",
|
||||
"thin-vec",
|
||||
|
@ -368,7 +368,7 @@ impl Clone for TokenKind {
|
||||
// a copy. This is faster than the `derive(Clone)` version which has a
|
||||
// separate path for every variant.
|
||||
match self {
|
||||
Interpolated(nt) => Interpolated(nt.clone()),
|
||||
Interpolated(nt) => Interpolated(Lrc::clone(nt)),
|
||||
_ => unsafe { std::ptr::read(self) },
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use std::assert_matches::assert_matches;
|
||||
use rustc_ast::ptr::P as AstP;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::HirId;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
@ -143,7 +144,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ExprKind::IncludedBytes(bytes) => {
|
||||
let lit = self.arena.alloc(respan(
|
||||
self.lower_span(e.span),
|
||||
LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
|
||||
LitKind::ByteStr(Lrc::clone(bytes), StrStyle::Cooked),
|
||||
));
|
||||
hir::ExprKind::Lit(lit)
|
||||
}
|
||||
@ -536,7 +537,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
this.mark_span_with_reason(
|
||||
DesugaringKind::TryBlock,
|
||||
expr.span,
|
||||
Some(this.allow_try_trait.clone()),
|
||||
Some(Lrc::clone(&this.allow_try_trait)),
|
||||
),
|
||||
expr,
|
||||
)
|
||||
@ -544,7 +545,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let try_span = this.mark_span_with_reason(
|
||||
DesugaringKind::TryBlock,
|
||||
this.tcx.sess.source_map().end_point(body.span),
|
||||
Some(this.allow_try_trait.clone()),
|
||||
Some(Lrc::clone(&this.allow_try_trait)),
|
||||
);
|
||||
|
||||
(try_span, this.expr_unit(try_span))
|
||||
@ -653,7 +654,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let unstable_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Async,
|
||||
self.lower_span(span),
|
||||
Some(self.allow_gen_future.clone()),
|
||||
Some(Lrc::clone(&self.allow_gen_future)),
|
||||
);
|
||||
let resume_ty =
|
||||
self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None);
|
||||
@ -739,7 +740,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let unstable_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Async,
|
||||
span,
|
||||
Some(self.allow_gen_future.clone()),
|
||||
Some(Lrc::clone(&self.allow_gen_future)),
|
||||
);
|
||||
self.lower_attrs(inner_hir_id, &[Attribute {
|
||||
kind: AttrKind::Normal(ptr::P(NormalAttr::from_ident(Ident::new(
|
||||
@ -815,13 +816,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
let features = match await_kind {
|
||||
FutureKind::Future => None,
|
||||
FutureKind::AsyncIterator => Some(self.allow_for_await.clone()),
|
||||
FutureKind::AsyncIterator => Some(Lrc::clone(&self.allow_for_await)),
|
||||
};
|
||||
let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, features);
|
||||
let gen_future_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Await,
|
||||
full_span,
|
||||
Some(self.allow_gen_future.clone()),
|
||||
Some(Lrc::clone(&self.allow_gen_future)),
|
||||
);
|
||||
let expr_hir_id = expr.hir_id;
|
||||
|
||||
@ -1841,13 +1842,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let unstable_span = self.mark_span_with_reason(
|
||||
DesugaringKind::QuestionMark,
|
||||
span,
|
||||
Some(self.allow_try_trait.clone()),
|
||||
Some(Lrc::clone(&self.allow_try_trait)),
|
||||
);
|
||||
let try_span = self.tcx.sess.source_map().end_point(span);
|
||||
let try_span = self.mark_span_with_reason(
|
||||
DesugaringKind::QuestionMark,
|
||||
try_span,
|
||||
Some(self.allow_try_trait.clone()),
|
||||
Some(Lrc::clone(&self.allow_try_trait)),
|
||||
);
|
||||
|
||||
// `Try::branch(<expr>)`
|
||||
@ -1941,7 +1942,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let unstable_span = self.mark_span_with_reason(
|
||||
DesugaringKind::YeetExpr,
|
||||
span,
|
||||
Some(self.allow_try_trait.clone()),
|
||||
Some(Lrc::clone(&self.allow_try_trait)),
|
||||
);
|
||||
|
||||
let from_yeet_expr = self.wrap_in_try_constructor(
|
||||
|
@ -1878,7 +1878,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),
|
||||
CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),
|
||||
CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {
|
||||
(return_impl_trait_id, Some(self.allow_async_iterator.clone()))
|
||||
(return_impl_trait_id, Some(Lrc::clone(&self.allow_async_iterator)))
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -73,7 +73,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
let bound_modifier_allowed_features = if let Res::Def(DefKind::Trait, async_def_id) = res
|
||||
&& self.tcx.async_fn_trait_kind_from_def_id(async_def_id).is_some()
|
||||
{
|
||||
Some(self.allow_async_fn_traits.clone())
|
||||
Some(Lrc::clone(&self.allow_async_fn_traits))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||
# tidy-alphabetical-start
|
||||
itertools = "0.12"
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_lexer = { path = "../rustc_lexer" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
thin-vec = "0.2.12"
|
||||
|
@ -21,6 +21,7 @@ use rustc_ast::{
|
||||
GenericBound, InlineAsmOperand, InlineAsmOptions, InlineAsmRegOrRegClass,
|
||||
InlineAsmTemplatePiece, PatKind, RangeEnd, RangeSyntax, Safety, SelfKind, Term, attr,
|
||||
};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::{SourceMap, Spanned};
|
||||
use rustc_span::symbol::{Ident, IdentPrinter, Symbol, kw, sym};
|
||||
@ -105,7 +106,7 @@ fn split_block_comment_into_lines(text: &str, col: CharPos) -> Vec<String> {
|
||||
fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comment> {
|
||||
let sm = SourceMap::new(sm.path_mapping().clone());
|
||||
let source_file = sm.new_source_file(path, src);
|
||||
let text = (*source_file.src.as_ref().unwrap()).clone();
|
||||
let text = Lrc::clone(&(*source_file.src.as_ref().unwrap()));
|
||||
|
||||
let text: &str = text.as_str();
|
||||
let start_bpos = source_file.start_pos;
|
||||
|
@ -107,13 +107,13 @@ pub(crate) fn compute_regions<'a, 'tcx>(
|
||||
param_env,
|
||||
body,
|
||||
promoted,
|
||||
universal_regions.clone(),
|
||||
Rc::clone(&universal_regions),
|
||||
location_table,
|
||||
borrow_set,
|
||||
&mut all_facts,
|
||||
flow_inits,
|
||||
move_data,
|
||||
elements.clone(),
|
||||
Rc::clone(&elements),
|
||||
upvars,
|
||||
);
|
||||
|
||||
|
@ -733,7 +733,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
}
|
||||
|
||||
// Now take member constraints into account.
|
||||
let member_constraints = self.member_constraints.clone();
|
||||
let member_constraints = Rc::clone(&self.member_constraints);
|
||||
for m_c_i in member_constraints.indices(scc_a) {
|
||||
self.apply_member_constraint(scc_a, m_c_i, member_constraints.choice_regions(m_c_i));
|
||||
}
|
||||
@ -1679,7 +1679,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
errors_buffer: &mut RegionErrors<'tcx>,
|
||||
) {
|
||||
let member_constraints = self.member_constraints.clone();
|
||||
let member_constraints = Rc::clone(&self.member_constraints);
|
||||
for m_c_i in member_constraints.all_indices() {
|
||||
debug!(?m_c_i);
|
||||
let m_c = &member_constraints[m_c_i];
|
||||
|
@ -134,7 +134,7 @@ pub(crate) fn type_check<'a, 'tcx>(
|
||||
let mut constraints = MirTypeckRegionConstraints {
|
||||
placeholder_indices: PlaceholderIndices::default(),
|
||||
placeholder_index_to_region: IndexVec::default(),
|
||||
liveness_constraints: LivenessValues::with_specific_points(elements.clone()),
|
||||
liveness_constraints: LivenessValues::with_specific_points(Rc::clone(&elements)),
|
||||
outlives_constraints: OutlivesConstraintSet::default(),
|
||||
member_constraints: MemberConstraintSet::default(),
|
||||
type_tests: Vec::default(),
|
||||
@ -150,7 +150,7 @@ pub(crate) fn type_check<'a, 'tcx>(
|
||||
infcx,
|
||||
param_env,
|
||||
implicit_region_bound,
|
||||
universal_regions.clone(),
|
||||
Rc::clone(&universal_regions),
|
||||
&mut constraints,
|
||||
);
|
||||
|
||||
|
@ -503,9 +503,9 @@ fn thin_lto(
|
||||
// upstream...
|
||||
let data = llvm::LLVMRustCreateThinLTOData(
|
||||
thin_modules.as_ptr(),
|
||||
thin_modules.len() as u32,
|
||||
thin_modules.len(),
|
||||
symbols_below_threshold.as_ptr(),
|
||||
symbols_below_threshold.len() as u32,
|
||||
symbols_below_threshold.len(),
|
||||
)
|
||||
.ok_or_else(|| write::llvm_err(dcx, LlvmError::PrepareThinLtoContext))?;
|
||||
|
||||
@ -570,7 +570,7 @@ fn thin_lto(
|
||||
|
||||
info!(" - {}: re-compiled", module_name);
|
||||
opt_jobs.push(LtoModuleCodegen::Thin(ThinModule {
|
||||
shared: shared.clone(),
|
||||
shared: Arc::clone(&shared),
|
||||
idx: module_index,
|
||||
}));
|
||||
}
|
||||
|
@ -2385,9 +2385,9 @@ unsafe extern "C" {
|
||||
pub fn LLVMRustThinLTOBufferThinLinkDataLen(M: &ThinLTOBuffer) -> size_t;
|
||||
pub fn LLVMRustCreateThinLTOData(
|
||||
Modules: *const ThinLTOModule,
|
||||
NumModules: c_uint,
|
||||
NumModules: size_t,
|
||||
PreservedSymbols: *const *const c_char,
|
||||
PreservedSymbolsLen: c_uint,
|
||||
PreservedSymbolsLen: size_t,
|
||||
) -> Option<&'static mut ThinLTOData>;
|
||||
pub fn LLVMRustPrepareThinLTORename(
|
||||
Data: &ThinLTOData,
|
||||
|
@ -514,7 +514,7 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
|
||||
future: Some(coordinator_thread),
|
||||
phantom: PhantomData,
|
||||
},
|
||||
output_filenames: tcx.output_filenames(()).clone(),
|
||||
output_filenames: Arc::clone(tcx.output_filenames(())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1203,7 +1203,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
||||
coordinator_send,
|
||||
expanded_args: tcx.sess.expanded_args.clone(),
|
||||
diag_emitter: shared_emitter.clone(),
|
||||
output_filenames: tcx.output_filenames(()).clone(),
|
||||
output_filenames: Arc::clone(tcx.output_filenames(())),
|
||||
regular_module_config: regular_config,
|
||||
metadata_module_config: metadata_config,
|
||||
allocator_module_config: allocator_config,
|
||||
|
@ -7,7 +7,7 @@ use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_n
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
|
||||
use rustc_data_structures::sync::par_map;
|
||||
use rustc_data_structures::sync::{Lrc, par_map};
|
||||
use rustc_data_structures::unord::UnordMap;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
@ -923,7 +923,7 @@ impl CrateInfo {
|
||||
crate_name: UnordMap::with_capacity(n_crates),
|
||||
used_crates,
|
||||
used_crate_source: UnordMap::with_capacity(n_crates),
|
||||
dependency_formats: tcx.dependency_formats(()).clone(),
|
||||
dependency_formats: Lrc::clone(tcx.dependency_formats(())),
|
||||
windows_subsystem,
|
||||
natvis_debugger_visualizers: Default::default(),
|
||||
};
|
||||
@ -936,7 +936,7 @@ impl CrateInfo {
|
||||
info.crate_name.insert(cnum, tcx.crate_name(cnum));
|
||||
|
||||
let used_crate_source = tcx.used_crate_source(cnum);
|
||||
info.used_crate_source.insert(cnum, used_crate_source.clone());
|
||||
info.used_crate_source.insert(cnum, Lrc::clone(used_crate_source));
|
||||
if tcx.is_profiler_runtime(cnum) {
|
||||
info.profiler_runtime = Some(cnum);
|
||||
}
|
||||
|
@ -1395,7 +1395,7 @@ pub fn install_ice_hook(
|
||||
}
|
||||
|
||||
let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
|
||||
let using_internal_features_hook = using_internal_features.clone();
|
||||
let using_internal_features_hook = Arc::clone(&using_internal_features);
|
||||
panic::update_hook(Box::new(
|
||||
move |default_hook: &(dyn Fn(&PanicHookInfo<'_>) + Send + Sync + 'static),
|
||||
info: &PanicHookInfo<'_>| {
|
||||
|
@ -173,7 +173,7 @@ impl AnnotateSnippetEmitter {
|
||||
source_map.ensure_source_file_source_present(&file);
|
||||
(
|
||||
format!("{}", source_map.filename_for_diagnostics(&file.name)),
|
||||
source_string(file.clone(), &line),
|
||||
source_string(Lrc::clone(&file), &line),
|
||||
line.line_index,
|
||||
line.annotations,
|
||||
)
|
||||
|
@ -1555,7 +1555,7 @@ impl HumanEmitter {
|
||||
// Get the left-side margin to remove it
|
||||
let mut whitespace_margin = usize::MAX;
|
||||
for line_idx in 0..annotated_file.lines.len() {
|
||||
let file = annotated_file.file.clone();
|
||||
let file = Lrc::clone(&annotated_file.file);
|
||||
let line = &annotated_file.lines[line_idx];
|
||||
if let Some(source_string) =
|
||||
line.line_index.checked_sub(1).and_then(|l| file.get_line(l))
|
||||
@ -1646,7 +1646,7 @@ impl HumanEmitter {
|
||||
|
||||
let depths = self.render_source_line(
|
||||
&mut buffer,
|
||||
annotated_file.file.clone(),
|
||||
Lrc::clone(&annotated_file.file),
|
||||
&annotated_file.lines[line_idx],
|
||||
width_offset,
|
||||
code_offset,
|
||||
@ -2529,7 +2529,12 @@ impl FileWithAnnotatedLines {
|
||||
// | | |
|
||||
// | |______foo
|
||||
// | baz
|
||||
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
|
||||
add_annotation_to_file(
|
||||
&mut output,
|
||||
Lrc::clone(&file),
|
||||
ann.line_start,
|
||||
ann.as_start(),
|
||||
);
|
||||
// 4 is the minimum vertical length of a multiline span when presented: two lines
|
||||
// of code and two lines of underline. This is not true for the special case where
|
||||
// the beginning doesn't have an underline, but the current logic seems to be
|
||||
@ -2545,11 +2550,11 @@ impl FileWithAnnotatedLines {
|
||||
.unwrap_or(ann.line_start);
|
||||
for line in ann.line_start + 1..until {
|
||||
// Every `|` that joins the beginning of the span (`___^`) to the end (`|__^`).
|
||||
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
|
||||
add_annotation_to_file(&mut output, Lrc::clone(&file), line, ann.as_line());
|
||||
}
|
||||
let line_end = ann.line_end - 1;
|
||||
if middle < line_end {
|
||||
add_annotation_to_file(&mut output, file.clone(), line_end, ann.as_line());
|
||||
add_annotation_to_file(&mut output, Lrc::clone(&file), line_end, ann.as_line());
|
||||
}
|
||||
} else {
|
||||
end_ann.annotation_type = AnnotationType::Singleline;
|
||||
|
@ -367,9 +367,9 @@ impl Diagnostic {
|
||||
ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)),
|
||||
ColorConfig::Never => {}
|
||||
}
|
||||
HumanEmitter::new(dst, je.fallback_bundle.clone())
|
||||
HumanEmitter::new(dst, Lrc::clone(&je.fallback_bundle))
|
||||
.short_message(short)
|
||||
.sm(Some(je.sm.clone()))
|
||||
.sm(Some(Lrc::clone(&je.sm)))
|
||||
.fluent_bundle(je.fluent_bundle.clone())
|
||||
.diagnostic_width(je.diagnostic_width)
|
||||
.macro_backtrace(je.macro_backtrace)
|
||||
|
@ -622,7 +622,7 @@ impl TtParser {
|
||||
// possible next positions into `next_mps`. After some post-processing, the contents of
|
||||
// `next_mps` replenish `cur_mps` and we start over again.
|
||||
self.cur_mps.clear();
|
||||
self.cur_mps.push(MatcherPos { idx: 0, matches: self.empty_matches.clone() });
|
||||
self.cur_mps.push(MatcherPos { idx: 0, matches: Rc::clone(&self.empty_matches) });
|
||||
|
||||
loop {
|
||||
self.next_mps.clear();
|
||||
|
@ -5,6 +5,7 @@ use rustc_ast::mut_visit::{self, MutVisitor};
|
||||
use rustc_ast::token::{self, Delimiter, IdentIsRaw, Lit, LitKind, Nonterminal, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
|
||||
use rustc_parse::lexer::nfc_normalize;
|
||||
use rustc_parse::parser::ParseNtResult;
|
||||
@ -293,7 +294,7 @@ pub(super) fn transcribe<'a>(
|
||||
// `Delimiter::Invisible` to maintain parsing priorities.
|
||||
// `Interpolated` is currently used for such groups in rustc parser.
|
||||
marker.visit_span(&mut sp);
|
||||
TokenTree::token_alone(token::Interpolated(nt.clone()), sp)
|
||||
TokenTree::token_alone(token::Interpolated(Lrc::clone(nt)), sp)
|
||||
}
|
||||
MatchedSeq(..) => {
|
||||
// We were unable to descend far enough. This is an error.
|
||||
|
@ -149,10 +149,6 @@ hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported
|
||||
hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice
|
||||
.label = parameter captured again here
|
||||
|
||||
hir_analysis_effects_without_next_solver = using `#![feature(effects)]` without enabling next trait solver globally
|
||||
.note = the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
.help = use `-Znext-solver` to enable
|
||||
|
||||
hir_analysis_empty_specialization = specialization impl does not specialize any associated items
|
||||
.note = impl is a specialization of this impl
|
||||
|
||||
|
@ -367,20 +367,8 @@ pub(super) fn explicit_item_bounds_with_filter(
|
||||
// a projection self type.
|
||||
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
|
||||
let opaque_ty = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_opaque_ty();
|
||||
let item_ty = Ty::new_projection_from_args(
|
||||
tcx,
|
||||
def_id.to_def_id(),
|
||||
ty::GenericArgs::identity_for_item(tcx, def_id),
|
||||
);
|
||||
let bounds = opaque_type_bounds(
|
||||
tcx,
|
||||
opaque_def_id.expect_local(),
|
||||
opaque_ty.bounds,
|
||||
item_ty,
|
||||
opaque_ty.span,
|
||||
filter,
|
||||
);
|
||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||
let bounds =
|
||||
associated_type_bounds(tcx, def_id, opaque_ty.bounds, opaque_ty.span, filter);
|
||||
return ty::EarlyBinder::bind(bounds);
|
||||
}
|
||||
Some(ty::ImplTraitInTraitData::Impl { .. }) => span_bug!(
|
||||
|
@ -1623,12 +1623,6 @@ pub(crate) struct InvalidReceiverTy<'tcx> {
|
||||
pub receiver_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_effects_without_next_solver)]
|
||||
#[note]
|
||||
#[help]
|
||||
pub(crate) struct EffectsWithoutNextSolver;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_cmse_inputs_stack_spill, code = E0798)]
|
||||
#[note]
|
||||
|
@ -153,12 +153,6 @@ pub fn provide(providers: &mut Providers) {
|
||||
pub fn check_crate(tcx: TyCtxt<'_>) {
|
||||
let _prof_timer = tcx.sess.timer("type_check_crate");
|
||||
|
||||
// FIXME(effects): remove once effects is implemented in old trait solver
|
||||
// or if the next solver is stabilized.
|
||||
if tcx.features().effects() && !tcx.next_trait_solver_globally() {
|
||||
tcx.dcx().emit_err(errors::EffectsWithoutNextSolver);
|
||||
}
|
||||
|
||||
tcx.sess.time("coherence_checking", || {
|
||||
tcx.hir().par_for_each_module(|module| {
|
||||
let _ = tcx.ensure().check_mod_type_wf(module);
|
||||
|
@ -364,7 +364,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
span,
|
||||
concrete_ty,
|
||||
r,
|
||||
choice_regions.clone(),
|
||||
Lrc::clone(&choice_regions),
|
||||
)
|
||||
},
|
||||
});
|
||||
|
@ -142,7 +142,7 @@ impl Linker {
|
||||
|
||||
Ok(Linker {
|
||||
dep_graph: tcx.dep_graph.clone(),
|
||||
output_filenames: tcx.output_filenames(()).clone(),
|
||||
output_filenames: Arc::clone(tcx.output_filenames(())),
|
||||
crate_hash: if tcx.needs_crate_hash() {
|
||||
Some(tcx.crate_hash(LOCAL_CRATE))
|
||||
} else {
|
||||
|
@ -1251,12 +1251,12 @@ getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
|
||||
// here is basically the same as before threads are spawned in the `run`
|
||||
// function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
|
||||
extern "C" LLVMRustThinLTOData *
|
||||
LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules,
|
||||
const char **preserved_symbols, int num_symbols) {
|
||||
LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, size_t num_modules,
|
||||
const char **preserved_symbols, size_t num_symbols) {
|
||||
auto Ret = std::make_unique<LLVMRustThinLTOData>();
|
||||
|
||||
// Load each module's summary and merge it into one combined index
|
||||
for (int i = 0; i < num_modules; i++) {
|
||||
for (size_t i = 0; i < num_modules; i++) {
|
||||
auto module = &modules[i];
|
||||
auto buffer = StringRef(module->data, module->len);
|
||||
auto mem_buffer = MemoryBufferRef(buffer, module->identifier);
|
||||
@ -1275,7 +1275,7 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules,
|
||||
|
||||
// Convert the preserved symbols set from string to GUID, this is then needed
|
||||
// for internalization.
|
||||
for (int i = 0; i < num_symbols; i++) {
|
||||
for (size_t i = 0; i < num_symbols; i++) {
|
||||
auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
|
||||
Ret->GUIDPreservedSymbols.insert(GUID);
|
||||
}
|
||||
|
@ -1231,7 +1231,7 @@ extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() {
|
||||
return dwarf::DW_OP_plus_uconst;
|
||||
}
|
||||
|
||||
extern "C" int64_t LLVMRustDIBuilderCreateOpLLVMFragment() {
|
||||
extern "C" uint64_t LLVMRustDIBuilderCreateOpLLVMFragment() {
|
||||
return dwarf::DW_OP_LLVM_fragment;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
|
||||
let source_map = s.tcx.sess.source_map();
|
||||
let source_file_index = source_map.lookup_source_file_idx(self.lo);
|
||||
s.source_file_cache =
|
||||
(source_map.files()[source_file_index].clone(), source_file_index);
|
||||
(Lrc::clone(&source_map.files()[source_file_index]), source_file_index);
|
||||
}
|
||||
let (ref source_file, source_file_index) = s.source_file_cache;
|
||||
debug_assert!(source_file.contains(self.lo));
|
||||
@ -2275,7 +2275,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) {
|
||||
encoder.emit_raw_bytes(&0u64.to_le_bytes());
|
||||
|
||||
let source_map_files = tcx.sess.source_map().files();
|
||||
let source_file_cache = (source_map_files[0].clone(), 0);
|
||||
let source_file_cache = (Lrc::clone(&source_map_files[0]), 0);
|
||||
let required_source_files = Some(FxIndexSet::default());
|
||||
drop(source_map_files);
|
||||
|
||||
|
@ -32,7 +32,7 @@ impl DebuggerVisualizerFile {
|
||||
|
||||
pub fn path_erased(&self) -> Self {
|
||||
DebuggerVisualizerFile {
|
||||
src: self.src.clone(),
|
||||
src: Lrc::clone(&self.src),
|
||||
visualizer_type: self.visualizer_type,
|
||||
path: None,
|
||||
}
|
||||
|
@ -472,32 +472,27 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
|
||||
let CacheDecoder { tcx, file_index_to_file, file_index_to_stable_id, source_map, .. } =
|
||||
*self;
|
||||
|
||||
file_index_to_file
|
||||
.borrow_mut()
|
||||
.entry(index)
|
||||
.or_insert_with(|| {
|
||||
let source_file_id = &file_index_to_stable_id[&index];
|
||||
let source_file_cnum =
|
||||
tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
|
||||
Lrc::clone(file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
|
||||
let source_file_id = &file_index_to_stable_id[&index];
|
||||
let source_file_cnum = tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
|
||||
|
||||
// If this `SourceFile` is from a foreign crate, then make sure
|
||||
// that we've imported all of the source files from that crate.
|
||||
// This has usually already been done during macro invocation.
|
||||
// However, when encoding query results like `TypeckResults`,
|
||||
// we might encode an `AdtDef` for a foreign type (because it
|
||||
// was referenced in the body of the function). There is no guarantee
|
||||
// that we will load the source files from that crate during macro
|
||||
// expansion, so we use `import_source_files` to ensure that the foreign
|
||||
// source files are actually imported before we call `source_file_by_stable_id`.
|
||||
if source_file_cnum != LOCAL_CRATE {
|
||||
self.tcx.import_source_files(source_file_cnum);
|
||||
}
|
||||
// If this `SourceFile` is from a foreign crate, then make sure
|
||||
// that we've imported all of the source files from that crate.
|
||||
// This has usually already been done during macro invocation.
|
||||
// However, when encoding query results like `TypeckResults`,
|
||||
// we might encode an `AdtDef` for a foreign type (because it
|
||||
// was referenced in the body of the function). There is no guarantee
|
||||
// that we will load the source files from that crate during macro
|
||||
// expansion, so we use `import_source_files` to ensure that the foreign
|
||||
// source files are actually imported before we call `source_file_by_stable_id`.
|
||||
if source_file_cnum != LOCAL_CRATE {
|
||||
self.tcx.import_source_files(source_file_cnum);
|
||||
}
|
||||
|
||||
source_map
|
||||
.source_file_by_stable_id(source_file_id.stable_source_file_id)
|
||||
.expect("failed to lookup `SourceFile` in new context")
|
||||
})
|
||||
.clone()
|
||||
source_map
|
||||
.source_file_by_stable_id(source_file_id.stable_source_file_id)
|
||||
.expect("failed to lookup `SourceFile` in new context")
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ use rustc_ast::{
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult, Subdiagnostic,
|
||||
Suggestions, pluralize,
|
||||
@ -2437,7 +2438,7 @@ impl<'a> Parser<'a> {
|
||||
let mut labels = vec![];
|
||||
while let TokenKind::Interpolated(nt) = &tok.kind {
|
||||
let tokens = nt.tokens();
|
||||
labels.push(nt.clone());
|
||||
labels.push(Lrc::clone(nt));
|
||||
if let Some(tokens) = tokens
|
||||
&& let tokens = tokens.to_attr_token_stream()
|
||||
&& let tokens = tokens.0.deref()
|
||||
|
@ -134,7 +134,7 @@ impl<D: Deps> DepGraph<D> {
|
||||
encoder,
|
||||
record_graph,
|
||||
record_stats,
|
||||
prev_graph.clone(),
|
||||
Arc::clone(&prev_graph),
|
||||
);
|
||||
|
||||
let colors = DepNodeColorMap::new(prev_graph_node_count);
|
||||
|
@ -237,7 +237,7 @@ impl QueryLatch {
|
||||
// the `wait` call below, by 1) the `set` method or 2) by deadlock detection.
|
||||
// Both of these will remove it from the `waiters` list before resuming
|
||||
// this thread.
|
||||
info.waiters.push(waiter.clone());
|
||||
info.waiters.push(Arc::clone(waiter));
|
||||
|
||||
// If this detects a deadlock and the deadlock handler wants to resume this thread
|
||||
// we have to be in the `wait` call. This is ensured by the deadlock handler
|
||||
|
@ -1694,9 +1694,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
|
||||
fn dummy_ext(&self, macro_kind: MacroKind) -> Lrc<SyntaxExtension> {
|
||||
match macro_kind {
|
||||
MacroKind::Bang => self.dummy_ext_bang.clone(),
|
||||
MacroKind::Derive => self.dummy_ext_derive.clone(),
|
||||
MacroKind::Attr => self.non_macro_attr.ext.clone(),
|
||||
MacroKind::Bang => Lrc::clone(&self.dummy_ext_bang),
|
||||
MacroKind::Derive => Lrc::clone(&self.dummy_ext_derive),
|
||||
MacroKind::Attr => Lrc::clone(&self.non_macro_attr.ext),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -826,7 +826,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
None => self.get_macro(res).map(|macro_data| macro_data.ext.clone()),
|
||||
None => self.get_macro(res).map(|macro_data| Lrc::clone(¯o_data.ext)),
|
||||
};
|
||||
Ok((ext, res))
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ impl ParseSess {
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let emitter = Box::new(
|
||||
HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle)
|
||||
.sm(Some(sm.clone())),
|
||||
.sm(Some(Lrc::clone(&sm))),
|
||||
);
|
||||
let dcx = DiagCtxt::new(emitter);
|
||||
ParseSess::with_dcx(dcx, sm)
|
||||
@ -278,7 +278,7 @@ impl ParseSess {
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let emitter = Box::new(HumanEmitter::new(
|
||||
stderr_destination(ColorConfig::Auto),
|
||||
fallback_bundle.clone(),
|
||||
Lrc::clone(&fallback_bundle),
|
||||
));
|
||||
let fatal_dcx = DiagCtxt::new(emitter);
|
||||
let dcx = DiagCtxt::new(Box::new(SilentEmitter {
|
||||
@ -297,7 +297,7 @@ impl ParseSess {
|
||||
}
|
||||
|
||||
pub fn clone_source_map(&self) -> Lrc<SourceMap> {
|
||||
self.source_map.clone()
|
||||
Lrc::clone(&self.source_map)
|
||||
}
|
||||
|
||||
pub fn buffer_lint(
|
||||
|
@ -1036,7 +1036,8 @@ pub fn build_session(
|
||||
sopts.unstable_opts.translate_directionality_markers,
|
||||
);
|
||||
let source_map = rustc_span::source_map::get_source_map().unwrap();
|
||||
let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle);
|
||||
let emitter =
|
||||
default_emitter(&sopts, registry, Lrc::clone(&source_map), bundle, fallback_bundle);
|
||||
|
||||
let mut dcx =
|
||||
DiagCtxt::new(emitter).with_flags(sopts.unstable_opts.dcx_flags(can_emit_warnings));
|
||||
@ -1079,7 +1080,7 @@ pub fn build_session(
|
||||
let target_tlib_path = if host_triple == target_triple {
|
||||
// Use the same `SearchPath` if host and target triple are identical to avoid unnecessary
|
||||
// rescanning of the target lib path and an unnecessary allocation.
|
||||
host_tlib_path.clone()
|
||||
Lrc::clone(&host_tlib_path)
|
||||
} else {
|
||||
Lrc::new(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ pub struct CachingSourceMapView<'sm> {
|
||||
impl<'sm> CachingSourceMapView<'sm> {
|
||||
pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> {
|
||||
let files = source_map.files();
|
||||
let first_file = files[0].clone();
|
||||
let first_file = Lrc::clone(&files[0]);
|
||||
let entry = CacheEntry {
|
||||
time_stamp: 0,
|
||||
line_number: 0,
|
||||
@ -92,7 +92,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
||||
cache_entry.touch(self.time_stamp);
|
||||
|
||||
let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32());
|
||||
return Some((cache_entry.file.clone(), cache_entry.line_number, col));
|
||||
return Some((Lrc::clone(&cache_entry.file), cache_entry.line_number, col));
|
||||
}
|
||||
|
||||
// No cache hit ...
|
||||
@ -109,7 +109,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
||||
cache_entry.update(new_file_and_idx, pos, self.time_stamp);
|
||||
|
||||
let col = RelativeBytePos(pos.to_u32() - cache_entry.line.start.to_u32());
|
||||
Some((cache_entry.file.clone(), cache_entry.line_number, col))
|
||||
Some((Lrc::clone(&cache_entry.file), cache_entry.line_number, col))
|
||||
}
|
||||
|
||||
pub fn span_data_to_lines_and_cols(
|
||||
@ -133,7 +133,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
||||
}
|
||||
|
||||
(
|
||||
lo.file.clone(),
|
||||
Lrc::clone(&lo.file),
|
||||
lo.line_number,
|
||||
span_data.lo - lo.line.start,
|
||||
hi.line_number,
|
||||
@ -181,7 +181,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
||||
lo.update(new_file_and_idx, span_data.lo, self.time_stamp);
|
||||
|
||||
if !lo.line.contains(&span_data.hi) {
|
||||
let new_file_and_idx = Some((lo.file.clone(), lo.file_index));
|
||||
let new_file_and_idx = Some((Lrc::clone(&lo.file), lo.file_index));
|
||||
let next_oldest = self.oldest_cache_entry_index_avoid(oldest);
|
||||
let hi = &mut self.line_cache[next_oldest];
|
||||
hi.update(new_file_and_idx, span_data.hi, self.time_stamp);
|
||||
@ -227,7 +227,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
||||
assert_eq!(lo.file_index, hi.file_index);
|
||||
|
||||
Some((
|
||||
lo.file.clone(),
|
||||
Lrc::clone(&lo.file),
|
||||
lo.line_number,
|
||||
span_data.lo - lo.line.start,
|
||||
hi.line_number,
|
||||
@ -277,7 +277,7 @@ impl<'sm> CachingSourceMapView<'sm> {
|
||||
let file = &self.source_map.files()[file_idx];
|
||||
|
||||
if file_contains(file, pos) {
|
||||
return Some((file.clone(), file_idx));
|
||||
return Some((Lrc::clone(file), file_idx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,8 +286,8 @@ impl SourceMap {
|
||||
});
|
||||
|
||||
let file = Lrc::new(file);
|
||||
files.source_files.push(file.clone());
|
||||
files.stable_id_to_source_file.insert(file_id, file.clone());
|
||||
files.source_files.push(Lrc::clone(&file));
|
||||
files.stable_id_to_source_file.insert(file_id, Lrc::clone(&file));
|
||||
|
||||
Ok(file)
|
||||
}
|
||||
@ -386,7 +386,7 @@ impl SourceMap {
|
||||
/// Return the SourceFile that contains the given `BytePos`
|
||||
pub fn lookup_source_file(&self, pos: BytePos) -> Lrc<SourceFile> {
|
||||
let idx = self.lookup_source_file_idx(pos);
|
||||
(*self.files.borrow().source_files)[idx].clone()
|
||||
Lrc::clone(&(*self.files.borrow().source_files)[idx])
|
||||
}
|
||||
|
||||
/// Looks up source information about a `BytePos`.
|
||||
@ -468,7 +468,7 @@ impl SourceMap {
|
||||
if lo != hi {
|
||||
return true;
|
||||
}
|
||||
let f = (*self.files.borrow().source_files)[lo].clone();
|
||||
let f = Lrc::clone(&(*self.files.borrow().source_files)[lo]);
|
||||
let lo = f.relative_position(sp.lo());
|
||||
let hi = f.relative_position(sp.hi());
|
||||
f.lookup_line(lo) != f.lookup_line(hi)
|
||||
@ -994,7 +994,7 @@ impl SourceMap {
|
||||
let filename = self.path_mapping().map_filename_prefix(filename).0;
|
||||
for sf in self.files.borrow().source_files.iter() {
|
||||
if filename == sf.name {
|
||||
return Some(sf.clone());
|
||||
return Some(Lrc::clone(&sf));
|
||||
}
|
||||
}
|
||||
None
|
||||
@ -1003,7 +1003,7 @@ impl SourceMap {
|
||||
/// For a global `BytePos`, computes the local offset within the containing `SourceFile`.
|
||||
pub fn lookup_byte_offset(&self, bpos: BytePos) -> SourceFileAndBytePos {
|
||||
let idx = self.lookup_source_file_idx(bpos);
|
||||
let sf = (*self.files.borrow().source_files)[idx].clone();
|
||||
let sf = Lrc::clone(&(*self.files.borrow().source_files)[idx]);
|
||||
let offset = bpos - sf.start_pos;
|
||||
SourceFileAndBytePos { sf, pos: offset }
|
||||
}
|
||||
|
152
compiler/rustc_trait_selection/src/traits/effects.rs
Normal file
152
compiler/rustc_trait_selection/src/traits/effects.rs
Normal 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),
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
@ -17,6 +17,7 @@ use rustc_middle::ty::{self, Binder, Const, GenericArgsRef, TypeVisitableExt};
|
||||
use thin_vec::ThinVec;
|
||||
use tracing::{debug, debug_span, instrument};
|
||||
|
||||
use super::effects::{self, HostEffectObligation};
|
||||
use super::project::{self, ProjectAndUnifyResult};
|
||||
use super::select::SelectionContext;
|
||||
use super::{
|
||||
@ -402,8 +403,13 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||
ProcessResult::Changed(Default::default())
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
|
||||
let host_obligation = obligation.with(infcx.tcx, data);
|
||||
|
||||
self.process_host_obligation(
|
||||
host_obligation,
|
||||
&mut pending_obligation.stalled_on,
|
||||
)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
|
||||
@ -854,6 +860,27 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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`.
|
||||
|
@ -6,6 +6,7 @@ pub mod auto_trait;
|
||||
pub(crate) mod coherence;
|
||||
pub mod const_evaluatable;
|
||||
mod dyn_compatibility;
|
||||
pub mod effects;
|
||||
mod engine;
|
||||
mod fulfill;
|
||||
pub mod misc;
|
||||
|
@ -49,7 +49,7 @@ use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||
use crate::solve::InferCtxtSelectExt as _;
|
||||
use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
|
||||
use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt};
|
||||
use crate::traits::{ProjectionCacheKey, Unimplemented};
|
||||
use crate::traits::{ProjectionCacheKey, Unimplemented, effects};
|
||||
|
||||
mod _match;
|
||||
mod candidate_assembly;
|
||||
@ -645,11 +645,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||
// FIXME(effects): It should be relatively straightforward to implement
|
||||
// old trait solver support for `HostEffect` bounds; or at least basic
|
||||
// support for them.
|
||||
todo!()
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
|
||||
self.infcx.enter_forall(bound_predicate.rebind(data), |data| {
|
||||
match effects::evaluate_host_effect_obligation(
|
||||
self,
|
||||
&obligation.with(self.tcx(), data),
|
||||
) {
|
||||
Ok(nested) => {
|
||||
self.evaluate_predicates_recursively(previous_stack, nested)
|
||||
}
|
||||
Err(effects::EvaluationFailure::Ambiguous) => Ok(EvaluatedToAmbig),
|
||||
Err(effects::EvaluationFailure::NoSolution) => Ok(EvaluatedToErr),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ty::PredicateKind::Subtype(p) => {
|
||||
|
File diff suppressed because it is too large
Load Diff
747
library/alloc/src/boxed/convert.rs
Normal file
747
library/alloc/src/boxed/convert.rs
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
194
library/alloc/src/boxed/iter.rs
Normal file
194
library/alloc/src/boxed/iter.rs
Normal 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()
|
||||
}
|
||||
}
|
@ -185,7 +185,9 @@
|
||||
#![feature(cfg_target_has_atomic_equal_alignment)]
|
||||
#![feature(cfg_ub_checks)]
|
||||
#![feature(const_for)]
|
||||
#![feature(const_is_char_boundary)]
|
||||
#![feature(const_precise_live_drops)]
|
||||
#![feature(const_str_split_at)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(deprecated_suggestion)]
|
||||
#![feature(doc_cfg)]
|
||||
|
@ -185,8 +185,9 @@ impl str {
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[stable(feature = "is_char_boundary", since = "1.9.0")]
|
||||
#[rustc_const_unstable(feature = "const_is_char_boundary", issue = "131516")]
|
||||
#[inline]
|
||||
pub fn is_char_boundary(&self, index: usize) -> bool {
|
||||
pub const fn is_char_boundary(&self, index: usize) -> bool {
|
||||
// 0 is always ok.
|
||||
// Test for 0 explicitly so that it can optimize out the check
|
||||
// easily and skip reading string data for that case.
|
||||
@ -195,8 +196,8 @@ impl str {
|
||||
return true;
|
||||
}
|
||||
|
||||
match self.as_bytes().get(index) {
|
||||
// For `None` we have two options:
|
||||
if index >= self.len() {
|
||||
// For `true` we have two options:
|
||||
//
|
||||
// - index == self.len()
|
||||
// Empty strings are valid, so return true
|
||||
@ -205,9 +206,9 @@ impl str {
|
||||
//
|
||||
// The check is placed exactly here, because it improves generated
|
||||
// code on higher opt-levels. See PR #84751 for more details.
|
||||
None => index == self.len(),
|
||||
|
||||
Some(&b) => b.is_utf8_char_boundary(),
|
||||
index == self.len()
|
||||
} else {
|
||||
self.as_bytes()[index].is_utf8_char_boundary()
|
||||
}
|
||||
}
|
||||
|
||||
@ -637,7 +638,8 @@ impl str {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "str_split_at", since = "1.4.0")]
|
||||
pub fn split_at(&self, mid: usize) -> (&str, &str) {
|
||||
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
|
||||
pub const fn split_at(&self, mid: usize) -> (&str, &str) {
|
||||
match self.split_at_checked(mid) {
|
||||
None => slice_error_fail(self, 0, mid),
|
||||
Some(pair) => pair,
|
||||
@ -677,7 +679,8 @@ impl str {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "str_split_at", since = "1.4.0")]
|
||||
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
|
||||
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
|
||||
pub const fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
|
||||
// is_char_boundary checks that the index is in [0, .len()]
|
||||
if self.is_char_boundary(mid) {
|
||||
// SAFETY: just checked that `mid` is on a char boundary.
|
||||
@ -716,11 +719,12 @@ impl str {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "split_at_checked", since = "1.80.0")]
|
||||
pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
|
||||
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
|
||||
pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
|
||||
// is_char_boundary checks that the index is in [0, .len()]
|
||||
if self.is_char_boundary(mid) {
|
||||
// SAFETY: just checked that `mid` is on a char boundary.
|
||||
Some(unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) })
|
||||
Some(unsafe { self.split_at_unchecked(mid) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -756,7 +760,9 @@ impl str {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "split_at_checked", since = "1.80.0")]
|
||||
pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
|
||||
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
|
||||
#[rustc_allow_const_fn_unstable(const_is_char_boundary)]
|
||||
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
|
||||
// is_char_boundary checks that the index is in [0, .len()]
|
||||
if self.is_char_boundary(mid) {
|
||||
// SAFETY: just checked that `mid` is on a char boundary.
|
||||
@ -772,7 +778,25 @@ impl str {
|
||||
///
|
||||
/// The caller must ensure that `mid` is a valid byte offset from the start
|
||||
/// of the string and falls on the boundary of a UTF-8 code point.
|
||||
unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
|
||||
const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
|
||||
let len = self.len();
|
||||
let ptr = self.as_ptr();
|
||||
// SAFETY: caller guarantees `mid` is on a char boundary.
|
||||
unsafe {
|
||||
(
|
||||
from_utf8_unchecked(slice::from_raw_parts(ptr, mid)),
|
||||
from_utf8_unchecked(slice::from_raw_parts(ptr.add(mid), len - mid)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Divides one string slice into two at an index.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure that `mid` is a valid byte offset from the start
|
||||
/// of the string and falls on the boundary of a UTF-8 code point.
|
||||
const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
|
||||
let len = self.len();
|
||||
let ptr = self.as_mut_ptr();
|
||||
// SAFETY: caller guarantees `mid` is on a char boundary.
|
||||
|
@ -1197,7 +1197,7 @@ impl OpenOptions {
|
||||
|
||||
/// Sets the option for truncating a previous file.
|
||||
///
|
||||
/// If a file is successfully opened with this option set it will truncate
|
||||
/// If a file is successfully opened with this option set to true, it will truncate
|
||||
/// the file to 0 length if it already exists.
|
||||
///
|
||||
/// The file must be opened with write access for truncate to work.
|
||||
|
@ -51,7 +51,8 @@ ENV SCRIPT \
|
||||
/scripts/check-default-config-profiles.sh && \
|
||||
python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
|
||||
python3 ../x.py clippy bootstrap -Dwarnings && \
|
||||
python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \
|
||||
python3 ../x.py clippy library -Aclippy::all -Dclippy::correctness && \
|
||||
python3 ../x.py clippy compiler -Aclippy::all -Dclippy::correctness -Dclippy::clone_on_ref_ptr && \
|
||||
python3 ../x.py build --stage 0 src/tools/build-manifest && \
|
||||
python3 ../x.py test --stage 0 src/tools/compiletest && \
|
||||
python3 ../x.py test --stage 0 core alloc std test proc_macro && \
|
||||
|
@ -250,7 +250,7 @@ def get_known_directive_names():
|
||||
os.path.join(
|
||||
# We go back to `src`.
|
||||
os.path.dirname(os.path.dirname(__file__)),
|
||||
"tools/compiletest/src/command-list.rs",
|
||||
"tools/compiletest/src/directive-list.rs",
|
||||
),
|
||||
"r",
|
||||
encoding="utf8"
|
||||
|
@ -709,11 +709,11 @@ fn line_directive<'line>(
|
||||
Some(DirectiveLine { line_number, revision, raw_directive })
|
||||
}
|
||||
|
||||
// To prevent duplicating the list of commmands between `compiletest`,`htmldocck` and `jsondocck`,
|
||||
// To prevent duplicating the list of directives between `compiletest`,`htmldocck` and `jsondocck`,
|
||||
// we put it into a common file which is included in rust code and parsed here.
|
||||
// FIXME: This setup is temporary until we figure out how to improve this situation.
|
||||
// See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
|
||||
include!("command-list.rs");
|
||||
include!("directive-list.rs");
|
||||
|
||||
const KNOWN_HTMLDOCCK_DIRECTIVE_NAMES: &[&str] = &[
|
||||
"count",
|
||||
|
@ -123,7 +123,7 @@ fn print_err(msg: &str, lineno: usize) {
|
||||
|
||||
// FIXME: This setup is temporary until we figure out how to improve this situation.
|
||||
// See <https://github.com/rust-lang/rust/issues/125813#issuecomment-2141953780>.
|
||||
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/command-list.rs"));
|
||||
include!(concat!(env!("CARGO_MANIFEST_DIR"), "/../compiletest/src/directive-list.rs"));
|
||||
|
||||
/// Get a list of commands from a file. Does the work of ensuring the commands
|
||||
/// are syntactically valid.
|
||||
|
@ -23,7 +23,7 @@ note: inside `<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-p
|
||||
|
|
||||
LL | match me.resume(()) {
|
||||
| ^^^^^^^^^^^^^
|
||||
= note: inside `<std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-pinned-moved.rs:LL:CC}>> as std::iter::Iterator>::next` at RUSTLIB/alloc/src/boxed.rs:LL:CC
|
||||
= note: inside `std::boxed::iter::<impl std::iter::Iterator for std::boxed::Box<CoroutineIteratorAdapter<{static coroutine@tests/fail/coroutine-pinned-moved.rs:LL:CC}>>>::next` at RUSTLIB/alloc/src/boxed/iter.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> tests/fail/coroutine-pinned-moved.rs:LL:CC
|
||||
|
|
||||
|
@ -1,6 +1,9 @@
|
||||
//@ assembly-output: emit-asm
|
||||
//@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d
|
||||
//@ needs-llvm-components: riscv
|
||||
//@ revisions: LLVM-PRE-20 LLVM-POST-20
|
||||
//@ [LLVM-PRE-20] ignore-llvm-version: 20 - 99
|
||||
//@ [LLVM-POST-20] min-llvm-version: 20
|
||||
|
||||
#![feature(no_core, lang_items, f16)]
|
||||
#![crate_type = "lib"]
|
||||
@ -31,9 +34,11 @@ pub extern "C" fn read_f16(x: &f16) -> f16 {
|
||||
// CHECK-LABEL: read_f32
|
||||
#[no_mangle]
|
||||
pub extern "C" fn read_f32(x: &f32) -> f32 {
|
||||
// CHECK: flw fa5, 0(a0)
|
||||
// CHECK-NEXT: fmv.x.w a0, fa5
|
||||
// CHECK-NEXT: ret
|
||||
// LLVM-PRE-20: flw fa5, 0(a0)
|
||||
// LLVM-PRE-20-NEXT: fmv.x.w a0, fa5
|
||||
// LLVM-PRE-20-NEXT: ret
|
||||
// LLVM-POST-20: lw a0, 0(a0)
|
||||
// LLVM-POST-20-NEXT: ret
|
||||
*x
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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() {}
|
@ -1,14 +1,15 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
|
||||
error[E0277]: the trait bound `T: const Tr` is not satisfied
|
||||
--> $DIR/constifconst-call-in-const-position.rs:17:38
|
||||
|
|
||||
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
|
||||
| ^^^^^^ calling non-const function `<() as Tr>::a`
|
||||
| ^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `T: const Tr` is not satisfied
|
||||
--> $DIR/constifconst-call-in-const-position.rs:18:9
|
||||
|
|
||||
LL | [0; T::a()]
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -1,8 +1,3 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:26:5: 26:24>::{synthetic#0}`
|
||||
--> $DIR/unsupported.rs:27:25
|
||||
|
|
||||
@ -89,7 +84,7 @@ LL | reuse Trait::foo;
|
||||
|
|
||||
= note: cannot satisfy `_: effects::Trait`
|
||||
|
||||
error: aborting due to 5 previous errors; 2 warnings emitted
|
||||
error: aborting due to 4 previous errors; 2 warnings emitted
|
||||
|
||||
Some errors have detailed explanations: E0283, E0391.
|
||||
For more information about an error, try `rustc --explain E0283`.
|
||||
|
@ -17,11 +17,6 @@ LL | #![feature(effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: const `impl` for trait `Drop` which is not marked with `#[const_trait]`
|
||||
--> $DIR/const_drop_is_valid.rs:6:12
|
||||
|
|
||||
@ -39,7 +34,7 @@ LL | impl const Drop for A {}
|
||||
|
|
||||
= help: implement the missing item: `fn drop(&mut self) { todo!() }`
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0046, E0658.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
|
@ -1,8 +1,3 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
|
||||
--> $DIR/safe-intrinsic-mismatch.rs:11:5
|
||||
|
|
||||
@ -47,6 +42,6 @@ LL | const fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
|
||||
= note: expected signature `unsafe fn(_, _, _)`
|
||||
found signature `fn(_, _, _)`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -7,11 +7,6 @@ LL | #![feature(const_trait_impl, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: `~const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-bounds-non-const-trait.rs:6:21
|
||||
|
|
||||
@ -32,5 +27,5 @@ error: `const` can only be applied to `#[const_trait]` traits
|
||||
LL | fn operate<T: const NonConst>() {}
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
|
@ -48,6 +48,30 @@ LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
|
||||
--> $DIR/const-drop.rs:67:46
|
||||
|
|
||||
LL | impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `t::ConstDropWithBound`
|
||||
--> $DIR/const-drop.rs:65:38
|
||||
|
|
||||
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
|
||||
| ^^^^^ required by this bound in `ConstDropWithBound`
|
||||
|
||||
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
|
||||
--> $DIR/const-drop.rs:68:22
|
||||
|
|
||||
LL | fn drop(&mut self) {
|
||||
| ^^^^
|
||||
|
|
||||
note: required by a bound in `t::ConstDropWithBound`
|
||||
--> $DIR/const-drop.rs:65:38
|
||||
|
|
||||
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
|
||||
| ^^^^^ required by this bound in `ConstDropWithBound`
|
||||
|
||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||
--> $DIR/const-drop.rs:18:32
|
||||
|
|
||||
@ -66,7 +90,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||
LL + #![feature(effects)]
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0493.
|
||||
Some errors have detailed explanations: E0015, E0277, E0493.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -48,6 +48,30 @@ LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
|
||||
--> $DIR/const-drop.rs:67:46
|
||||
|
|
||||
LL | impl<T: ~const SomeTrait> const Drop for ConstDropWithBound<T> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `t::ConstDropWithBound`
|
||||
--> $DIR/const-drop.rs:65:38
|
||||
|
|
||||
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
|
||||
| ^^^^^ required by this bound in `ConstDropWithBound`
|
||||
|
||||
error[E0277]: the trait bound `T: const SomeTrait` is not satisfied
|
||||
--> $DIR/const-drop.rs:68:22
|
||||
|
|
||||
LL | fn drop(&mut self) {
|
||||
| ^^^^
|
||||
|
|
||||
note: required by a bound in `t::ConstDropWithBound`
|
||||
--> $DIR/const-drop.rs:65:38
|
||||
|
|
||||
LL | pub struct ConstDropWithBound<T: const SomeTrait>(pub core::marker::PhantomData<T>);
|
||||
| ^^^^^ required by this bound in `ConstDropWithBound`
|
||||
|
||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||
--> $DIR/const-drop.rs:18:32
|
||||
|
|
||||
@ -68,7 +92,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||
LL + #![feature(effects)]
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0493.
|
||||
Some errors have detailed explanations: E0015, E0277, E0493.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -7,11 +7,6 @@ LL | #![feature(derive_const, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
|
||||
--> $DIR/derive-const-non-const-type.rs:10:16
|
||||
|
|
||||
@ -33,6 +28,6 @@ LL | pub struct S(A);
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
@ -19,11 +19,6 @@ error[E0635]: unknown feature `const_default_impls`
|
||||
LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const, effects)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
|
||||
--> $DIR/derive-const-use.rs:7:12
|
||||
|
|
||||
@ -122,7 +117,7 @@ LL | pub struct S((), A);
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 13 previous errors; 1 warning emitted
|
||||
error: aborting due to 12 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0015, E0635.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -7,11 +7,6 @@ LL | #![feature(const_trait_impl, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
|
||||
--> $DIR/derive-const-with-params.rs:7:16
|
||||
|
|
||||
@ -43,6 +38,6 @@ LL | a == b
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
@ -17,11 +17,6 @@ LL | #![feature(const_trait_impl, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: `~const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
||||
|
|
||||
@ -54,7 +49,7 @@ LL | assert_eq!(first, &b'f');
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0015, E0658.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -23,4 +23,5 @@ const FOO: () = {
|
||||
//~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
|
||||
<() as Bar<false>>::bar();
|
||||
//~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
|
||||
//~| ERROR the trait bound `(): const Bar` is not satisfied
|
||||
};
|
||||
|
@ -7,11 +7,6 @@ LL | #![feature(const_trait_impl, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
|
||||
--> $DIR/no-explicit-const-params.rs:22:5
|
||||
|
|
||||
@ -40,6 +35,12 @@ note: trait defined here, with 0 generic parameters
|
||||
LL | trait Bar {
|
||||
| ^^^
|
||||
|
||||
error[E0277]: the trait bound `(): const Bar` is not satisfied
|
||||
--> $DIR/no-explicit-const-params.rs:24:5
|
||||
|
|
||||
LL | <() as Bar<false>>::bar();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
|
||||
--> $DIR/no-explicit-const-params.rs:15:5
|
||||
|
|
||||
@ -70,4 +71,5 @@ LL | trait Bar {
|
||||
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0107`.
|
||||
Some errors have detailed explanations: E0107, E0277.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
@ -17,11 +17,6 @@ LL | #![feature(effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/span-bug-issue-121418.rs:9:27
|
||||
|
|
||||
@ -44,7 +39,7 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>`
|
||||
--> $SRC_DIR/std/src/sync/mutex.rs:LL:COL
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -7,11 +7,6 @@ LL | #![feature(effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||
--> $DIR/spec-effectvar-ice.rs:11:15
|
||||
|
|
||||
@ -60,5 +55,5 @@ error: cannot specialize on trait `Specialize`
|
||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
|
@ -63,11 +63,6 @@ LL | #![feature(const_trait_impl, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0379`.
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -1,8 +1,3 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
|
||||
--> $DIR/ice-119717-constant-lifetime.rs:6:15
|
||||
|
|
||||
@ -32,7 +27,7 @@ help: try replacing `_` with the type in the corresponding trait method signatur
|
||||
LL | fn from_residual(t: T) -> T {
|
||||
| ~
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0121, E0210.
|
||||
For more information about an error, try `rustc --explain E0121`.
|
||||
|
@ -55,11 +55,6 @@ LL | #![feature(effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error[E0425]: cannot find function `main8` in this scope
|
||||
--> $DIR/ice-120503-async-const-method.rs:12:9
|
||||
|
|
||||
@ -69,7 +64,7 @@ LL | main8().await;
|
||||
LL | fn main() {}
|
||||
| --------- similarly named function `main` defined here
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0379, E0407, E0425.
|
||||
For more information about an error, try `rustc --explain E0379`.
|
||||
|
@ -23,11 +23,6 @@ LL | #![feature(const_trait_impl, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0379`.
|
||||
|
@ -1,8 +1,3 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: `~const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/ice-123664-unexpected-bound-var.rs:4:27
|
||||
|
|
||||
@ -17,5 +12,5 @@ LL | const fn with_positive<F: ~const Fn()>() {}
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,8 +1,3 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Foo` for type `i32`
|
||||
--> $DIR/ice-124857-combine-effect-const-infer-vars.rs:11:1
|
||||
|
|
||||
@ -12,6 +7,6 @@ LL |
|
||||
LL | impl<T> const Foo for T where T: ~const Foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
|
@ -1,8 +1,3 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]`
|
||||
--> $DIR/ice-126148-failed-to-normalize.rs:8:12
|
||||
|
|
||||
@ -54,7 +49,7 @@ LL | TryMe?;
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0046.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -1,8 +1,3 @@
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `req`
|
||||
--> $DIR/impl-with-default-fn-fail.rs:13:1
|
||||
|
|
||||
@ -12,6 +7,6 @@ LL | fn req(&self);
|
||||
LL | impl const Tr for u16 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0046`.
|
||||
|
@ -7,16 +7,11 @@ LL | #![feature(const_trait_impl, effects)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: cannot specialize on const impl with non-const impl
|
||||
--> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1
|
||||
|
|
||||
LL | impl Value for FortyTwo {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
|
@ -7,16 +7,11 @@ LL | #![feature(const_trait_impl, effects, min_specialization, rustc_attrs)]
|
||||
= note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
|
||||
error: cannot specialize on const impl with non-const impl
|
||||
--> $DIR/specializing-constness.rs:23:1
|
||||
|
|
||||
LL | impl<T: Spec + Sup> A for T {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
|
@ -8,6 +8,7 @@ struct Foo<const N: usize>;
|
||||
impl<const N: usize> Foo<N> {
|
||||
fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
|
||||
//~^ ERROR `~const` is not allowed here
|
||||
//~| ERROR the trait bound `A: const Add42` is not satisfied
|
||||
Foo
|
||||
}
|
||||
}
|
||||
@ -25,6 +26,7 @@ impl const Add42 for () {
|
||||
|
||||
fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
//~^ ERROR `~const` is not allowed here
|
||||
//~| ERROR the trait bound `A: const Add42` is not satisfied
|
||||
Foo
|
||||
}
|
||||
|
||||
|
@ -11,21 +11,29 @@ LL | fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
|
||||
| ^^^
|
||||
|
||||
error: `~const` is not allowed here
|
||||
--> $DIR/tilde-const-and-const-params.rs:26:11
|
||||
--> $DIR/tilde-const-and-const-params.rs:27:11
|
||||
|
|
||||
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
| ^^^^^^
|
||||
|
|
||||
note: this function is not `const`, so it cannot have `~const` trait bounds
|
||||
--> $DIR/tilde-const-and-const-params.rs:26:4
|
||||
--> $DIR/tilde-const-and-const-params.rs:27:4
|
||||
|
|
||||
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
| ^^^
|
||||
|
||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||
error[E0277]: the trait bound `A: const Add42` is not satisfied
|
||||
--> $DIR/tilde-const-and-const-params.rs:27:61
|
||||
|
|
||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||
= help: use `-Znext-solver` to enable
|
||||
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0277]: the trait bound `A: const Add42` is not satisfied
|
||||
--> $DIR/tilde-const-and-const-params.rs:9:44
|
||||
|
|
||||
LL | fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -725,9 +725,6 @@ please modify the tool then regenerate the library source file with the tool
|
||||
instead of editing the library source file manually.
|
||||
"""
|
||||
|
||||
[mentions."src/librustdoc/clean/types.rs"]
|
||||
cc = ["@camelid"]
|
||||
|
||||
[mentions."src/librustdoc/html/static"]
|
||||
message = "Some changes occurred in HTML/CSS/JS."
|
||||
cc = [
|
||||
@ -938,9 +935,6 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
|
||||
[mentions."tests/ui/stack-protector"]
|
||||
cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
|
||||
|
||||
[mentions."tests/ui/check-cfg"]
|
||||
cc = ["@Urgau"]
|
||||
|
||||
[mentions."compiler/rustc_middle/src/mir/coverage.rs"]
|
||||
message = "Some changes occurred in coverage instrumentation."
|
||||
cc = ["@Zalathar"]
|
||||
|
Loading…
Reference in New Issue
Block a user