diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 9325d4c413941..9079e26eb509e 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -273,7 +273,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { if !generic_args.parenthesized && !has_lifetimes { generic_args.args = self .elided_path_lifetimes( - first_generic_span.map(|s| s.shrink_to_lo()).unwrap_or(segment.ident.span), + first_generic_span.map_or(segment.ident.span, |s| s.shrink_to_lo()), expected_lifetimes, ) .map(GenericArg::Lifetime) diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index d65bc820f8fb1..7bd805f91c857 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -370,7 +370,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!( &self, negative_impls, - span.to(of_trait.as_ref().map(|t| t.path.span).unwrap_or(span)), + span.to(of_trait.as_ref().map_or(span, |t| t.path.span)), "negative trait bounds are not yet fully implemented; \ use marker types for now" ); diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 68f319ade1e79..e225730dce061 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1002,8 +1002,7 @@ pub unsafe fn with_llvm_pmb( // reasonable defaults and prepare it to actually populate the pass // manager. let builder = llvm::LLVMPassManagerBuilderCreate(); - let opt_size = - config.opt_size.map(|x| to_llvm_opt_settings(x).1).unwrap_or(llvm::CodeGenOptSizeNone); + let opt_size = config.opt_size.map_or(llvm::CodeGenOptSizeNone, |x| to_llvm_opt_settings(x).1); let inline_threshold = config.inline_threshold; let pgo_gen_path = get_pgo_gen_path(config); let pgo_use_path = get_pgo_use_path(config); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index ccbe7325cc6c2..955e739b2c126 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -552,7 +552,6 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation( - utils::debug_context(self).llcontext, line.unwrap_or(UNKNOWN_LINE_NUMBER), col.unwrap_or(UNKNOWN_COLUMN_NUMBER), scope, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index e359d9f8c9c77..eb4f36266dbae 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2102,7 +2102,6 @@ extern "C" { ); pub fn LLVMRustDIBuilderCreateDebugLocation( - Context: &'a Context, Line: c_uint, Column: c_uint, Scope: &'a DIScope, diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 728795cf50b85..ff77db9eab852 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -166,7 +166,7 @@ fn get_linker( _ => match flavor { LinkerFlavor::Lld(f) => Command::lld(linker, f), LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => { - Command::new(msvc_tool.as_ref().map(|t| t.path()).unwrap_or(linker)) + Command::new(msvc_tool.as_ref().map_or(linker, |t| t.path())) } _ => Command::new(linker), }, diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 5d13b7f27c704..b16d5a9e2b421 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -166,7 +166,7 @@ impl SelfProfilerRef { // If there is no SelfProfiler then the filter mask is set to NONE, // ensuring that nothing ever tries to actually access it. let event_filter_mask = - profiler.as_ref().map(|p| p.event_filter_mask).unwrap_or(EventFilter::empty()); + profiler.as_ref().map_or(EventFilter::empty(), |p| p.event_filter_mask); SelfProfilerRef { profiler, diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 509f81e16536b..15b984acac590 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -798,7 +798,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) { println!("commit-date: {}", unw(util::commit_date_str())); println!("host: {}", config::host_triple()); println!("release: {}", unw(util::release_str())); - if cfg!(llvm) { + if cfg!(feature = "llvm") { get_builtin_codegen_backend("llvm")().print_version(); } } @@ -1087,7 +1087,7 @@ pub fn handle_options(args: &[String]) -> Option { } if cg_flags.iter().any(|x| *x == "passes=list") { - if cfg!(llvm) { + if cfg!(feature = "llvm") { get_builtin_codegen_backend("llvm")().print_passes(); } return None; @@ -1236,7 +1236,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { } // If backtraces are enabled, also print the query stack - let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false); + let backtrace = env::var_os("RUST_BACKTRACE").map_or(false, |x| &x != "0"); let num_frames = if backtrace { None } else { Some(2) }; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 593e0d92031ff..e184e929b0745 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -804,7 +804,7 @@ impl HandlerInner { } fn treat_err_as_bug(&self) -> bool { - self.flags.treat_err_as_bug.map(|c| self.err_count() >= c).unwrap_or(false) + self.flags.treat_err_as_bug.map_or(false, |c| self.err_count() >= c) } fn print_error_count(&mut self, registry: &Registry) { @@ -913,7 +913,7 @@ impl HandlerInner { // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before // incrementing `err_count` by one, so we need to +1 the comparing. // FIXME: Would be nice to increment err_count in a more coherent way. - if self.flags.treat_err_as_bug.map(|c| self.err_count() + 1 >= c).unwrap_or(false) { + if self.flags.treat_err_as_bug.map_or(false, |c| self.err_count() + 1 >= c) { // FIXME: don't abort here if report_delayed_bugs is off self.span_bug(sp, msg); } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 1193f66651ce9..b07bce94870c1 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -423,7 +423,7 @@ impl<'a> StripUnconfigured<'a> { /// If attributes are not allowed on expressions, emit an error for `attr` pub fn maybe_emit_expr_attr_err(&self, attr: &Attribute) { - if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) { + if !self.features.map_or(true, |features| features.stmt_expr_attributes) { let mut err = feature_err( &self.sess.parse_sess, sym::stmt_expr_attributes, diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index e76cc6f1fed7b..1aed42a24e2b3 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -500,7 +500,7 @@ fn inner_parse_loop<'root, 'tt>( if idx == len && item.sep.is_some() { // We have a separator, and it is the current token. We can advance past the // separator token. - if item.sep.as_ref().map(|sep| token_name_eq(token, sep)).unwrap_or(false) { + if item.sep.as_ref().map_or(false, |sep| token_name_eq(token, sep)) { item.idx += 1; next_items.push(item); } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 3d126749d541d..8373304ea9134 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -203,7 +203,7 @@ fn macro_rules_dummy_expander<'cx>( } fn trace_macros_note(cx_expansions: &mut FxHashMap>, sp: Span, message: String) { - let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); + let sp = sp.macro_backtrace().last().map_or(sp, |trace| trace.call_site); cx_expansions.entry(sp).or_default().push(message); } diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index a4b44931fc1ae..c8049495d223c 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -99,10 +99,10 @@ pub(super) fn parse( } _ => token.span, }, - tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), + tree => tree.as_ref().map_or(span, tokenstream::TokenTree::span), } } - tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp), + tree => tree.as_ref().map_or(start_sp, tokenstream::TokenTree::span), }; if node_id != DUMMY_NODE_ID { // Macros loaded from other crates have dummy node ids. @@ -250,7 +250,7 @@ fn parse_kleene_op( Some(op) => Ok(Ok((op, token.span))), None => Ok(Err(token)), }, - tree => Err(tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span)), + tree => Err(tree.as_ref().map_or(span, tokenstream::TokenTree::span)), } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 269916390ed45..5c3c1591b1ce5 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -561,7 +561,7 @@ impl WhereClause<'_> { /// in `fn foo(t: T) where T: Foo,` so we don't suggest two trailing commas. pub fn tail_span_for_suggestion(&self) -> Span { let end = self.span_for_predicates_or_empty_place().shrink_to_hi(); - self.predicates.last().map(|p| p.span()).unwrap_or(end).shrink_to_hi().to(end) + self.predicates.last().map_or(end, |p| p.span()).shrink_to_hi().to(end) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 5d56744805f89..fee6f87ae42c3 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2118,7 +2118,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let consider = format!( "{} {}...", msg, - if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) { + if type_param_span.map_or(false, |(_, _, is_impl_trait)| is_impl_trait) { format!(" `{}` to `{}`", sub, bound_kind) } else { format!("`{}: {}`", bound_kind, sub) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 56d9634213ae5..27545c126857b 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1533,7 +1533,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Note: if these two lines are combined into one we get // dynamic borrow errors on `self.inner`. let known = self.inner.borrow_mut().type_variables().probe(v).known(); - known.map(|t| self.shallow_resolve_ty(t)).unwrap_or(typ) + known.map_or(typ, |t| self.shallow_resolve_ty(t)) } ty::Infer(ty::IntVar(v)) => self diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 9ad9d53cd0db3..424f91b3f883e 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -647,8 +647,7 @@ pub fn transparent_newtype_field<'a, 'tcx>( let param_env = tcx.param_env(variant.def_id); for field in &variant.fields { let field_ty = tcx.type_of(field.did); - let is_zst = - tcx.layout_of(param_env.and(field_ty)).map(|layout| layout.is_zst()).unwrap_or(false); + let is_zst = tcx.layout_of(param_env.and(field_ty)).map_or(false, |layout| layout.is_zst()); if !is_zst { return Some(field); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 35915dc7a9753..bc7363a69a6e8 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -529,8 +529,8 @@ trait UnusedDelimLint { pprust::expr_to_string(value) }; let keep_space = ( - left_pos.map(|s| s >= value.span.lo()).unwrap_or(false), - right_pos.map(|s| s <= value.span.hi()).unwrap_or(false), + left_pos.map_or(false, |s| s >= value.span.lo()), + right_pos.map_or(false, |s| s <= value.span.hi()), ); self.emit_unused_delims(cx, value.span, &expr_text, ctx.into(), keep_space); } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index c0ff62c17beb5..1d6f00562f136 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -994,11 +994,9 @@ LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder, } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line, - unsigned Column, LLVMMetadataRef Scope, +LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column, + LLVMMetadataRef Scope, LLVMMetadataRef InlinedAt) { - LLVMContext &Context = *unwrap(ContextRef); - DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr(Scope), unwrapDIPtr(InlinedAt)); diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 6d876784be653..d264462bf0895 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -429,7 +429,7 @@ fn add_query_description_impl( }; let (tcx, desc) = modifiers.desc; - let tcx = tcx.as_ref().map(|t| quote! { #t }).unwrap_or(quote! { _ }); + let tcx = tcx.as_ref().map_or(quote! { _ }, |t| quote! { #t }); let desc = quote! { #[allow(unused_variables)] diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 019ca5174a223..a7bf79d7e6743 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -326,7 +326,7 @@ impl<'a> CrateLoader<'a> { self.verify_no_symbol_conflicts(&crate_root)?; let private_dep = - self.sess.opts.externs.get(&name.as_str()).map(|e| e.is_private_dep).unwrap_or(false); + self.sess.opts.externs.get(&name.as_str()).map_or(false, |e| e.is_private_dep); // Claim this crate number and cache it let cnum = self.cstore.alloc_new_crate_num(); diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 5b33678b25ae2..8d0994320e383 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -132,7 +132,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { impl Collector<'tcx> { fn register_native_lib(&mut self, span: Option, lib: NativeLib) { - if lib.name.as_ref().map(|&s| s == kw::Empty).unwrap_or(false) { + if lib.name.as_ref().map_or(false, |&s| s == kw::Empty) { match span { Some(span) => { struct_span_err!( diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 209d1838e3ebc..2568af23ef506 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -813,7 +813,7 @@ impl<'hir> Map<'hir> { /// Given a node ID, gets a list of attributes associated with the AST /// corresponding to the node-ID. pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] { - let attrs = self.find_entry(id).map(|entry| match entry.node { + self.find_entry(id).map_or(&[], |entry| match entry.node { Node::Param(a) => &a.attrs[..], Node::Local(l) => &l.attrs[..], Node::Item(i) => &i.attrs[..], @@ -840,8 +840,7 @@ impl<'hir> Map<'hir> { | Node::Block(..) | Node::Lifetime(..) | Node::Visibility(..) => &[], - }); - attrs.unwrap_or(&[]) + }) } /// Gets the span of the definition of the specified HIR node. diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ecf2837b3e423..a2638d8bddad0 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -82,7 +82,7 @@ impl<'tcx> ConstKind<'tcx> { /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the /// unevaluated constant. pub fn eval(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self { - self.try_eval(tcx, param_env).and_then(Result::ok).map(ConstKind::Value).unwrap_or(self) + self.try_eval(tcx, param_env).and_then(Result::ok).map_or(self, ConstKind::Value) } #[inline] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3540f0f06b6e6..c3ad4c1c126d2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1338,7 +1338,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn serialize_query_result_cache(self, encoder: &mut FileEncoder) -> FileEncodeResult { - self.queries.on_disk_cache.as_ref().map(|c| c.serialize(self, encoder)).unwrap_or(Ok(())) + self.queries.on_disk_cache.as_ref().map_or(Ok(()), |c| c.serialize(self, encoder)) } /// If `true`, we should use the MIR-based borrowck, but also @@ -2601,7 +2601,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn is_late_bound(self, id: HirId) -> bool { - self.is_late_bound_map(id.owner).map(|set| set.contains(&id.local_id)).unwrap_or(false) + self.is_late_bound_map(id.owner).map_or(false, |set| set.contains(&id.local_id)) } pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 413c9cca589d9..6ca5dcc532d22 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -535,7 +535,7 @@ fn polymorphize<'tcx>( } else { None }; - let has_upvars = upvars_ty.map(|ty| ty.tuple_fields().count() > 0).unwrap_or(false); + let has_upvars = upvars_ty.map_or(false, |ty| ty.tuple_fields().count() > 0); debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars); struct PolymorphizationFolder<'tcx> { diff --git a/compiler/rustc_mir/src/borrow_check/borrow_set.rs b/compiler/rustc_mir/src/borrow_check/borrow_set.rs index b4299fbc5a1fe..288eda32e414e 100644 --- a/compiler/rustc_mir/src/borrow_check/borrow_set.rs +++ b/compiler/rustc_mir/src/borrow_check/borrow_set.rs @@ -149,7 +149,7 @@ impl<'tcx> BorrowSet<'tcx> { } crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] { - self.activation_map.get(&location).map(|activations| &activations[..]).unwrap_or(&[]) + self.activation_map.get(&location).map_or(&[], |activations| &activations[..]) } crate fn len(&self) -> usize { diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs index eccb6168229c2..a3d09c3a8d4c1 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs @@ -75,7 +75,7 @@ impl BorrowExplanation { LaterUseKind::FakeLetRead => "stored here", LaterUseKind::Other => "used here", }; - if !borrow_span.map(|sp| sp.overlaps(var_or_use_span)).unwrap_or(false) { + if !borrow_span.map_or(false, |sp| sp.overlaps(var_or_use_span)) { err.span_label( var_or_use_span, format!("{}borrow later {}", borrow_desc, message), diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 6d7781671d8cc..7e9594dd6bfd7 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -370,7 +370,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { #[inline(always)] pub fn cur_span(&self) -> Span { - self.stack().last().map(|f| f.current_span()).unwrap_or(self.tcx.span) + self.stack().last().map_or(self.tcx.span, |f| f.current_span()) } #[inline(always)] diff --git a/compiler/rustc_mir/src/interpret/util.rs b/compiler/rustc_mir/src/interpret/util.rs index c2165db278fa0..89f34cd07aa4b 100644 --- a/compiler/rustc_mir/src/interpret/util.rs +++ b/compiler/rustc_mir/src/interpret/util.rs @@ -47,8 +47,7 @@ where let index = index .try_into() .expect("more generic parameters than can fit into a `u32`"); - let is_used = - unused_params.contains(index).map(|unused| !unused).unwrap_or(true); + let is_used = unused_params.contains(index).map_or(true, |unused| !unused); // Only recurse when generic parameters in fns, closures and generators // are used and require substitution. match (is_used, subst.needs_subst()) { diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index a8f2b4d60e140..75f80f69beafc 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -823,7 +823,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> } if !tcx.is_mir_available(def_id) { - bug!("cannot create local mono-item for {:?}", def_id) + bug!("no MIR available for {:?}", def_id); } true diff --git a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs index db6d3b2d912d6..b9fcd32250dcf 100644 --- a/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs +++ b/compiler/rustc_mir/src/monomorphize/partitioning/mod.rs @@ -247,8 +247,7 @@ where for (mono_item, linkage) in cgu.items() { let symbol_name = mono_item.symbol_name(tcx).name; let symbol_hash_start = symbol_name.rfind('h'); - let symbol_hash = - symbol_hash_start.map(|i| &symbol_name[i..]).unwrap_or(""); + let symbol_hash = symbol_hash_start.map_or("", |i| &symbol_name[i..]); debug!( " - {} [{:?}] [{}] estimated size {}", diff --git a/compiler/rustc_mir/src/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs index a3459887a9a75..05a88828070fb 100644 --- a/compiler/rustc_mir/src/transform/simplify_try.rs +++ b/compiler/rustc_mir/src/transform/simplify_try.rs @@ -113,7 +113,7 @@ fn get_arm_identity_info<'a, 'tcx>( test: impl Fn(&'a Statement<'tcx>) -> bool, mut action: impl FnMut(usize, &'a Statement<'tcx>), ) { - while stmt_iter.peek().map(|(_, stmt)| test(stmt)).unwrap_or(false) { + while stmt_iter.peek().map_or(false, |(_, stmt)| test(stmt)) { let (idx, stmt) = stmt_iter.next().unwrap(); action(idx, stmt); @@ -635,7 +635,7 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> { }) .peekable(); - let bb_first = iter_bbs_reachable.peek().map(|(idx, _)| *idx).unwrap_or(&targets_and_values[0]); + let bb_first = iter_bbs_reachable.peek().map_or(&targets_and_values[0], |(idx, _)| *idx); let mut all_successors_equivalent = StatementEquality::TrivialEqual; // All successor basic blocks must be equal or contain statements that are pairwise considered equal. diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 83fee380ccce7..d7c08a2d1af6b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -952,7 +952,7 @@ fn is_useful<'p, 'tcx>( assert!(rows.iter().all(|r| r.len() == v.len())); // FIXME(Nadrieril): Hack to work around type normalization issues (see #72476). - let ty = matrix.heads().next().map(|r| r.ty).unwrap_or(v.head().ty); + let ty = matrix.heads().next().map_or(v.head().ty, |r| r.ty); let pcx = PatCtxt { cx, ty, span: v.head().span, is_top_level }; debug!("is_useful_expand_first_col: ty={:#?}, expanding {:#?}", pcx.ty, v.head()); diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 98c7b9a63a55f..35435baea7019 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -511,7 +511,7 @@ impl<'a> Parser<'a> { // // `x.foo::>>(3)` let parsed_angle_bracket_args = - segment.args.as_ref().map(|args| args.is_angle_bracketed()).unwrap_or(false); + segment.args.as_ref().map_or(false, |args| args.is_angle_bracketed()); debug!( "check_trailing_angle_brackets: parsed_angle_bracket_args={:?}", diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 25e3e67e28e6c..f7b16bd991bfd 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -347,7 +347,7 @@ impl<'a> Parser<'a> { let mut pos = pos; // This handles the raw string case, the raw argument is the number of # // in r###"..."### (we need to add one because of the `r`). - let raw = self.style.map(|raw| raw + 1).unwrap_or(0); + let raw = self.style.map_or(0, |raw| raw + 1); for skip in &self.skips { if pos > *skip { pos += 1; @@ -814,7 +814,7 @@ fn find_skips_from_snippet( skips } - let r_start = str_style.map(|r| r + 1).unwrap_or(0); + let r_start = str_style.map_or(0, |r| r + 1); let r_end = str_style.unwrap_or(0); let s = &snippet[r_start + 1..snippet.len() - r_end - 1]; (find_skips(s, str_style.is_some()), true) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 605d7ae4af678..151e056a5b356 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -953,7 +953,7 @@ impl DepGraph { // Returns true if the given node has been marked as green during the // current compilation session. Used in various assertions pub fn is_green(&self, dep_node: &DepNode) -> bool { - self.node_color(dep_node).map(|c| c.is_green()).unwrap_or(false) + self.node_color(dep_node).map_or(false, |c| c.is_green()) } // This method loads all on-disk cacheable query results into memory, so diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6219d1b08eb68..9de35a8006123 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1925,7 +1925,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { { // Check if we wrote `str::from_utf8` instead of `std::str::from_utf8` let item_span = - path.iter().last().map(|segment| segment.ident.span).unwrap_or(span); + path.iter().last().map_or(span, |segment| segment.ident.span); let mut hm = self.r.session.confused_type_with_std_module.borrow_mut(); hm.insert(item_span, span); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 55623c9bd9cf6..3945afb4724a8 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -264,7 +264,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { // The current function has a `self' parameter, but we were unable to resolve // a reference to `self`. This can only happen if the `self` identifier we // are resolving came from a different hygiene context. - if fn_kind.decl().inputs.get(0).map(|p| p.is_self()).unwrap_or(false) { + if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) { err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters"); } else { let doesnt = if is_assoc_fn { @@ -1452,8 +1452,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } else { let needs_placeholder = |def_id: DefId, kind: CtorKind| { - let has_no_fields = - self.r.field_names.get(&def_id).map(|f| f.is_empty()).unwrap_or(false); + let has_no_fields = self.r.field_names.get(&def_id).map_or(false, |f| f.is_empty()); match kind { CtorKind::Const => false, CtorKind::Fn | CtorKind::Fictive if has_no_fields => false, diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index cc0e99dc6b10c..aab5c3cf8f59d 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -644,17 +644,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } else { bug!(); }; - if let hir::ParamName::Plain(param_name) = name { - if param_name.name == kw::UnderscoreLifetime { - // Pick the elided lifetime "definition" if one exists - // and use it to make an elision scope. - self.lifetime_uses.insert(def_id, LifetimeUseSet::Many); - elision = Some(reg); - } else { - lifetimes.insert(name, reg); - } + // We cannot predict what lifetimes are unused in opaque type. + self.lifetime_uses.insert(def_id, LifetimeUseSet::Many); + if let hir::ParamName::Plain(Ident { + name: kw::UnderscoreLifetime, + .. + }) = name + { + // Pick the elided lifetime "definition" if one exists + // and use it to make an elision scope. + elision = Some(reg); } else { - self.lifetime_uses.insert(def_id, LifetimeUseSet::Many); lifetimes.insert(name, reg); } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index fb364053e241e..c5b8f7d647ca7 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1052,7 +1052,7 @@ pub struct ResolverArenas<'a> { impl<'a> ResolverArenas<'a> { fn alloc_module(&'a self, module: ModuleData<'a>) -> Module<'a> { let module = self.modules.alloc(module); - if module.def_id().map(|def_id| def_id.is_local()).unwrap_or(true) { + if module.def_id().map_or(true, |def_id| def_id.is_local()) { self.local_modules.borrow_mut().push(module); } module @@ -3031,7 +3031,7 @@ impl<'a> Resolver<'a> { let duplicate = new_binding.res().opt_def_id() == old_binding.res().opt_def_id(); let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy(); let from_item = - self.extern_prelude.get(&ident).map(|entry| entry.introduced_by_item).unwrap_or(true); + self.extern_prelude.get(&ident).map_or(true, |entry| entry.introduced_by_item); // Only suggest removing an import if both bindings are to the same def, if both spans // aren't dummy spans. Further, if both bindings are imports, then the ident must have // been introduced by a item. diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index c8cdff4f7e5d3..129123349a028 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -670,7 +670,7 @@ impl<'tcx> SaveContext<'tcx> { ) -> Option { // Returns true if the path is function type sugar, e.g., `Fn(A) -> B`. fn fn_type(seg: &hir::PathSegment<'_>) -> bool { - seg.args.map(|args| args.parenthesized).unwrap_or(false) + seg.args.map_or(false, |args| args.parenthesized) } let res = self.get_path_res(id); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 1f9a1af0f6872..6d01854228662 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1358,7 +1358,7 @@ pub fn build_session( let optimization_fuel_crate = sopts.debugging_opts.fuel.as_ref().map(|i| i.0.clone()); let optimization_fuel = Lock::new(OptimizationFuel { - remaining: sopts.debugging_opts.fuel.as_ref().map(|i| i.1).unwrap_or(0), + remaining: sopts.debugging_opts.fuel.as_ref().map_or(0, |i| i.1), out_of_fuel: false, }); let print_fuel_crate = sopts.debugging_opts.print_fuel.clone(); diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 842ccda6ea8b0..4e0ce0d344de4 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -539,7 +539,7 @@ impl SourceMap { pub fn is_line_before_span_empty(&self, sp: Span) -> bool { match self.span_to_prev_source(sp) { - Ok(s) => s.split('\n').last().map(|l| l.trim_start().is_empty()).unwrap_or(false), + Ok(s) => s.split('\n').last().map_or(false, |l| l.trim_start().is_empty()), Err(_) => false, } } @@ -568,7 +568,7 @@ impl SourceMap { // asserting that the line numbers here are all indeed 1-based. let hi_line = hi.line.saturating_sub(1); for line_index in lo.line.saturating_sub(1)..hi_line { - let line_len = lo.file.get_line(line_index).map(|s| s.chars().count()).unwrap_or(0); + let line_len = lo.file.get_line(line_index).map_or(0, |s| s.chars().count()); lines.push(LineInfo { line_index, start_col, end_col: CharPos::from_usize(line_len) }); start_col = CharPos::from_usize(0); } diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs index b8459eee4ecf0..3f22829b049fe 100644 --- a/compiler/rustc_span/src/source_map/tests.rs +++ b/compiler/rustc_span/src/source_map/tests.rs @@ -107,7 +107,7 @@ fn t7() { fn span_from_selection(input: &str, selection: &str) -> Span { assert_eq!(input.len(), selection.len()); let left_index = selection.find('~').unwrap() as u32; - let right_index = selection.rfind('~').map(|x| x as u32).unwrap_or(left_index); + let right_index = selection.rfind('~').map_or(left_index, |x| x as u32); Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1)) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 0186d164a4c53..795cf2e19decc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -830,7 +830,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .collect::>(), ), Node::Ctor(ref variant_data) => { - let span = variant_data.ctor_hir_id().map(|id| hir.span(id)).unwrap_or(DUMMY_SP); + let span = variant_data.ctor_hir_id().map_or(DUMMY_SP, |id| hir.span(id)); let span = sm.guess_head_span(span); (span, vec![ArgKind::empty(); variant_data.fields().len()]) } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index f1fb2b800232d..8e339eb26b26c 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -1259,8 +1259,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty let layout = tcx.layout_of(param_env.and(ty)); // We are currently checking the type this field came from, so it must be local let span = tcx.hir().span_if_local(field.did).unwrap(); - let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false); - let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false); + let zst = layout.map_or(false, |layout| layout.is_zst()); + let align1 = layout.map_or(false, |layout| layout.align.abi.bytes() == 1); (span, zst, align1) }); diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 320ded5334e21..0036edda36da5 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -364,13 +364,14 @@ fn check_region_bounds_on_impl_item<'tcx>( if trait_params != impl_params { let item_kind = assoc_item_kind_str(impl_m); let def_span = tcx.sess.source_map().guess_head_span(span); - let span = tcx.hir().get_generics(impl_m.def_id).map(|g| g.span).unwrap_or(def_span); + let span = tcx.hir().get_generics(impl_m.def_id).map_or(def_span, |g| g.span); let generics_span = if let Some(sp) = tcx.hir().span_if_local(trait_m.def_id) { let def_sp = tcx.sess.source_map().guess_head_span(sp); - Some(tcx.hir().get_generics(trait_m.def_id).map(|g| g.span).unwrap_or(def_sp)) + Some(tcx.hir().get_generics(trait_m.def_id).map_or(def_sp, |g| g.span)) } else { None }; + tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait { span, item_kind, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index c3166ce8164f4..47799c95fc0a7 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -904,8 +904,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // Return directly on cache hit. This is useful to avoid doubly reporting // errors with default match binding modes. See #44614. - let def = - cached_result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err); + let def = cached_result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)); return (def, Some(ty), slice::from_ref(&**item_segment)); } let item_name = item_segment.ident; @@ -932,7 +931,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Write back the new resolution. self.write_resolution(hir_id, result); ( - result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), + result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), Some(ty), slice::from_ref(&**item_segment), ) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 94f8bfa3fc04b..ba944599653fa 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -821,7 +821,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(match &arm.body.kind { // Point at the tail expression when possible. hir::ExprKind::Block(block, _) => { - block.expr.as_ref().map(|e| e.span).unwrap_or(block.span) + block.expr.as_ref().map_or(block.span, |e| e.span) } _ => arm.body.span, }) @@ -882,7 +882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Write back the new resolution. self.write_resolution(hir_id, result); - (result.map(|(kind, def_id)| Res::Def(kind, def_id)).unwrap_or(Res::Err), ty) + (result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty) } QPath::LangItem(lang_item, span) => { self.resolve_lang_item_path(lang_item, span, hir_id) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 5cfd78ebeacad..e6bfa5e1497fe 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1193,7 +1193,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .any(|imp_did| { let imp = self.tcx.impl_trait_ref(imp_did).unwrap(); let imp_simp = simplify_type(self.tcx, imp.self_ty(), true); - imp_simp.map(|s| s == simp_rcvr_ty).unwrap_or(false) + imp_simp.map_or(false, |s| s == simp_rcvr_ty) }) { explicitly_negative.push(candidate); @@ -1270,11 +1270,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match ty.kind() { ty::Adt(def, _) => def.did.is_local(), ty::Foreign(did) => did.is_local(), - - ty::Dynamic(ref tr, ..) => { - tr.principal().map(|d| d.def_id().is_local()).unwrap_or(false) - } - + ty::Dynamic(ref tr, ..) => tr.principal().map_or(false, |d| d.def_id().is_local()), ty::Param(_) => true, // Everything else (primitive types, etc.) is effectively diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index fc3dff2654257..2c720ce025b0b 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -108,7 +108,7 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) { .impl_trait_ref(tcx.hir().local_def_id(item.hir_id)) .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) { - let sp = impl_.of_trait.as_ref().map(|t| t.path.span).unwrap_or(item.span); + let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span); let mut err = tcx.sess.struct_span_err(sp, "impls of auto traits cannot be default"); err.span_labels(impl_.defaultness_span, "default because of this"); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1626a0116a7eb..a6677328f8f88 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1656,7 +1656,7 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity { .. }) => { if is_rustc_reservation { - let span = span.to(of_trait.as_ref().map(|t| t.path.span).unwrap_or(*span)); + let span = span.to(of_trait.as_ref().map_or(*span, |t| t.path.span)); tcx.sess.span_err(span, "reservation impls can't be negative"); } ty::ImplPolarity::Negative diff --git a/compiler/rustc_typeck/src/mem_categorization.rs b/compiler/rustc_typeck/src/mem_categorization.rs index a601123c8d055..4f11594d39813 100644 --- a/compiler/rustc_typeck/src/mem_categorization.rs +++ b/compiler/rustc_typeck/src/mem_categorization.rs @@ -653,9 +653,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { // Then we see that to get the same result, we must start with // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)` // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`. - for _ in - 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map(|v| v.len()).unwrap_or(0) - { + for _ in 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) { debug!("cat_pattern: applying adjustment to place_with_id={:?}", place_with_id); place_with_id = self.cat_deref(pat, place_with_id)?; } diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 3d0635e3fe437..02008e180b34d 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -99,7 +99,7 @@ impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> { // we walk the crates again and re-calculate predicates for all // items. let item_predicates_len: usize = - self.global_inferred_outlives.get(&item_did.to_def_id()).map(|p| p.len()).unwrap_or(0); + self.global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len()); if item_required_predicates.len() > item_predicates_len { *self.predicates_added = true; self.global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates); diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index f8fad6de1a3cc..5b61e8911a59a 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1292,7 +1292,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn front(&self) -> Option<&T> { - if !self.is_empty() { Some(&self[0]) } else { None } + self.get(0) } /// Provides a mutable reference to the front element, or `None` if the @@ -1316,7 +1316,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { - if !self.is_empty() { Some(&mut self[0]) } else { None } + self.get_mut(0) } /// Provides a reference to the back element, or `None` if the `VecDeque` is @@ -1336,7 +1336,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { - if !self.is_empty() { Some(&self[self.len() - 1]) } else { None } + self.get(self.len().wrapping_sub(1)) } /// Provides a mutable reference to the back element, or `None` if the @@ -1360,8 +1360,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { - let len = self.len(); - if !self.is_empty() { Some(&mut self[len - 1]) } else { None } + self.get_mut(self.len().wrapping_sub(1)) } /// Removes the first element and returns it, or `None` if the `VecDeque` is diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs index e8e1e66da5ed4..5067af1d4ff68 100644 --- a/library/alloc/src/sync/tests.rs +++ b/library/alloc/src/sync/tests.rs @@ -370,7 +370,7 @@ fn test_weak_count_locked() { let n = Arc::weak_count(&a2); assert!(n < 2, "bad weak count: {}", n); #[cfg(miri)] // Miri's scheduler does not guarantee liveness, and thus needs this hint. - atomic::spin_loop_hint(); + std::hint::spin_loop(); } t.join().unwrap(); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 1ca194c336112..ccc4f03a1e505 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1953,27 +1953,6 @@ impl Vec { } } -impl Vec { - /// Removes the first instance of `item` from the vector if the item exists. - /// - /// This method will be removed soon. - #[unstable(feature = "vec_remove_item", reason = "recently added", issue = "40062")] - #[rustc_deprecated( - reason = "Removing the first item equal to a needle is already easily possible \ - with iterators and the current Vec methods. Furthermore, having a method for \ - one particular case of removal (linear search, only the first item, no swap remove) \ - but not for others is inconsistent. This method will be removed soon.", - since = "1.46.0" - )] - pub fn remove_item(&mut self, item: &V) -> Option - where - T: PartialEq, - { - let pos = self.iter().position(|x| *x == *item)?; - Some(self.remove(pos)) - } -} - //////////////////////////////////////////////////////////////////////////////// // Internal methods and functions //////////////////////////////////////////////////////////////////////////////// diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 0c65c1c9eb7e9..7e817edeec1ee 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -1555,7 +1555,7 @@ impl<'a> Formatter<'a> { /// } /// } /// - /// // We set alignment to the left with ">". + /// // We set alignment to the right with ">". /// assert_eq!(&format!("{:G>3}", Foo), "GGG"); /// assert_eq!(&format!("{:t>6}", Foo), "tttttt"); /// ``` diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index 1d67e65e51f5f..0571dc74b9af9 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -678,6 +678,29 @@ pub enum Bound { Unbounded, } +#[unstable(feature = "bound_as_ref", issue = "80996")] +impl Bound { + /// Converts from `&Bound` to `Bound<&T>`. + #[inline] + pub fn as_ref(&self) -> Bound<&T> { + match *self { + Included(ref x) => Included(x), + Excluded(ref x) => Excluded(x), + Unbounded => Unbounded, + } + } + + /// Converts from `&mut Bound` to `Bound<&T>`. + #[inline] + pub fn as_mut(&mut self) -> Bound<&mut T> { + match *self { + Included(ref mut x) => Included(x), + Excluded(ref mut x) => Excluded(x), + Unbounded => Unbounded, + } + } +} + impl Bound<&T> { /// Map a `Bound<&T>` to a `Bound` by cloning the contents of the bound. /// diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 081d80f487605..6de2714059480 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1877,7 +1877,7 @@ impl [T] { /// Some(b"llo".as_ref())); /// ``` #[must_use = "returns the subslice without modifying the original"] - #[stable(feature = "slice_strip", since = "1.50.0")] + #[stable(feature = "slice_strip", since = "1.51.0")] pub fn strip_prefix + ?Sized>(&self, prefix: &P) -> Option<&[T]> where T: PartialEq, @@ -1911,7 +1911,7 @@ impl [T] { /// assert_eq!(v.strip_suffix(&[50, 30]), None); /// ``` #[must_use = "returns the subslice without modifying the original"] - #[stable(feature = "slice_strip", since = "1.50.0")] + #[stable(feature = "slice_strip", since = "1.51.0")] pub fn strip_suffix + ?Sized>(&self, suffix: &P) -> Option<&[T]> where T: PartialEq, @@ -3323,7 +3323,7 @@ pub trait SlicePattern { fn as_slice(&self) -> &[Self::Item]; } -#[stable(feature = "slice_strip", since = "1.50.0")] +#[stable(feature = "slice_strip", since = "1.51.0")] impl SlicePattern for [T] { type Item = T; @@ -3333,7 +3333,7 @@ impl SlicePattern for [T] { } } -#[stable(feature = "slice_strip", since = "1.50.0")] +#[stable(feature = "slice_strip", since = "1.51.0")] impl SlicePattern for [T; N] { type Item = T; diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index a167f0ffa09ec..81c9e1d1c10b2 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -120,21 +120,6 @@ use crate::intrinsics; use crate::hint::spin_loop; -/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock"). -/// -/// This function is expected to be deprecated in favor of -/// [`hint::spin_loop`]. -/// -/// **Note**: On platforms that do not support receiving spin-loop hints this function does not -/// do anything at all. -/// -/// [`hint::spin_loop`]: crate::hint::spin_loop -#[inline] -#[stable(feature = "spin_loop_hint", since = "1.24.0")] -pub fn spin_loop_hint() { - spin_loop() -} - /// A boolean type which can be safely shared between threads. /// /// This type has the same in-memory representation as a [`bool`]. @@ -2791,3 +2776,15 @@ impl fmt::Pointer for AtomicPtr { fmt::Pointer::fmt(&self.load(Ordering::SeqCst), f) } } + +/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock"). +/// +/// This function is deprecated in favor of [`hint::spin_loop`]. +/// +/// [`hint::spin_loop`]: crate::hint::spin_loop +#[inline] +#[stable(feature = "spin_loop_hint", since = "1.24.0")] +#[rustc_deprecated(since = "1.51.0", reason = "use hint::spin_loop instead")] +pub fn spin_loop_hint() { + spin_loop() +} diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 7ad9e446c5997..6b051400890ca 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -944,6 +944,54 @@ pub trait Read { } } +/// Read all bytes from a [reader][Read] into a new [`String`]. +/// +/// This is a convenience function for [`Read::read_to_string`]. Using this +/// function avoids having to create a variable first and provides more type +/// safety since you can only get the buffer out if there were no errors. (If you +/// use [`Read::read_to_string`] you have to remember to check whether the read +/// succeeded because otherwise your buffer will be empty or only partially full.) +/// +/// # Performance +/// +/// The downside of this function's increased ease of use and type safety is +/// that it gives you less control over performance. For example, you can't +/// pre-allocate memory like you can using [`String::with_capacity`] and +/// [`Read::read_to_string`]. Also, you can't re-use the buffer if an error +/// occurs while reading. +/// +/// In many cases, this function's performance will be adequate and the ease of use +/// and type safety tradeoffs will be worth it. However, there are cases where you +/// need more control over performance, and in those cases you should definitely use +/// [`Read::read_to_string`] directly. +/// +/// # Errors +/// +/// This function forces you to handle errors because the output (the `String`) +/// is wrapped in a [`Result`]. See [`Read::read_to_string`] for the errors +/// that can occur. If any error occurs, you will get an [`Err`], so you +/// don't have to worry about your buffer being empty or partially full. +/// +/// # Examples +/// +/// ```no_run +/// #![feature(io_read_to_string)] +/// +/// # use std::io; +/// fn main() -> io::Result<()> { +/// let stdin = io::read_to_string(&mut io::stdin())?; +/// println!("Stdin was:"); +/// println!("{}", stdin); +/// Ok(()) +/// } +/// ``` +#[unstable(feature = "io_read_to_string", issue = "80218")] +pub fn read_to_string(reader: &mut R) -> Result { + let mut buf = String::new(); + reader.read_to_string(&mut buf)?; + Ok(buf) +} + /// A buffer type used with `Read::read_vectored`. /// /// It is semantically a wrapper around an `&mut [u8]`, but is guaranteed to be diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs index f988a019cfedb..885389ca54cd4 100644 --- a/library/std/src/sys/hermit/mutex.rs +++ b/library/std/src/sys/hermit/mutex.rs @@ -1,9 +1,10 @@ use crate::cell::UnsafeCell; use crate::collections::VecDeque; use crate::ffi::c_void; +use crate::hint; use crate::ops::{Deref, DerefMut, Drop}; use crate::ptr; -use crate::sync::atomic::{spin_loop_hint, AtomicUsize, Ordering}; +use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::hermit::abi; /// This type provides a lock based on busy waiting to realize mutual exclusion @@ -46,7 +47,7 @@ impl Spinlock { fn obtain_lock(&self) { let ticket = self.queue.fetch_add(1, Ordering::SeqCst) + 1; while self.dequeue.load(Ordering::SeqCst) != ticket { - spin_loop_hint(); + hint::spin_loop(); } } diff --git a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs index 9140041c58414..7f1a671bab4eb 100644 --- a/library/std/src/sys/sgx/waitqueue/spin_mutex.rs +++ b/library/std/src/sys/sgx/waitqueue/spin_mutex.rs @@ -2,8 +2,9 @@ mod tests; use crate::cell::UnsafeCell; +use crate::hint; use crate::ops::{Deref, DerefMut}; -use crate::sync::atomic::{spin_loop_hint, AtomicBool, Ordering}; +use crate::sync::atomic::{AtomicBool, Ordering}; #[derive(Default)] pub struct SpinMutex { @@ -32,7 +33,7 @@ impl SpinMutex { match self.try_lock() { None => { while self.lock.load(Ordering::Relaxed) { - spin_loop_hint() + hint::spin_loop() } } Some(guard) => return guard, diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 3615a8a5ee8b0..f4c67b225e6e1 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -9,6 +9,14 @@ use crate::process; use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +mod private { + /// This trait being unreachable from outside the crate + /// prevents other implementations of the `ExitStatusExt` trait, + /// which allows potentially adding more trait methods in the future. + #[stable(feature = "none", since = "1.51.0")] + pub trait Sealed {} +} + /// Unix-specific extensions to the [`process::Command`] builder. #[stable(feature = "rust1", since = "1.0.0")] pub trait CommandExt { @@ -163,18 +171,48 @@ impl CommandExt for process::Command { } /// Unix-specific extensions to [`process::ExitStatus`]. +/// +/// This trait is sealed: it cannot be implemented outside the standard library. +/// This is so that future additional methods are not breaking changes. #[stable(feature = "rust1", since = "1.0.0")] -pub trait ExitStatusExt { +pub trait ExitStatusExt: private::Sealed { /// Creates a new `ExitStatus` from the raw underlying `i32` return value of /// a process. #[stable(feature = "exit_status_from", since = "1.12.0")] fn from_raw(raw: i32) -> Self; /// If the process was terminated by a signal, returns that signal. + /// + /// In other words, if `WIFSIGNALED`, this returns `WTERMSIG`. #[stable(feature = "rust1", since = "1.0.0")] fn signal(&self) -> Option; + + /// If the process was terminated by a signal, says whether it dumped core. + #[unstable(feature = "unix_process_wait_more", issue = "80695")] + fn core_dumped(&self) -> bool; + + /// If the process was stopped by a signal, returns that signal. + /// + /// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from + /// a `wait` system call which was passed `WUNTRACED`, was then converted into an `ExitStatus`. + #[unstable(feature = "unix_process_wait_more", issue = "80695")] + fn stopped_signal(&self) -> Option; + + /// Whether the process was continued from a stopped status. + /// + /// Ie, `WIFCONTINUED`. This is only possible if the status came from a `wait` system call + /// which was passed `WCONTINUED`, was then converted into an `ExitStatus`. + #[unstable(feature = "unix_process_wait_more", issue = "80695")] + fn continued(&self) -> bool; + + /// Returns the underlying raw `wait` status. + #[unstable(feature = "unix_process_wait_more", issue = "80695")] + fn into_raw(self) -> i32; } +#[stable(feature = "none", since = "1.51.0")] +impl private::Sealed for process::ExitStatus {} + #[stable(feature = "rust1", since = "1.0.0")] impl ExitStatusExt for process::ExitStatus { fn from_raw(raw: i32) -> Self { @@ -184,6 +222,22 @@ impl ExitStatusExt for process::ExitStatus { fn signal(&self) -> Option { self.as_inner().signal() } + + fn core_dumped(&self) -> bool { + self.as_inner().core_dumped() + } + + fn stopped_signal(&self) -> Option { + self.as_inner().stopped_signal() + } + + fn continued(&self) -> bool { + self.as_inner().continued() + } + + fn into_raw(self) -> i32 { + self.as_inner().into_raw().into() + } } #[stable(feature = "process_extensions", since = "1.2.0")] diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs index b64636c3f3d15..0d4703d7f503a 100644 --- a/library/std/src/sys/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/unix/process/process_fuchsia.rs @@ -245,6 +245,50 @@ impl ExitStatus { pub fn signal(&self) -> Option { None } + + // FIXME: The actually-Unix implementation in process_unix.rs uses WSTOPSIG, WCOREDUMP et al. + // I infer from the implementation of `success`, `code` and `signal` above that these are not + // available on Fuchsia. + // + // It does not appear that Fuchsia is Unix-like enough to implement ExitStatus (or indeed many + // other things from std::os::unix) properly. This veneer is always going to be a bodge. So + // while I don't know if these implementations are actually correct, I think they will do for + // now at least. + pub fn core_dumped(&self) -> bool { + false + } + pub fn stopped_signal(&self) -> Option { + None + } + pub fn continued(&self) -> bool { + false + } + + pub fn into_raw(&self) -> c_int { + // We don't know what someone who calls into_raw() will do with this value, but it should + // have the conventional Unix representation. Despite the fact that this is not + // standardised in SuS or POSIX, all Unix systems encode the signal and exit status the + // same way. (Ie the WIFEXITED, WEXITSTATUS etc. macros have identical behaviour on every + // Unix.) + // + // The caller of `std::os::unix::into_raw` is probably wanting a Unix exit status, and may + // do their own shifting and masking, or even pass the status to another computer running a + // different Unix variant. + // + // The other view would be to say that the caller on Fuchsia ought to know that `into_raw` + // will give a raw Fuchsia status (whatever that is - I don't know, personally). That is + // not possible here becaause we must return a c_int because that's what Unix (including + // SuS and POSIX) say a wait status is, but Fuchsia apparently uses a u64, so it won't + // necessarily fit. + // + // It seems to me that that the right answer would be to provide std::os::fuchsia with its + // own ExitStatusExt, rather that trying to provide a not very convincing imitation of + // Unix. Ie, std::os::unix::process:ExitStatusExt ought not to exist on Fuchsia. But + // fixing this up that is beyond the scope of my efforts now. + let exit_status_as_if_unix: u8 = self.0.try_into().expect("Fuchsia process return code bigger than 8 bits, but std::os::unix::ExitStatusExt::into_raw() was called to try to convert the value into a traditional Unix-style wait status, which cannot represent values greater than 255."); + let wait_status_as_if_unix = (exit_status_as_if_unix as c_int) << 8; + wait_status_as_if_unix + } } /// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying. diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index a590c74435639..945b43678a919 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -479,7 +479,23 @@ impl ExitStatus { } pub fn signal(&self) -> Option { - if !self.exited() { Some(libc::WTERMSIG(self.0)) } else { None } + if libc::WIFSIGNALED(self.0) { Some(libc::WTERMSIG(self.0)) } else { None } + } + + pub fn core_dumped(&self) -> bool { + libc::WIFSIGNALED(self.0) && libc::WCOREDUMP(self.0) + } + + pub fn stopped_signal(&self) -> Option { + if libc::WIFSTOPPED(self.0) { Some(libc::WSTOPSIG(self.0)) } else { None } + } + + pub fn continued(&self) -> bool { + libc::WIFCONTINUED(self.0) + } + + pub fn into_raw(&self) -> c_int { + self.0 } } diff --git a/library/std/src/sys/windows/ext/process.rs b/library/std/src/sys/windows/ext/process.rs index 61e4c6a1d1718..7a92381d6609b 100644 --- a/library/std/src/sys/windows/ext/process.rs +++ b/library/std/src/sys/windows/ext/process.rs @@ -7,6 +7,14 @@ use crate::process; use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +mod private { + /// This trait being unreachable from outside the crate + /// prevents other implementations of the `ExitStatusExt` trait, + /// which allows potentially adding more trait methods in the future. + #[stable(feature = "none", since = "1.51.0")] + pub trait Sealed {} +} + #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawHandle for process::Stdio { unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio { @@ -73,8 +81,11 @@ impl IntoRawHandle for process::ChildStderr { } /// Windows-specific extensions to [`process::ExitStatus`]. +/// +/// This trait is sealed: it cannot be implemented outside the standard library. +/// This is so that future additional methods are not breaking changes. #[stable(feature = "exit_status_from", since = "1.12.0")] -pub trait ExitStatusExt { +pub trait ExitStatusExt: private::Sealed { /// Creates a new `ExitStatus` from the raw underlying `u32` return value of /// a process. #[stable(feature = "exit_status_from", since = "1.12.0")] @@ -88,6 +99,9 @@ impl ExitStatusExt for process::ExitStatus { } } +#[stable(feature = "none", since = "1.51.0")] +impl private::Sealed for process::ExitStatus {} + /// Windows-specific extensions to the [`process::Command`] builder. #[stable(feature = "windows_process_extensions", since = "1.16.0")] pub trait CommandExt { diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 5d65f960fcd39..0d004a516f594 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1186,32 +1186,37 @@ impl fmt::Debug for Thread { /// the [`Error`](crate::error::Error) trait. /// /// Thus, a sensible way to handle a thread panic is to either: -/// 1. `unwrap` the `Result`, propagating the panic +/// +/// 1. propagate the panic with [`std::panic::resume_unwind`] /// 2. or in case the thread is intended to be a subsystem boundary /// that is supposed to isolate system-level failures, -/// match on the `Err` variant and handle the panic in an appropriate way. +/// match on the `Err` variant and handle the panic in an appropriate way /// /// A thread that completes without panicking is considered to exit successfully. /// /// # Examples /// +/// Matching on the result of a joined thread: +/// /// ```no_run -/// use std::thread; -/// use std::fs; +/// use std::{fs, thread, panic}; /// /// fn copy_in_thread() -> thread::Result<()> { -/// thread::spawn(move || { fs::copy("foo.txt", "bar.txt").unwrap(); }).join() +/// thread::spawn(|| { +/// fs::copy("foo.txt", "bar.txt").unwrap(); +/// }).join() /// } /// /// fn main() { /// match copy_in_thread() { -/// Ok(_) => println!("this is fine"), -/// Err(_) => println!("thread panicked"), +/// Ok(_) => println!("copy succeeded"), +/// Err(e) => panic::resume_unwind(e), /// } /// } /// ``` /// /// [`Result`]: crate::result::Result +/// [`std::panic::resume_unwind`]: crate::panic::resume_unwind #[stable(feature = "rust1", since = "1.0.0")] pub type Result = crate::result::Result>; diff --git a/src/doc/book b/src/doc/book index 5bb44f8b5b0aa..ac57a0ddd23d1 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 5bb44f8b5b0aa105c8b22602e9b18800484afa21 +Subproject commit ac57a0ddd23d173b26731ccf939f3ba729753275 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index ba34b8a968f95..ceec19e873be8 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit ba34b8a968f9531d38c4dc4411d5568b7c076bfe +Subproject commit ceec19e873be87c6ee5666b030c6bb612f889a96 diff --git a/src/doc/nomicon b/src/doc/nomicon index a5a48441d411f..a8584998eacde 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit a5a48441d411f61556b57d762b03d6874afe575d +Subproject commit a8584998eacdea7106a1dfafcbf6c1c06fcdf925 diff --git a/src/doc/reference b/src/doc/reference index b278478b76617..50af691f83893 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit b278478b766178491a8b6f67afa4bcd6b64d977a +Subproject commit 50af691f838937c300b47812d0507c6d88c14f97 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 1cce0737d6a7d..03e23af01f0b4 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 1cce0737d6a7d3ceafb139b4a206861fb1dcb2ab +Subproject commit 03e23af01f0b4f83a3a513da280e1ca92587f2ec diff --git a/src/test/codegen/vecdeque_no_panic.rs b/src/test/codegen/vecdeque_no_panic.rs new file mode 100644 index 0000000000000..7e2b5974a0e1b --- /dev/null +++ b/src/test/codegen/vecdeque_no_panic.rs @@ -0,0 +1,19 @@ +// This test checks that `VecDeque::front[_mut]()` and `VecDeque::back[_mut]()` can't panic. + +// compile-flags: -O +// min-llvm-version: 11.0.0 + +#![crate_type = "lib"] + +use std::collections::VecDeque; + +// CHECK-LABEL: @dont_panic +#[no_mangle] +pub fn dont_panic(v: &mut VecDeque) { + // CHECK-NOT: expect + // CHECK-NOT: panic + v.front(); + v.front_mut(); + v.back(); + v.back_mut(); +} diff --git a/src/test/ui/async-await/unused-lifetime.rs b/src/test/ui/async-await/unused-lifetime.rs index 1cf546bcb4266..5bd6ae8d3a42d 100644 --- a/src/test/ui/async-await/unused-lifetime.rs +++ b/src/test/ui/async-await/unused-lifetime.rs @@ -1,42 +1,47 @@ -// edition:2018 +// Check "unused_lifetimes" lint on both async and sync functions -// Avoid spurious warnings of unused lifetime. The below async functions -// are desugered to have an unused lifetime -// but we don't want to warn about that as there's nothing they can do about it. +// edition:2018 #![deny(unused_lifetimes)] -#![allow(dead_code)] - -pub async fn october(s: &str) { - println!("{}", s); -} - -pub async fn async_fn(&mut ref s: &mut[i32]) { - println!("{:?}", s); -} - -macro_rules! foo_macro { - () => { - pub async fn async_fn_in_macro(&mut ref _s: &mut[i32]) {} - }; -} - -foo_macro!(); - -pub async fn func_with_unused_lifetime<'a>(s: &'a str) { - //~^ ERROR lifetime parameter `'a` never used - println!("{}", s); -} - -pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) { - //~^ ERROR lifetime parameter `'a` never used - //~^^ ERROR lifetime parameter `'b` never used - println!("{}", s); -} - -pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) { - //~^ ERROR lifetime parameter `'c` never used - println!("{}", s); -} + + +// Async part with unused lifetimes +// +// Even wrong cases don't cause errors because async functions are desugared with all lifetimes +// involved in the signature. So, we cannot predict what lifetimes are unused in async function. +async fn async_wrong_without_args<'a>() {} + +async fn async_wrong_1_lifetime<'a>(_: &i32) {} + +async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} + +async fn async_right_1_lifetime<'a>(_: &'a i32) {} + +async fn async_right_2_lifetimes<'a, 'b>(_: &'a i32, _: &'b i32) {} + +async fn async_right_trait_bound_lifetime<'a, I>(_: I) +where + I: Iterator +{} + + +// Sync part with unused lifetimes +// +// These functions are compiled as supposed +fn wrong_without_args<'a>() {} //~ ERROR lifetime parameter `'a` never used + +fn wrong_1_lifetime<'a>(_: &i32) {} //~ ERROR lifetime parameter `'a` never used + +fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} //~ ERROR lifetime parameter `'b` never used + +fn right_1_lifetime<'a>(_: &'a i32) {} + +fn right_2_lifetimes<'a, 'b>(_: &'a i32, _: &'b i32) {} + +fn right_trait_bound_lifetime<'a, I>(_: I) +where + I: Iterator +{} + fn main() {} diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr index 2a7a12a364346..4e90f43fdd07b 100644 --- a/src/test/ui/async-await/unused-lifetime.stderr +++ b/src/test/ui/async-await/unused-lifetime.stderr @@ -1,32 +1,28 @@ error: lifetime parameter `'a` never used - --> $DIR/unused-lifetime.rs:26:40 + --> $DIR/unused-lifetime.rs:31:23 | -LL | pub async fn func_with_unused_lifetime<'a>(s: &'a str) { - | ^^ +LL | fn wrong_without_args<'a>() {} + | -^^- help: elide the unused lifetime | note: the lint level is defined here - --> $DIR/unused-lifetime.rs:7:9 + --> $DIR/unused-lifetime.rs:5:9 | LL | #![deny(unused_lifetimes)] | ^^^^^^^^^^^^^^^^ error: lifetime parameter `'a` never used - --> $DIR/unused-lifetime.rs:31:44 + --> $DIR/unused-lifetime.rs:33:21 | -LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) { - | ^^ +LL | fn wrong_1_lifetime<'a>(_: &i32) {} + | -^^- help: elide the unused lifetime error: lifetime parameter `'b` never used - --> $DIR/unused-lifetime.rs:31:48 + --> $DIR/unused-lifetime.rs:35:26 | -LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) { - | ^^ +LL | fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} + | --^^ + | | + | help: elide the unused lifetime -error: lifetime parameter `'c` never used - --> $DIR/unused-lifetime.rs:37:54 - | -LL | pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) { - | ^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors