diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index fe0d0747be6..0ef784a4453 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -600,7 +600,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.impl_trait_defs = current_impl_trait_defs; self.impl_trait_bounds = current_impl_trait_bounds; - debug_assert!(self.children.iter().find(|(id, _)| id == &def_id).is_none()); + debug_assert!(!self.children.iter().any(|(id, _)| id == &def_id)); self.children.push((def_id, hir::MaybeOwner::Owner(info))); } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 5289de9b0ab..d8c22fbe59f 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -2059,12 +2059,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) -> Option { let mpi = self.move_data.rev_lookup.find_local(local); let ii = &self.move_data.init_path_map[mpi]; - for &index in ii { - if flow_state.ever_inits.contains(index) { - return Some(index); - } - } - None + ii.into_iter().find(|&&index| flow_state.ever_inits.contains(index)).copied() } /// Adds the place into the used mutable variables set diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 853a8b82853..5bf45a81e43 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -233,8 +233,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // Set KCFI operand bundle let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; let kcfi_bundle = - if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call { - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap()); + if self.tcx.sess.is_sanitizer_kcfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call { + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi); Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) } else { None diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 5266d8858d4..6eb120157da 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -123,7 +123,7 @@ fn try_filter_fat_archs<'a>( ) -> io::Result> { let archs = archs.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; - let desired = match archs.iter().filter(|a| a.architecture() == target_arch).next() { + let desired = match archs.iter().find(|a| a.architecture() == target_arch) { Some(a) => a, None => return Ok(None), }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index aef1c7ddcd0..c9d179de39f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1124,9 +1124,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let hir = self.tcx.hir(); - let cond_parent = hir.parent_iter(expr.hir_id).skip_while(|(_, node)| { - matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, _, _), .. }) if op.node == hir::BinOpKind::And) - }).next(); + let cond_parent = hir.parent_iter(expr.hir_id).find(|(_, node)| { + !matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, _, _), .. }) if op.node == hir::BinOpKind::And) + }); // Don't suggest: // `let Some(_) = a.is_some() && b` // ++++++++++ diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index ba990acfe6f..da2c6fbc05f 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -488,7 +488,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // If this empty region is from a universe that can // name the placeholder, then the placeholder is // larger; otherwise, the only ancestor is `'static`. - if a_ui.can_name(placeholder.universe) { true } else { false } + return a_ui.can_name(placeholder.universe); } } } diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs index 611961ab1cc..955c54e8515 100644 --- a/compiler/rustc_infer/src/infer/undo_log.rs +++ b/compiler/rustc_infer/src/infer/undo_log.rs @@ -87,18 +87,12 @@ impl<'tcx> Rollback> for InferCtxtInner<'tcx> { /// The combined undo log for all the various unification tables. For each change to the storage /// for any kind of inference variable, we record an UndoLog entry in the vector here. -#[derive(Clone)] +#[derive(Clone, Default)] pub(crate) struct InferCtxtUndoLogs<'tcx> { logs: Vec>, num_open_snapshots: usize, } -impl Default for InferCtxtUndoLogs<'_> { - fn default() -> Self { - Self { logs: Default::default(), num_open_snapshots: Default::default() } - } -} - /// The UndoLogs trait defines how we undo a particular kind of action (of type T). We can undo any /// action that is convertible into an UndoLog (per the From impls above). impl<'tcx, T> UndoLogs for InferCtxtUndoLogs<'tcx> diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index fc08d58cc40..0e18ba73d71 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -103,12 +103,7 @@ impl EffectiveVisibilities { pub fn public_at_level(&self, id: LocalDefId) -> Option { self.effective_vis(id).and_then(|effective_vis| { - for level in Level::all_levels() { - if effective_vis.is_public_at_level(level) { - return Some(level); - } - } - None + Level::all_levels().into_iter().find(|&level| effective_vis.is_public_at_level(level)) }) } diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 558a372fb1e..3a2bf051516 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -182,7 +182,7 @@ fn replace_flattened_locals<'tcx>( let mut fragments = IndexVec::new(); for (k, v) in &replacements.fields { fragments.ensure_contains_elem(k.local, || Vec::new()); - fragments[k.local].push((&k.projection[..], *v)); + fragments[k.local].push((k.projection, *v)); } debug!(?fragments); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 10ea4d29cfe..deeeb9af4eb 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -595,8 +595,8 @@ fn check_recursion_limit<'tcx>( let def_path_str = tcx.def_path_str(def_id); let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); let mut path = PathBuf::new(); - let was_written = if written_to_path.is_some() { - path = written_to_path.unwrap(); + let was_written = if let Some(written_to_path) = written_to_path { + path = written_to_path; Some(()) } else { None diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 2d432e3f5bd..5333d3b8587 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -277,8 +277,7 @@ impl<'a> Parser<'a> { if let Some(arg) = args .iter() .rev() - .skip_while(|arg| matches!(arg, AngleBracketedArg::Constraint(_))) - .next() + .find(|arg| !matches!(arg, AngleBracketedArg::Constraint(_))) { err.span_suggestion_verbose( arg.span().shrink_to_hi(), diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index a71ae717a50..f5556738bff 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -787,7 +787,6 @@ impl<'tcx> DeadVisitor<'tcx> { let mut dead_codes = dead_codes .iter() .filter(|v| !v.name.as_str().starts_with('_')) - .map(|v| v) .collect::>(); if dead_codes.is_empty() { return; diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 1855a49c1ec..6f1b31ff9c3 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -122,7 +122,7 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { let target = crate::config::host_triple(); let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot().expect("Failed finding sysroot")]; - let path = current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?)); + let path = current_dll_path().and_then(|s| s.canonicalize().map_err(|e| e.to_string())); if let Ok(dll) = path { // use `parent` twice to chop off the file name and then also the // directory containing the dll which should be either `lib` or `bin`. @@ -165,7 +165,7 @@ pub fn get_or_default_sysroot() -> Result { } fn default_from_rustc_driver_dll() -> Result { - let dll = current_dll_path().and_then(|s| Ok(canonicalize(s)))?; + let dll = current_dll_path().map(|s| canonicalize(s))?; // `dll` will be in one of the following two: // - compiler's libdir: $sysroot/lib/*.dll diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index c9ddb084d63..0845b1b6b09 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -99,13 +99,8 @@ fn is_c_void_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { ty::Adt(adt_def, ..) => { let def_id = adt_def.0.did; let crate_name = tcx.crate_name(def_id.krate); - if tcx.item_name(def_id).as_str() == "c_void" + tcx.item_name(def_id).as_str() == "c_void" && (crate_name == sym::core || crate_name == sym::std || crate_name == sym::libc) - { - true - } else { - false - } } _ => false, } @@ -267,8 +262,7 @@ fn encode_predicates<'tcx>( ) -> String { // E as part of vendor extended type let mut s = String::new(); - let predicates: Vec> = - predicates.iter().map(|predicate| predicate).collect(); + let predicates: Vec> = predicates.iter().collect(); for predicate in predicates { s.push_str(&encode_predicate(tcx, predicate, dict, options)); } @@ -322,7 +316,7 @@ fn encode_substs<'tcx>( ) -> String { // [IE] as part of vendor extended type let mut s = String::new(); - let substs: Vec> = substs.iter().map(|subst| subst).collect(); + let substs: Vec> = substs.iter().collect(); if !substs.is_empty() { s.push('I'); for subst in substs { @@ -703,11 +697,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio tcx.layout_of(param_env.and(ty)).map_or(false, |layout| layout.is_zst()); !is_zst }); - if field.is_none() { - // Transform repr(transparent) types without non-ZST field into () - ty = tcx.mk_unit(); - } else { - let ty0 = tcx.type_of(field.unwrap().did); + if let Some(field) = field { + let ty0 = tcx.type_of(field.did); // Generalize any repr(transparent) user-defined type that is either a pointer // or reference, and either references itself or any other type that contains or // references itself, to avoid a reference cycle. @@ -720,6 +711,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio } else { ty = transform_ty(tcx, ty0, options); } + } else { + // Transform repr(transparent) types without non-ZST field into () + ty = tcx.mk_unit(); } } else { ty = tcx.mk_adt(*adt_def, transform_substs(tcx, substs, options)); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5a4c87c56d5..036e8f6d47b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1789,7 +1789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.note_conflicting_closure_bounds(cause, &mut err); if let Some(found_node) = found_node { - hint_missing_borrow(span, found_span, found, expected, found_node, &mut err); + hint_missing_borrow(span, found, expected, found_node, &mut err); } err @@ -2344,28 +2344,33 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } GeneratorInteriorOrUpvar::Upvar(upvar_span) => { - // `Some(ref_ty)` if `target_ty` is `&T` and `T` fails to impl `Sync` - let refers_to_non_sync = match target_ty.kind() { - ty::Ref(_, ref_ty, _) => match self.evaluate_obligation(&obligation) { - Ok(eval) if !eval.may_apply() => Some(ref_ty), + // `Some((ref_ty, is_mut))` if `target_ty` is `&T` or `&mut T` and fails to impl `Send` + let non_send = match target_ty.kind() { + ty::Ref(_, ref_ty, mutability) => match self.evaluate_obligation(&obligation) { + Ok(eval) if !eval.may_apply() => Some((ref_ty, mutability.is_mut())), _ => None, }, _ => None, }; - let (span_label, span_note) = match refers_to_non_sync { - // if `target_ty` is `&T` and `T` fails to impl `Sync`, - // include suggestions to make `T: Sync` so that `&T: Send` - Some(ref_ty) => ( - format!( - "has type `{}` which {}, because `{}` is not `Sync`", - target_ty, trait_explanation, ref_ty - ), - format!( - "captured value {} because `&` references cannot be sent unless their referent is `Sync`", - trait_explanation - ), - ), + let (span_label, span_note) = match non_send { + // if `target_ty` is `&T` or `&mut T` and fails to impl `Send`, + // include suggestions to make `T: Sync` so that `&T: Send`, + // or to make `T: Send` so that `&mut T: Send` + Some((ref_ty, is_mut)) => { + let ref_ty_trait = if is_mut { "Send" } else { "Sync" }; + let ref_kind = if is_mut { "&mut" } else { "&" }; + ( + format!( + "has type `{}` which {}, because `{}` is not `{}`", + target_ty, trait_explanation, ref_ty, ref_ty_trait + ), + format!( + "captured value {} because `{}` references cannot be sent unless their referent is `{}`", + trait_explanation, ref_kind, ref_ty_trait + ), + ) + } None => ( format!("has type `{}` which {}", target_ty, trait_explanation), format!("captured value {}", trait_explanation), @@ -3455,7 +3460,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { /// Add a hint to add a missing borrow or remove an unnecessary one. fn hint_missing_borrow<'tcx>( span: Span, - found_span: Span, found: Ty<'tcx>, expected: Ty<'tcx>, found_node: Node<'_>, @@ -3474,9 +3478,8 @@ fn hint_missing_borrow<'tcx>( } }; - let fn_decl = found_node - .fn_decl() - .unwrap_or_else(|| span_bug!(found_span, "found node must be a function")); + // This could be a variant constructor, for example. + let Some(fn_decl) = found_node.fn_decl() else { return; }; let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span); diff --git a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs index adab343ac98..e4f3e7928da 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs @@ -76,11 +76,7 @@ mod rustc { } }; - let ret = if self.visibility(def_id).is_accessible_from(parent, *self) { - true - } else { - false - }; + let ret: bool = self.visibility(def_id).is_accessible_from(parent, *self); trace!(?ret, "ret"); ret diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 122da675f7e..5f4a666de92 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2471,8 +2471,8 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - // Cast is needed here because `.addr()` requires `T: Sized`. - pointer_fmt_inner((*self as *const ()).addr(), f) + // Cast is needed here because `.expose_addr()` requires `T: Sized`. + pointer_fmt_inner((*self as *const ()).expose_addr(), f) } } diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs index 524658bce13..796796e07a9 100644 --- a/library/test/src/cli.rs +++ b/library/test/src/cli.rs @@ -354,8 +354,7 @@ fn get_shuffle_seed(matches: &getopts::Matches, allow_unstable: bool) -> OptPart Err(e) => { return Err(format!( "argument for --shuffle-seed must be a number \ - (error: {})", - e + (error: {e})" )); } }, @@ -383,8 +382,7 @@ fn get_test_threads(matches: &getopts::Matches) -> OptPartRes> { Err(e) => { return Err(format!( "argument for --test-threads must be a number > 0 \ - (error: {})", - e + (error: {e})" )); } }, @@ -418,8 +416,7 @@ fn get_format( Some(v) => { return Err(format!( "argument for --format must be pretty, terse, json or junit (was \ - {})", - v + {v})" )); } }; @@ -436,8 +433,7 @@ fn get_color_config(matches: &getopts::Matches) -> OptPartRes { Some(v) => { return Err(format!( "argument for --color must be auto, always, or never (was \ - {})", - v + {v})" )); } }; diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs index c07fdafb167..5526aadb67f 100644 --- a/library/test/src/formatters/json.rs +++ b/library/test/src/formatters/json.rs @@ -53,7 +53,7 @@ impl JsonFormatter { self.write_message(&*format!(r#", "stdout": "{}""#, EscapedString(stdout)))?; } if let Some(extra) = extra { - self.write_message(&*format!(r#", {}"#, extra))?; + self.write_message(&*format!(r#", {extra}"#))?; } self.writeln_message(" }") } @@ -62,13 +62,12 @@ impl JsonFormatter { impl OutputFormatter for JsonFormatter { fn write_run_start(&mut self, test_count: usize, shuffle_seed: Option) -> io::Result<()> { let shuffle_seed_json = if let Some(shuffle_seed) = shuffle_seed { - format!(r#", "shuffle_seed": {}"#, shuffle_seed) + format!(r#", "shuffle_seed": {shuffle_seed}"#) } else { String::new() }; self.writeln_message(&*format!( - r#"{{ "type": "suite", "event": "started", "test_count": {}{} }}"#, - test_count, shuffle_seed_json + r#"{{ "type": "suite", "event": "started", "test_count": {test_count}{shuffle_seed_json} }}"# )) } diff --git a/library/test/src/formatters/mod.rs b/library/test/src/formatters/mod.rs index cb80859759f..cb67b6491a3 100644 --- a/library/test/src/formatters/mod.rs +++ b/library/test/src/formatters/mod.rs @@ -38,5 +38,5 @@ pub(crate) fn write_stderr_delimiter(test_output: &mut Vec, test_name: &Test Some(_) => test_output.push(b'\n'), None => (), } - writeln!(test_output, "---- {} stderr ----", test_name).unwrap(); + writeln!(test_output, "---- {test_name} stderr ----").unwrap(); } diff --git a/library/test/src/formatters/pretty.rs b/library/test/src/formatters/pretty.rs index 69420222980..0299c8b5433 100644 --- a/library/test/src/formatters/pretty.rs +++ b/library/test/src/formatters/pretty.rs @@ -47,7 +47,7 @@ impl PrettyFormatter { pub fn write_ignored(&mut self, message: Option<&'static str>) -> io::Result<()> { if let Some(message) = message { - self.write_short_result(&format!("ignored, {}", message), term::color::YELLOW) + self.write_short_result(&format!("ignored, {message}"), term::color::YELLOW) } else { self.write_short_result("ignored", term::color::YELLOW) } diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 256c9e8d141..f6a41bbb88c 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -213,8 +213,7 @@ pub fn assert_test_result(result: T) -> Result<(), String> { } else { Err(format!( "the test returned a termination value with a non-zero status code \ - ({}) which indicates a failure", - code + ({code}) which indicates a failure" )) } } @@ -750,7 +749,7 @@ fn spawn_test_subprocess( })() { Ok(r) => r, Err(e) => { - write!(&mut test_output, "Unexpected error: {}", e).unwrap(); + write!(&mut test_output, "Unexpected error: {e}").unwrap(); TrFailed } }; diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs index 7f44d6e3d0f..7c5b0d6c0f7 100644 --- a/library/test/src/test_result.rs +++ b/library/test/src/test_result.rs @@ -44,9 +44,8 @@ pub fn calc_result<'a>( } else if let Some(panic_str) = maybe_panic_str { TestResult::TrFailedMsg(format!( r#"panic did not contain expected string - panic message: `{:?}`, - expected substring: `{:?}`"#, - panic_str, msg + panic message: `{panic_str:?}`, + expected substring: `{msg:?}`"# )) } else { TestResult::TrFailedMsg(format!( diff --git a/library/test/src/time.rs b/library/test/src/time.rs index 8c64e5d1b73..7fd69d7f7e7 100644 --- a/library/test/src/time.rs +++ b/library/test/src/time.rs @@ -107,16 +107,14 @@ impl TimeThreshold { let durations_str = env::var(env_var_name).ok()?; let (warn_str, critical_str) = durations_str.split_once(',').unwrap_or_else(|| { panic!( - "Duration variable {} expected to have 2 numbers separated by comma, but got {}", - env_var_name, durations_str + "Duration variable {env_var_name} expected to have 2 numbers separated by comma, but got {durations_str}" ) }); let parse_u64 = |v| { u64::from_str(v).unwrap_or_else(|_| { panic!( - "Duration value in variable {} is expected to be a number, but got {}", - env_var_name, v + "Duration value in variable {env_var_name} is expected to be a number, but got {v}" ) }) }; diff --git a/src/test/ui/generator/ref-upvar-not-send.rs b/src/test/ui/generator/ref-upvar-not-send.rs new file mode 100644 index 00000000000..eb9ef63ecfc --- /dev/null +++ b/src/test/ui/generator/ref-upvar-not-send.rs @@ -0,0 +1,31 @@ +// For `Send` generators, suggest a `T: Sync` requirement for `&T` upvars, +// and suggest a `T: Send` requirement for `&mut T` upvars. + +#![feature(generators)] + +fn assert_send(_: T) {} +//~^ NOTE required by a bound in `assert_send` +//~| NOTE required by this bound in `assert_send` +//~| NOTE required by a bound in `assert_send` +//~| NOTE required by this bound in `assert_send` + +fn main() { + let x: &*mut () = &std::ptr::null_mut(); + let y: &mut *mut () = &mut std::ptr::null_mut(); + assert_send(move || { + //~^ ERROR generator cannot be sent between threads safely + //~| NOTE generator is not `Send` + yield; + let _x = x; + }); + //~^^ NOTE captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` + //~| NOTE has type `&*mut ()` which is not `Send`, because `*mut ()` is not `Sync` + assert_send(move || { + //~^ ERROR generator cannot be sent between threads safely + //~| NOTE generator is not `Send` + yield; + let _y = y; + }); + //~^^ NOTE captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send` + //~| NOTE has type `&mut *mut ()` which is not `Send`, because `*mut ()` is not `Send` +} diff --git a/src/test/ui/generator/ref-upvar-not-send.stderr b/src/test/ui/generator/ref-upvar-not-send.stderr new file mode 100644 index 00000000000..689ace67e34 --- /dev/null +++ b/src/test/ui/generator/ref-upvar-not-send.stderr @@ -0,0 +1,50 @@ +error: generator cannot be sent between threads safely + --> $DIR/ref-upvar-not-send.rs:15:17 + | +LL | assert_send(move || { + | _________________^ +LL | | +LL | | +LL | | yield; +LL | | let _x = x; +LL | | }); + | |_____^ generator is not `Send` + | + = help: the trait `Sync` is not implemented for `*mut ()` +note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` + --> $DIR/ref-upvar-not-send.rs:19:18 + | +LL | let _x = x; + | ^ has type `&*mut ()` which is not `Send`, because `*mut ()` is not `Sync` +note: required by a bound in `assert_send` + --> $DIR/ref-upvar-not-send.rs:6:19 + | +LL | fn assert_send(_: T) {} + | ^^^^ required by this bound in `assert_send` + +error: generator cannot be sent between threads safely + --> $DIR/ref-upvar-not-send.rs:23:17 + | +LL | assert_send(move || { + | _________________^ +LL | | +LL | | +LL | | yield; +LL | | let _y = y; +LL | | }); + | |_____^ generator is not `Send` + | + = help: within `[generator@$DIR/ref-upvar-not-send.rs:23:17: 23:24]`, the trait `Send` is not implemented for `*mut ()` +note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send` + --> $DIR/ref-upvar-not-send.rs:27:18 + | +LL | let _y = y; + | ^ has type `&mut *mut ()` which is not `Send`, because `*mut ()` is not `Send` +note: required by a bound in `assert_send` + --> $DIR/ref-upvar-not-send.rs:6:19 + | +LL | fn assert_send(_: T) {} + | ^^^^ required by this bound in `assert_send` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/suggestions/enum-variant-arg-mismatch.rs b/src/test/ui/suggestions/enum-variant-arg-mismatch.rs new file mode 100644 index 00000000000..8de5bae92fc --- /dev/null +++ b/src/test/ui/suggestions/enum-variant-arg-mismatch.rs @@ -0,0 +1,10 @@ +pub enum Sexpr<'a> { + Ident(&'a str), +} + +fn map<'a, F: Fn(String) -> Sexpr<'a>>(f: F) {} + +fn main() { + map(Sexpr::Ident); + //~^ ERROR type mismatch in function arguments +} diff --git a/src/test/ui/suggestions/enum-variant-arg-mismatch.stderr b/src/test/ui/suggestions/enum-variant-arg-mismatch.stderr new file mode 100644 index 00000000000..f76019b7000 --- /dev/null +++ b/src/test/ui/suggestions/enum-variant-arg-mismatch.stderr @@ -0,0 +1,22 @@ +error[E0631]: type mismatch in function arguments + --> $DIR/enum-variant-arg-mismatch.rs:8:9 + | +LL | Ident(&'a str), + | ----- found signature defined here +... +LL | map(Sexpr::Ident); + | --- ^^^^^^^^^^^^ expected due to this + | | + | required by a bound introduced by this call + | + = note: expected function signature `fn(String) -> _` + found function signature `fn(&str) -> _` +note: required by a bound in `map` + --> $DIR/enum-variant-arg-mismatch.rs:5:15 + | +LL | fn map<'a, F: Fn(String) -> Sexpr<'a>>(f: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `map` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0631`.