diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index b986df403f9f3..16a903d5e593f 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -180,8 +180,9 @@ pub enum RegionClassification { /// anywhere. There is only one, `'static`. Global, - /// An **external** region is only relevant for closures. In that - /// case, it refers to regions that are free in the closure type + /// An **external** region is only relevant for + /// closures, generators, and inline consts. In that + /// case, it refers to regions that are free in the type /// -- basically, something bound in the surrounding context. /// /// Consider this example: @@ -198,8 +199,8 @@ pub enum RegionClassification { /// Here, the lifetimes `'a` and `'b` would be **external** to the /// closure. /// - /// If we are not analyzing a closure, there are no external - /// lifetimes. + /// If we are not analyzing a closure/generator/inline-const, + /// there are no external lifetimes. External, /// A **local** lifetime is one about which we know the full set @@ -424,22 +425,30 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id()); - // If this is a closure or generator, then the late-bound regions from the enclosing - // function are actually external regions to us. For example, here, 'a is not local - // to the closure c (although it is local to the fn foo): - // fn foo<'a>() { - // let c = || { let x: &'a u32 = ...; } - // } - if self.mir_def.did.to_def_id() != typeck_root_def_id { + // If this is is a 'root' body (not a closure/generator/inline const), then + // there are no extern regions, so the local regions start at the same + // position as the (empty) sub-list of extern regions + let first_local_index = if self.mir_def.did.to_def_id() == typeck_root_def_id { + first_extern_index + } else { + // If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing + // function are actually external regions to us. For example, here, 'a is not local + // to the closure c (although it is local to the fn foo): + // fn foo<'a>() { + // let c = || { let x: &'a u32 = ...; } + // } self.infcx - .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices) - } - - let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty); + .replace_late_bound_regions_with_nll_infer_vars(self.mir_def.did, &mut indices); + // Any regions created during the execution of `defining_ty` or during the above + // late-bound region replacement are all considered 'extern' regions + self.infcx.num_region_vars() + }; // "Liberate" the late-bound regions. These correspond to // "local" free regions. - let first_local_index = self.infcx.num_region_vars(); + + let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty); + let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars( FR, self.mir_def.did, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 3d5fd2f354e55..c90e43a4060f7 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1493,7 +1493,7 @@ fn generator_layout_and_saved_local_names<'tcx>( let state_arg = mir::Local::new(1); for var in &body.var_debug_info { - let place = if let mir::VarDebugInfoContents::Place(p) = var.value { p } else { continue }; + let mir::VarDebugInfoContents::Place(place) = &var.value else { continue }; if place.local != state_arg { continue; } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index cea4595fbbfed..f0612eaba8089 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -7,6 +7,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] +#![feature(let_else)] #![feature(extern_types)] #![feature(nll)] #![recursion_limit = "256"] diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 3804e10030733..263435619590e 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -124,7 +124,16 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option errs.into_iter().for_each(|mut err| err.cancel()), } - error!(r#"expected `key` or `key="value"`"#); + // If the user tried to use a key="value" flag, but is missing the quotes, provide + // a hint about how to resolve this. + if s.contains("=") && !s.contains("=\"") && !s.ends_with("\"") { + error!(concat!( + r#"expected `key` or `key="value"`, ensure escaping is appropriate"#, + r#" for your shell, try 'key="value"' or key=\"value\""# + )); + } else { + error!(r#"expected `key` or `key="value"`"#); + } }) .collect::(); cfg.into_iter().map(|(a, b)| (a.to_string(), b.map(|b| b.to_string()))).collect() diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 2fc3759968fd3..b911b108a735d 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -1,5 +1,6 @@ #![feature(bool_to_option)] #![feature(box_patterns)] +#![feature(let_else)] #![feature(internal_output_capture)] #![feature(thread_spawn_unchecked)] #![feature(nll)] diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 3921187baa55e..6d9183eda9d32 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -717,57 +717,57 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { } fn should_ignore_fn(ret_ty: &ast::FnRetTy) -> bool { - if let ast::FnRetTy::Ty(ref ty) = ret_ty { - fn involves_impl_trait(ty: &ast::Ty) -> bool { - match ty.kind { - ast::TyKind::ImplTrait(..) => true, - ast::TyKind::Slice(ref subty) - | ast::TyKind::Array(ref subty, _) - | ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. }) - | ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. }) - | ast::TyKind::Paren(ref subty) => involves_impl_trait(subty), - ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()), - ast::TyKind::Path(_, ref path) => { - path.segments.iter().any(|seg| match seg.args.as_deref() { - None => false, - Some(&ast::GenericArgs::AngleBracketed(ref data)) => { - data.args.iter().any(|arg| match arg { - ast::AngleBracketedArg::Arg(arg) => match arg { - ast::GenericArg::Type(ty) => involves_impl_trait(ty), - ast::GenericArg::Lifetime(_) - | ast::GenericArg::Const(_) => false, - }, - ast::AngleBracketedArg::Constraint(c) => match c.kind { - ast::AssocConstraintKind::Bound { .. } => true, - ast::AssocConstraintKind::Equality { ref term } => { - match term { - Term::Ty(ty) => involves_impl_trait(ty), - // FIXME(...): This should check if the constant - // involves a trait impl, but for now ignore. - Term::Const(_) => false, - } + let ast::FnRetTy::Ty(ref ty) = ret_ty else { + return false; + }; + fn involves_impl_trait(ty: &ast::Ty) -> bool { + match ty.kind { + ast::TyKind::ImplTrait(..) => true, + ast::TyKind::Slice(ref subty) + | ast::TyKind::Array(ref subty, _) + | ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. }) + | ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. }) + | ast::TyKind::Paren(ref subty) => involves_impl_trait(subty), + ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()), + ast::TyKind::Path(_, ref path) => { + path.segments.iter().any(|seg| match seg.args.as_deref() { + None => false, + Some(&ast::GenericArgs::AngleBracketed(ref data)) => { + data.args.iter().any(|arg| match arg { + ast::AngleBracketedArg::Arg(arg) => match arg { + ast::GenericArg::Type(ty) => involves_impl_trait(ty), + ast::GenericArg::Lifetime(_) | ast::GenericArg::Const(_) => { + false + } + }, + ast::AngleBracketedArg::Constraint(c) => match c.kind { + ast::AssocConstraintKind::Bound { .. } => true, + ast::AssocConstraintKind::Equality { ref term } => { + match term { + Term::Ty(ty) => involves_impl_trait(ty), + // FIXME(...): This should check if the constant + // involves a trait impl, but for now ignore. + Term::Const(_) => false, } - }, - }) - } - Some(&ast::GenericArgs::Parenthesized(ref data)) => { - any_involves_impl_trait(data.inputs.iter()) - || ReplaceBodyWithLoop::should_ignore_fn(&data.output) - } - }) - } - _ => false, + } + }, + }) + } + Some(&ast::GenericArgs::Parenthesized(ref data)) => { + any_involves_impl_trait(data.inputs.iter()) + || ReplaceBodyWithLoop::should_ignore_fn(&data.output) + } + }) } + _ => false, } + } - fn any_involves_impl_trait<'a, I: Iterator>>(mut it: I) -> bool { - it.any(|subty| involves_impl_trait(subty)) - } - - involves_impl_trait(ty) - } else { - false + fn any_involves_impl_trait<'a, I: Iterator>>(mut it: I) -> bool { + it.any(|subty| involves_impl_trait(subty)) } + + involves_impl_trait(ty) } fn is_sig_const(sig: &ast::FnSig) -> bool { diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 85950d8241940..3294f2cf64172 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1347,23 +1347,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mut otherwise = None; for match_pair in match_pairs { - if let PatKind::Or { ref pats } = *match_pair.pattern.kind { - let or_span = match_pair.pattern.span; - let place = match_pair.place; - - first_candidate.visit_leaves(|leaf_candidate| { - self.test_or_pattern( - leaf_candidate, - &mut otherwise, - pats, - or_span, - place.clone(), - fake_borrows, - ); - }); - } else { + let PatKind::Or { ref pats } = &*match_pair.pattern.kind else { bug!("Or-patterns should have been sorted to the end"); - } + }; + let or_span = match_pair.pattern.span; + let place = match_pair.place; + + first_candidate.visit_leaves(|leaf_candidate| { + self.test_or_pattern( + leaf_candidate, + &mut otherwise, + pats, + or_span, + place.clone(), + fake_borrows, + ); + }); } let remainder_start = otherwise.unwrap_or_else(|| self.cfg.start_new_block()); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 7ed5d1d67ab12..f4bf28bfa5ce2 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -88,11 +88,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { switch_ty: Ty<'tcx>, options: &mut FxIndexMap<&'tcx ty::Const<'tcx>, u128>, ) -> bool { - let match_pair = match candidate.match_pairs.iter().find(|mp| mp.place == *test_place) { - Some(match_pair) => match_pair, - _ => { - return false; - } + let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else { + return false; }; match *match_pair.pattern.kind { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 7b4fe6f0e07b3..7e1e5c788052b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1171,9 +1171,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ident: Symbol, kind: &AssocItemKind, ) -> Option { - let module = if let Some((module, _)) = self.current_trait_ref { - module - } else { + let Some((module, _)) = &self.current_trait_ref else { return None; }; if ident == kw::Underscore { diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index b077a5c9144c5..4c7bdb33fb87a 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1000,46 +1000,45 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // `fn foo<'a>() -> MyAnonTy<'a> { ... }` // ^ ^this gets resolved in the current scope for lifetime in lifetimes { - if let hir::GenericArg::Lifetime(lifetime) = lifetime { - self.visit_lifetime(lifetime); + let hir::GenericArg::Lifetime(lifetime) = lifetime else { + continue + }; + self.visit_lifetime(lifetime); + + // Check for predicates like `impl for<'a> Trait>` + // and ban them. Type variables instantiated inside binders aren't + // well-supported at the moment, so this doesn't work. + // In the future, this should be fixed and this error should be removed. + let def = self.map.defs.get(&lifetime.hir_id).cloned(); + let Some(Region::LateBound(_, _, def_id, _)) = def else { + continue + }; + let Some(def_id) = def_id.as_local() else { + continue + }; + let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); + // Ensure that the parent of the def is an item, not HRTB + let parent_id = self.tcx.hir().get_parent_node(hir_id); + // FIXME(cjgillot) Can this check be replaced by + // `let parent_is_item = parent_id.is_owner();`? + let parent_is_item = if let Some(parent_def_id) = parent_id.as_owner() { + matches!(self.tcx.hir().krate().owners.get(parent_def_id), Some(Some(_)),) + } else { + false + }; - // Check for predicates like `impl for<'a> Trait>` - // and ban them. Type variables instantiated inside binders aren't - // well-supported at the moment, so this doesn't work. - // In the future, this should be fixed and this error should be removed. - let def = self.map.defs.get(&lifetime.hir_id).cloned(); - if let Some(Region::LateBound(_, _, def_id, _)) = def { - if let Some(def_id) = def_id.as_local() { - let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); - // Ensure that the parent of the def is an item, not HRTB - let parent_id = self.tcx.hir().get_parent_node(hir_id); - // FIXME(cjgillot) Can this check be replaced by - // `let parent_is_item = parent_id.is_owner();`? - let parent_is_item = - if let Some(parent_def_id) = parent_id.as_owner() { - matches!( - self.tcx.hir().krate().owners.get(parent_def_id), - Some(Some(_)), - ) - } else { - false - }; - - if !parent_is_item { - if !self.trait_definition_only { - struct_span_err!( - self.tcx.sess, - lifetime.span, - E0657, - "`impl Trait` can only capture lifetimes \ - bound at the fn or impl level" - ) - .emit(); - } - self.uninsert_lifetime_on_error(lifetime, def.unwrap()); - } - } + if !parent_is_item { + if !self.trait_definition_only { + struct_span_err!( + self.tcx.sess, + lifetime.span, + E0657, + "`impl Trait` can only capture lifetimes \ + bound at the fn or impl level" + ) + .emit(); } + self.uninsert_lifetime_on_error(lifetime, def.unwrap()); } } 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 e94c600bb4955..3fb42a2ec4a1d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -840,39 +840,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; for refs_remaining in 0..refs_number { - if let ty::Ref(_, inner_ty, _) = suggested_ty.kind() { - suggested_ty = inner_ty; + let ty::Ref(_, inner_ty, _) = suggested_ty.kind() else { + break; + }; + suggested_ty = inner_ty; - let new_obligation = self.mk_trait_obligation_with_new_self_ty( - obligation.param_env, - trait_ref, - suggested_ty, - ); + let new_obligation = self.mk_trait_obligation_with_new_self_ty( + obligation.param_env, + trait_ref, + suggested_ty, + ); - if self.predicate_may_hold(&new_obligation) { - let sp = self - .tcx - .sess - .source_map() - .span_take_while(span, |c| c.is_whitespace() || *c == '&'); + if self.predicate_may_hold(&new_obligation) { + let sp = self + .tcx + .sess + .source_map() + .span_take_while(span, |c| c.is_whitespace() || *c == '&'); - let remove_refs = refs_remaining + 1; + let remove_refs = refs_remaining + 1; - let msg = if remove_refs == 1 { - "consider removing the leading `&`-reference".to_string() - } else { - format!("consider removing {} leading `&`-references", remove_refs) - }; + let msg = if remove_refs == 1 { + "consider removing the leading `&`-reference".to_string() + } else { + format!("consider removing {} leading `&`-references", remove_refs) + }; - err.span_suggestion_short( - sp, - &msg, - String::new(), - Applicability::MachineApplicable, - ); - break; - } - } else { + err.span_suggestion_short( + sp, + &msg, + String::new(), + Applicability::MachineApplicable, + ); break; } } diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index eea8f40635d74..0fea0afb572c9 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -307,6 +307,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Give appropriate suggestion when encountering `[("a", 0) ("b", 1)]`, where the + /// likely intention is to create an array containing tuples. + fn maybe_suggest_bad_array_definition( + &self, + err: &mut DiagnosticBuilder<'a>, + call_expr: &'tcx hir::Expr<'tcx>, + callee_expr: &'tcx hir::Expr<'tcx>, + ) -> bool { + let hir_id = self.tcx.hir().get_parent_node(call_expr.hir_id); + let parent_node = self.tcx.hir().get(hir_id); + if let ( + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }), + hir::ExprKind::Tup(exp), + hir::ExprKind::Call(_, args), + ) = (parent_node, &callee_expr.kind, &call_expr.kind) + { + if args.len() == exp.len() { + let start = callee_expr.span.shrink_to_hi(); + err.span_suggestion( + start, + "consider separating array elements with a comma", + ",".to_string(), + Applicability::MaybeIncorrect, + ); + return true; + } + } + false + } + fn confirm_builtin_call( &self, call_expr: &'tcx hir::Expr<'tcx>, @@ -422,7 +452,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Res::Err, }; - err.span_label(call_expr.span, "call expression requires function"); + if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) { + err.span_label(call_expr.span, "call expression requires function"); + } if let Some(span) = self.tcx.hir().res_span(def) { let callee_ty = callee_ty.to_string(); diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index c20c457de85c8..74516acbfcff3 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -549,16 +549,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { is_assign: IsAssign, op: hir::BinOp, ) -> bool { - let source_map = self.tcx.sess.source_map(); - let remove_borrow_msg = "String concatenation appends the string on the right to the \ - string on the left and may require reallocation. This \ - requires ownership of the string on the left"; - - let msg = "`to_owned()` can be used to create an owned `String` \ - from a string reference. String concatenation \ - appends the string on the right to the string \ - on the left and may require reallocation. This \ - requires ownership of the string on the left"; + let str_concat_note = "string concatenation requires an owned `String` on the left"; + let rm_borrow_msg = "remove the borrow to obtain an owned `String`"; + let to_owned_msg = "create an owned `String` from a string reference"; let string_type = self.tcx.get_diagnostic_item(sym::String); let is_std_string = |ty: Ty<'tcx>| match ty.ty_adt_def() { @@ -574,31 +567,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) => { if let IsAssign::No = is_assign { // Do not supply this message if `&str += &str` - err.span_label( - op.span, - "`+` cannot be used to concatenate two `&str` strings", - ); - match source_map.span_to_snippet(lhs_expr.span) { - Ok(lstring) => { - err.span_suggestion( - lhs_expr.span, - if lstring.starts_with('&') { - remove_borrow_msg - } else { - msg - }, - if let Some(stripped) = lstring.strip_prefix('&') { - // let a = String::new(); - // let _ = &a + "bar"; - stripped.to_string() - } else { - format!("{}.to_owned()", lstring) - }, - Applicability::MachineApplicable, - ) - } - _ => err.help(msg), - }; + err.span_label(op.span, "`+` cannot be used to concatenate two `&str` strings"); + err.note(str_concat_note); + if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind { + err.span_suggestion_verbose( + lhs_expr.span.until(lhs_inner_expr.span), + rm_borrow_msg, + "".to_owned(), + Applicability::MachineApplicable + ); + } else { + err.span_suggestion_verbose( + lhs_expr.span.shrink_to_hi(), + to_owned_msg, + ".to_owned()".to_owned(), + Applicability::MachineApplicable + ); + } } true } @@ -609,32 +594,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { op.span, "`+` cannot be used to concatenate a `&str` with a `String`", ); - match ( - source_map.span_to_snippet(lhs_expr.span), - source_map.span_to_snippet(rhs_expr.span), - is_assign, - ) { - (Ok(l), Ok(r), IsAssign::No) => { - let to_string = if let Some(stripped) = l.strip_prefix('&') { - // let a = String::new(); let b = String::new(); - // let _ = &a + b; - stripped.to_string() + match is_assign { + IsAssign::No => { + let sugg_msg; + let lhs_sugg = if let hir::ExprKind::AddrOf(_, _, lhs_inner_expr) = lhs_expr.kind { + sugg_msg = "remove the borrow on the left and add one on the right"; + (lhs_expr.span.until(lhs_inner_expr.span), "".to_owned()) } else { - format!("{}.to_owned()", l) + sugg_msg = "create an owned `String` on the left and add a borrow on the right"; + (lhs_expr.span.shrink_to_hi(), ".to_owned()".to_owned()) }; - err.multipart_suggestion( - msg, - vec![ - (lhs_expr.span, to_string), - (rhs_expr.span, format!("&{}", r)), - ], + let suggestions = vec![ + lhs_sugg, + (rhs_expr.span.shrink_to_lo(), "&".to_owned()), + ]; + err.multipart_suggestion_verbose( + sugg_msg, + suggestions, Applicability::MachineApplicable, ); } - _ => { - err.help(msg); + IsAssign::Yes => { + err.note(str_concat_note); } - }; + } true } _ => false, diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 33bee4324fd38..bf5fcfdcbf5fa 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -451,12 +451,10 @@ impl Rc { /// /// let mut five = Rc::::new_uninit(); /// - /// let five = unsafe { - /// // Deferred initialization: - /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// // Deferred initialization: + /// Rc::get_mut(&mut five).unwrap().write(5); /// - /// five.assume_init() - /// }; + /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5) /// ``` @@ -543,12 +541,10 @@ impl Rc { /// /// let mut five = Rc::::try_new_uninit()?; /// - /// let five = unsafe { - /// // Deferred initialization: - /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// // Deferred initialization: + /// Rc::get_mut(&mut five).unwrap().write(5); /// - /// five.assume_init() - /// }; + /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5); /// # Ok::<(), std::alloc::AllocError>(()) @@ -660,14 +656,13 @@ impl Rc<[T]> { /// /// let mut values = Rc::<[u32]>::new_uninit_slice(3); /// - /// let values = unsafe { - /// // Deferred initialization: - /// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1); - /// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2); - /// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3); + /// // Deferred initialization: + /// let data = Rc::get_mut(&mut values).unwrap(); + /// data[0].write(1); + /// data[1].write(2); + /// data[2].write(3); /// - /// values.assume_init() - /// }; + /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]) /// ``` @@ -738,12 +733,10 @@ impl Rc> { /// /// let mut five = Rc::::new_uninit(); /// - /// let five = unsafe { - /// // Deferred initialization: - /// Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// // Deferred initialization: + /// Rc::get_mut(&mut five).unwrap().write(5); /// - /// five.assume_init() - /// }; + /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5) /// ``` @@ -777,14 +770,13 @@ impl Rc<[mem::MaybeUninit]> { /// /// let mut values = Rc::<[u32]>::new_uninit_slice(3); /// - /// let values = unsafe { - /// // Deferred initialization: - /// Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1); - /// Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2); - /// Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3); + /// // Deferred initialization: + /// let data = Rc::get_mut(&mut values).unwrap(); + /// data[0].write(1); + /// data[1].write(2); + /// data[2].write(3); /// - /// values.assume_init() - /// }; + /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]) /// ``` diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 7c065f37d1fa8..ab8a44b214743 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -437,12 +437,10 @@ impl Arc { /// /// let mut five = Arc::::new_uninit(); /// - /// let five = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// // Deferred initialization: + /// Arc::get_mut(&mut five).unwrap().write(5); /// - /// five.assume_init() - /// }; + /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5) /// ``` @@ -545,12 +543,10 @@ impl Arc { /// /// let mut five = Arc::::try_new_uninit()?; /// - /// let five = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// // Deferred initialization: + /// Arc::get_mut(&mut five).unwrap().write(5); /// - /// five.assume_init() - /// }; + /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5); /// # Ok::<(), std::alloc::AllocError>(()) @@ -652,14 +648,13 @@ impl Arc<[T]> { /// /// let mut values = Arc::<[u32]>::new_uninit_slice(3); /// - /// let values = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1); - /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2); - /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3); + /// // Deferred initialization: + /// let data = Arc::get_mut(&mut values).unwrap(); + /// data[0].write(1); + /// data[1].write(2); + /// data[2].write(3); /// - /// values.assume_init() - /// }; + /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]) /// ``` @@ -730,12 +725,10 @@ impl Arc> { /// /// let mut five = Arc::::new_uninit(); /// - /// let five = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); + /// // Deferred initialization: + /// Arc::get_mut(&mut five).unwrap().write(5); /// - /// five.assume_init() - /// }; + /// let five = unsafe { five.assume_init() }; /// /// assert_eq!(*five, 5) /// ``` @@ -770,14 +763,13 @@ impl Arc<[mem::MaybeUninit]> { /// /// let mut values = Arc::<[u32]>::new_uninit_slice(3); /// - /// let values = unsafe { - /// // Deferred initialization: - /// Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1); - /// Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2); - /// Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3); + /// // Deferred initialization: + /// let data = Arc::get_mut(&mut values).unwrap(); + /// data[0].write(1); + /// data[1].write(2); + /// data[2].write(3); /// - /// values.assume_init() - /// }; + /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [1, 2, 3]) /// ``` diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index d859bff1a45fa..66fee2fe54837 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -973,7 +973,8 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Arc { - /// Converts a [`CString`] into an [Arc]<[CStr]> without copying or allocating. + /// Converts a [`CString`] into an [Arc]<[CStr]> by moving the [`CString`] + /// data into a new [`Arc`] buffer. #[inline] fn from(s: CString) -> Arc { let arc: Arc<[u8]> = Arc::from(s.into_inner()); @@ -992,7 +993,8 @@ impl From<&CStr> for Arc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { - /// Converts a [`CString`] into an [Rc]<[CStr]> without copying or allocating. + /// Converts a [`CString`] into an [Rc]<[CStr]> by moving the [`CString`] + /// data into a new [`Arc`] buffer. #[inline] fn from(s: CString) -> Rc { let rc: Rc<[u8]> = Rc::from(s.into_inner()); diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 982ad1898788e..81f72e34d9388 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -989,7 +989,8 @@ impl Clone for Box { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Arc { - /// Converts an [`OsString`] into an [Arc]<[OsStr]> without copying or allocating. + /// Converts an [`OsString`] into an [Arc]<[OsStr]> by moving the [`OsString`] + /// data into a new [`Arc`] buffer. #[inline] fn from(s: OsString) -> Arc { let arc = s.inner.into_arc(); @@ -1008,7 +1009,8 @@ impl From<&OsStr> for Arc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { - /// Converts an [`OsString`] into an [Rc]<[OsStr]> without copying or allocating. + /// Converts an [`OsString`] into an [Rc]<[OsStr]> by moving the [`OsString`] + /// data into a new [`Rc`] buffer. #[inline] fn from(s: OsString) -> Rc { let rc = s.inner.into_rc(); diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index c072f0cafe47b..3d6de20d86091 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -7,7 +7,7 @@ use crate::io::prelude::*; use crate::cell::{Cell, RefCell}; use crate::fmt; -use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines, Split}; +use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines}; use crate::lazy::SyncOnceCell; use crate::pin::Pin; use crate::sync::atomic::{AtomicBool, Ordering}; @@ -465,29 +465,6 @@ impl Stdin { pub fn lines(self) -> Lines> { self.into_locked().lines() } - - /// Consumes this handle and returns an iterator over input bytes, - /// split at the specified byte value. - /// - /// For detailed semantics of this method, see the documentation on - /// [`BufRead::split`]. - /// - /// # Examples - /// - /// ```no_run - /// #![feature(stdin_forwarders)] - /// use std::io; - /// - /// let splits = io::stdin().split(b'-'); - /// for split in splits { - /// println!("got a chunk: {}", String::from_utf8_lossy(&split.unwrap())); - /// } - /// ``` - #[must_use = "`self` will be dropped if the result is not used"] - #[unstable(feature = "stdin_forwarders", issue = "87096")] - pub fn split(self, byte: u8) -> Split> { - self.into_locked().split(byte) - } } #[stable(feature = "std_debug", since = "1.16.0")] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index f509403fe2e43..558333518f1d4 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1766,7 +1766,8 @@ impl<'a> From> for PathBuf { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Arc { - /// Converts a [`PathBuf`] into an [`Arc`] by moving the [`PathBuf`] data into a new [`Arc`] buffer. + /// Converts a [`PathBuf`] into an [Arc]<[Path]> by moving the [`PathBuf`] data + /// into a new [`Arc`] buffer. #[inline] fn from(s: PathBuf) -> Arc { let arc: Arc = Arc::from(s.into_os_string()); @@ -1786,7 +1787,8 @@ impl From<&Path> for Arc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From for Rc { - /// Converts a [`PathBuf`] into an [`Rc`] by moving the [`PathBuf`] data into a new `Rc` buffer. + /// Converts a [`PathBuf`] into an [Rc]<[Path]> by moving the [`PathBuf`] data into + /// a new [`Rc`] buffer. #[inline] fn from(s: PathBuf) -> Rc { let rc: Rc = Rc::from(s.into_os_string()); @@ -1796,7 +1798,7 @@ impl From for Rc { #[stable(feature = "shared_from_slice2", since = "1.24.0")] impl From<&Path> for Rc { - /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new `Rc` buffer. + /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer. #[inline] fn from(s: &Path) -> Rc { let rc: Rc = Rc::from(s.as_os_str()); diff --git a/library/std/src/sys/common/alloc.rs b/library/std/src/sys/common/alloc.rs index 9665d1fa89243..e06eaf6db1a77 100644 --- a/library/std/src/sys/common/alloc.rs +++ b/library/std/src/sys/common/alloc.rs @@ -14,8 +14,8 @@ use crate::ptr; target_arch = "asmjs", target_arch = "wasm32", target_arch = "hexagon", - target_arch = "riscv32", - target_arch = "xtensa" + all(target_arch = "riscv32", not(target_os = "espidf")), + all(target_arch = "xtensa", not(target_os = "espidf")), )))] pub const MIN_ALIGN: usize = 8; #[cfg(all(any( @@ -28,6 +28,12 @@ pub const MIN_ALIGN: usize = 8; target_arch = "wasm64", )))] pub const MIN_ALIGN: usize = 16; +// The allocator on the esp-idf platform guarentees 4 byte alignment. +#[cfg(all(any( + all(target_arch = "riscv32", target_os = "espidf"), + all(target_arch = "xtensa", target_os = "espidf"), +)))] +pub const MIN_ALIGN: usize = 4; pub unsafe fn realloc_fallback( alloc: &System, diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 6ccf8b1d5221c..5cab3e8be1039 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -7,7 +7,7 @@ use std::fmt::Debug; use std::fs; use std::hash::Hash; use std::ops::Deref; -use std::path::{Path, PathBuf}; +use std::path::{Component, Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; @@ -105,6 +105,44 @@ struct StepDescription { should_run: fn(ShouldRun<'_>) -> ShouldRun<'_>, make_run: fn(RunConfig<'_>), name: &'static str, + kind: Kind, +} + +#[derive(Clone, PartialOrd, Ord, PartialEq, Eq)] +pub struct TaskPath { + pub path: PathBuf, + pub kind: Option, +} + +impl TaskPath { + pub fn parse(path: impl Into) -> TaskPath { + let mut kind = None; + let mut path = path.into(); + + let mut components = path.components(); + if let Some(Component::Normal(os_str)) = components.next() { + if let Some(str) = os_str.to_str() { + if let Some((found_kind, found_prefix)) = str.split_once("::") { + if found_kind.is_empty() { + panic!("empty kind in task path {}", path.display()); + } + kind = Some(Kind::parse(found_kind)); + path = Path::new(found_prefix).join(components.as_path()); + } + } + } + + TaskPath { path, kind } + } +} + +impl Debug for TaskPath { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(kind) = &self.kind { + write!(f, "{}::", kind.as_str())?; + } + write!(f, "{}", self.path.display()) + } } /// Collection of paths used to match a task rule. @@ -115,14 +153,14 @@ pub enum PathSet { /// These are generally matched as a path suffix. For example, a /// command-line value of `libstd` will match if `src/libstd` is in the /// set. - Set(BTreeSet), + Set(BTreeSet), /// A "suite" of paths. /// /// These can match as a path suffix (like `Set`), or as a prefix. For /// example, a command-line value of `src/test/ui/abi/variadic-ffi.rs` /// will match `src/test/ui`. A command-line value of `ui` would also /// match `src/test/ui`. - Suite(PathBuf), + Suite(TaskPath), } impl PathSet { @@ -130,35 +168,46 @@ impl PathSet { PathSet::Set(BTreeSet::new()) } - fn one>(path: P) -> PathSet { + fn one>(path: P, kind: Kind) -> PathSet { let mut set = BTreeSet::new(); - set.insert(path.into()); + set.insert(TaskPath { path: path.into(), kind: Some(kind.into()) }); PathSet::Set(set) } - fn has(&self, needle: &Path) -> bool { + fn has(&self, needle: &Path, module: Option) -> bool { + let check = |p: &TaskPath| { + if let (Some(p_kind), Some(kind)) = (&p.kind, module) { + p.path.ends_with(needle) && *p_kind == kind + } else { + p.path.ends_with(needle) + } + }; + match self { - PathSet::Set(set) => set.iter().any(|p| p.ends_with(needle)), - PathSet::Suite(suite) => suite.ends_with(needle), + PathSet::Set(set) => set.iter().any(check), + PathSet::Suite(suite) => check(suite), } } fn path(&self, builder: &Builder<'_>) -> PathBuf { match self { - PathSet::Set(set) => set.iter().next().unwrap_or(&builder.build.src).to_path_buf(), - PathSet::Suite(path) => PathBuf::from(path), + PathSet::Set(set) => { + set.iter().next().map(|p| &p.path).unwrap_or(&builder.build.src).clone() + } + PathSet::Suite(path) => path.path.clone(), } } } impl StepDescription { - fn from() -> StepDescription { + fn from(kind: Kind) -> StepDescription { StepDescription { default: S::DEFAULT, only_hosts: S::ONLY_HOSTS, should_run: S::should_run, make_run: S::make_run, name: std::any::type_name::(), + kind, } } @@ -177,7 +226,7 @@ impl StepDescription { } fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool { - if builder.config.exclude.iter().any(|e| pathset.has(e)) { + if builder.config.exclude.iter().any(|e| pathset.has(&e.path, e.kind)) { eprintln!("Skipping {:?} because it is excluded", pathset); return true; } @@ -192,8 +241,10 @@ impl StepDescription { } fn run(v: &[StepDescription], builder: &Builder<'_>, paths: &[PathBuf]) { - let should_runs = - v.iter().map(|desc| (desc.should_run)(ShouldRun::new(builder))).collect::>(); + let should_runs = v + .iter() + .map(|desc| (desc.should_run)(ShouldRun::new(builder, desc.kind))) + .collect::>(); // sanity checks on rules for (desc, should_run) in v.iter().zip(&should_runs) { @@ -226,7 +277,7 @@ impl StepDescription { if let Some(suite) = should_run.is_suite_path(path) { attempted_run = true; desc.maybe_run(builder, suite); - } else if let Some(pathset) = should_run.pathset_for_path(path) { + } else if let Some(pathset) = should_run.pathset_for_path(path, desc.kind) { attempted_run = true; desc.maybe_run(builder, pathset); } @@ -246,6 +297,8 @@ enum ReallyDefault<'a> { pub struct ShouldRun<'a> { pub builder: &'a Builder<'a>, + kind: Kind, + // use a BTreeSet to maintain sort order paths: BTreeSet, @@ -255,9 +308,10 @@ pub struct ShouldRun<'a> { } impl<'a> ShouldRun<'a> { - fn new(builder: &'a Builder<'_>) -> ShouldRun<'a> { + fn new(builder: &'a Builder<'_>, kind: Kind) -> ShouldRun<'a> { ShouldRun { builder, + kind, paths: BTreeSet::new(), is_really_default: ReallyDefault::Bool(true), // by default no additional conditions } @@ -293,7 +347,7 @@ impl<'a> ShouldRun<'a> { let mut set = BTreeSet::new(); for krate in self.builder.in_tree_crates(name, None) { let path = krate.local_path(self.builder); - set.insert(path); + set.insert(TaskPath { path, kind: Some(self.kind) }); } self.paths.insert(PathSet::Set(set)); self @@ -306,7 +360,7 @@ impl<'a> ShouldRun<'a> { pub fn krate(mut self, name: &str) -> Self { for krate in self.builder.in_tree_crates(name, None) { let path = krate.local_path(self.builder); - self.paths.insert(PathSet::one(path)); + self.paths.insert(PathSet::one(path, self.kind)); } self } @@ -318,19 +372,25 @@ impl<'a> ShouldRun<'a> { // multiple aliases for the same job pub fn paths(mut self, paths: &[&str]) -> Self { - self.paths.insert(PathSet::Set(paths.iter().map(PathBuf::from).collect())); + self.paths.insert(PathSet::Set( + paths + .iter() + .map(|p| TaskPath { path: p.into(), kind: Some(self.kind.into()) }) + .collect(), + )); self } pub fn is_suite_path(&self, path: &Path) -> Option<&PathSet> { self.paths.iter().find(|pathset| match pathset { - PathSet::Suite(p) => path.starts_with(p), + PathSet::Suite(p) => path.starts_with(&p.path), PathSet::Set(_) => false, }) } pub fn suite_path(mut self, suite: &str) -> Self { - self.paths.insert(PathSet::Suite(PathBuf::from(suite))); + self.paths + .insert(PathSet::Suite(TaskPath { path: suite.into(), kind: Some(self.kind.into()) })); self } @@ -340,12 +400,12 @@ impl<'a> ShouldRun<'a> { self } - fn pathset_for_path(&self, path: &Path) -> Option<&PathSet> { - self.paths.iter().find(|pathset| pathset.has(path)) + fn pathset_for_path(&self, path: &Path, kind: Kind) -> Option<&PathSet> { + self.paths.iter().find(|pathset| pathset.has(path, Some(kind))) } } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] pub enum Kind { Build, Check, @@ -359,11 +419,44 @@ pub enum Kind { Run, } +impl Kind { + fn parse(string: &str) -> Kind { + match string { + "build" => Kind::Build, + "check" => Kind::Check, + "clippy" => Kind::Clippy, + "fix" => Kind::Fix, + "test" => Kind::Test, + "bench" => Kind::Bench, + "dist" => Kind::Dist, + "doc" => Kind::Doc, + "install" => Kind::Install, + "run" => Kind::Run, + other => panic!("unknown kind: {}", other), + } + } + + fn as_str(&self) -> &'static str { + match self { + Kind::Build => "build", + Kind::Check => "check", + Kind::Clippy => "clippy", + Kind::Fix => "fix", + Kind::Test => "test", + Kind::Bench => "bench", + Kind::Dist => "dist", + Kind::Doc => "doc", + Kind::Install => "install", + Kind::Run => "run", + } + } +} + impl<'a> Builder<'a> { fn get_step_descriptions(kind: Kind) -> Vec { macro_rules! describe { ($($rule:ty),+ $(,)?) => {{ - vec![$(StepDescription::from::<$rule>()),+] + vec![$(StepDescription::from::<$rule>(kind)),+] }}; } match kind { @@ -540,8 +633,11 @@ impl<'a> Builder<'a> { let builder = Self::new_internal(build, kind, vec![]); let builder = &builder; - let mut should_run = ShouldRun::new(builder); + // The "build" kind here is just a placeholder, it will be replaced with something else in + // the following statement. + let mut should_run = ShouldRun::new(builder, Kind::Build); for desc in Builder::get_step_descriptions(builder.kind) { + should_run.kind = desc.kind; should_run = (desc.should_run)(should_run); } let mut help = String::from("Available paths:\n"); @@ -552,11 +648,11 @@ impl<'a> Builder<'a> { match pathset { PathSet::Set(set) => { for path in set { - add_path(&path); + add_path(&path.path); } } PathSet::Suite(path) => { - add_path(&path.join("...")); + add_path(&path.path.join("...")); } } } @@ -1626,9 +1722,10 @@ impl<'a> Builder<'a> { pub(crate) fn ensure_if_default>>( &'a self, step: S, + kind: Kind, ) -> S::Output { - let desc = StepDescription::from::(); - let should_run = (desc.should_run)(ShouldRun::new(self)); + let desc = StepDescription::from::(kind); + let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind)); // Avoid running steps contained in --exclude for pathset in &should_run.paths { @@ -1642,13 +1739,16 @@ impl<'a> Builder<'a> { } /// Checks if any of the "should_run" paths is in the `Builder` paths. - pub(crate) fn was_invoked_explicitly(&'a self) -> bool { - let desc = StepDescription::from::(); - let should_run = (desc.should_run)(ShouldRun::new(self)); + pub(crate) fn was_invoked_explicitly(&'a self, kind: Kind) -> bool { + let desc = StepDescription::from::(kind); + let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind)); for path in &self.paths { - if should_run.paths.iter().any(|s| s.has(path)) - && !desc.is_excluded(self, &PathSet::Suite(path.clone())) + if should_run.paths.iter().any(|s| s.has(path, Some(desc.kind))) + && !desc.is_excluded( + self, + &PathSet::Suite(TaskPath { path: path.clone(), kind: Some(desc.kind.into()) }), + ) { return true; } diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index bb3ea04d4ace9..bc71034496968 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -499,7 +499,7 @@ mod dist { let host = TargetSelection::from_user("A"); builder.run_step_descriptions( - &[StepDescription::from::()], + &[StepDescription::from::(Kind::Test)], &["library/std".into()], ); @@ -520,7 +520,7 @@ mod dist { #[test] fn test_exclude() { let mut config = configure(&["A"], &["A"]); - config.exclude = vec!["src/tools/tidy".into()]; + config.exclude = vec![TaskPath::parse("src/tools/tidy")]; config.cmd = Subcommand::Test { paths: Vec::new(), test_args: Vec::new(), diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 5af9248583cae..683cfc630e771 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -12,6 +12,7 @@ use std::fs; use std::path::{Path, PathBuf}; use std::str::FromStr; +use crate::builder::TaskPath; use crate::cache::{Interned, INTERNER}; use crate::channel::GitInfo; pub use crate::flags::Subcommand; @@ -62,7 +63,7 @@ pub struct Config { pub sanitizers: bool, pub profiler: bool, pub ignore_git: bool, - pub exclude: Vec, + pub exclude: Vec, pub include_default_paths: bool, pub rustc_error_format: Option, pub json_output: bool, @@ -635,7 +636,7 @@ impl Config { let flags = Flags::parse(&args); let mut config = Config::default_opts(); - config.exclude = flags.exclude; + config.exclude = flags.exclude.into_iter().map(|path| TaskPath::parse(path)).collect(); config.include_default_paths = flags.include_default_paths; config.rustc_error_format = flags.rustc_error_format; config.json_output = flags.json_output; diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index a46a4e63714c2..66b63cd1278c5 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -16,7 +16,7 @@ use std::process::Command; use build_helper::{output, t}; -use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::TargetSelection; @@ -1368,7 +1368,7 @@ impl Step for Extended { let mut built_tools = HashSet::new(); macro_rules! add_component { ($name:expr => $step:expr) => { - if let Some(tarball) = builder.ensure_if_default($step) { + if let Some(tarball) = builder.ensure_if_default($step, Kind::Dist) { tarballs.push(tarball); built_tools.insert($name); } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index f0f31c447bda4..23b5ddcd47a0e 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -15,7 +15,7 @@ use std::path::{Path, PathBuf}; use crate::Mode; use build_helper::{t, up_to_date}; -use crate::builder::{Builder, Compiler, RunConfig, ShouldRun, Step}; +use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; use crate::config::{Config, TargetSelection}; @@ -240,7 +240,7 @@ impl Step for TheBook { invoke_rustdoc(builder, compiler, target, path); } - if builder.was_invoked_explicitly::() { + if builder.was_invoked_explicitly::(Kind::Doc) { let out = builder.doc_out(target); let index = out.join("book").join("index.html"); open(builder, &index); @@ -400,7 +400,7 @@ impl Step for Standalone { // We open doc/index.html as the default if invoked as `x.py doc --open` // with no particular explicit doc requested (e.g. library/core). - if builder.paths.is_empty() || builder.was_invoked_explicitly::() { + if builder.paths.is_empty() || builder.was_invoked_explicitly::(Kind::Doc) { let index = out.join("index.html"); open(builder, &index); } @@ -902,7 +902,7 @@ impl Step for RustcBook { name: INTERNER.intern_str("rustc"), src: INTERNER.intern_path(out_base), }); - if builder.was_invoked_explicitly::() { + if builder.was_invoked_explicitly::(Kind::Doc) { let out = builder.doc_out(self.target); let index = out.join("rustc").join("index.html"); open(builder, &index); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index bdd8aa430b2d1..2c937aa0ec928 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -671,7 +671,6 @@ nav.sub { margin: .5em 0; width: calc(100% - 2px); overflow-x: auto; - overflow-wrap: normal; display: block; } @@ -858,6 +857,31 @@ h2.small-section-header > .anchor { .block a.current.crate { font-weight: 500; } +/* In most contexts we use `overflow-wrap: anywhere` to ensure that we can wrap + as much as needed on mobile (see + src/test/rustdoc-gui/type-declaration-overflow.goml for an example of why + this matters). The `anywhere` value means: + + "Soft wrap opportunities introduced by the word break are considered when + calculating min-content intrinsic sizes." + + https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap#values + + For table layouts, that becomes a problem: the browser tries to make each + column as narrow as possible, and `overflow-wrap: anywhere` means it can do + so by breaking words - even if some other column could be shrunk without + breaking words! This shows up, for instance, in the `Structs` / `Modules` / + `Functions` (etcetera) sections of a module page, and when a docblock + contains a table. + + So, for table layouts, override the default with break-word, which does + _not_ affect min-content intrinsic sizes. +*/ +table, +.item-table { + overflow-wrap: break-word; +} + .item-table { display: table; } @@ -2058,10 +2082,6 @@ details.rustdoc-toggle[open] > summary.hideme::after { overflow-wrap: anywhere; } - .docblock table code { - overflow-wrap: normal; - } - .sub-container { flex-direction: column; } diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir index bfc85e98786b8..975e2ffbf01e7 100644 --- a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir +++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -2,8 +2,8 @@ | Free Region Mapping | '_#0r | Global | ['_#2r, '_#1r, '_#0r, '_#4r, '_#3r] -| '_#1r | External | ['_#1r, '_#4r] -| '_#2r | External | ['_#2r, '_#1r, '_#4r] +| '_#1r | Local | ['_#1r, '_#4r] +| '_#2r | Local | ['_#2r, '_#1r, '_#4r] | '_#3r | Local | ['_#4r, '_#3r] | '_#4r | Local | ['_#4r] | diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index 79354ec874507..73013c9778f64 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -39,7 +39,6 @@ impl Trait for Foo { const Y: u32 = 0; } - impl implementors::Whatever for Foo { type Foo = u32; } @@ -58,8 +57,10 @@ pub mod sub_mod { pub mod long_trait { use std::ops::DerefMut; - pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem: DerefMut - + From + Send + Sync + AsRef + 'static {} + pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem: + DerefMut + From + Send + Sync + AsRef + 'static + { + } } pub mod long_table { @@ -88,18 +89,28 @@ pub mod summary_table { } pub mod too_long { -pub type ReallyLongTypeNameLongLongLong = Option *const u8>; - -pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0; - -pub struct SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { - pub a: u32, -} + pub type ReallyLongTypeNameLongLongLong = + Option *const u8>; + + pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0; + + /// This also has a really long doccomment. Lorem ipsum dolor sit amet, + /// consectetur adipiscing elit. Suspendisse id nibh malesuada, hendrerit + /// massa vel, tincidunt est. Nulla interdum, sem ac efficitur ornare, arcu + /// nunc dignissim nibh, at rutrum diam augue ac mauris. Fusce tincidunt et + /// ligula sed viverra. Aenean sed facilisis dui, non volutpat felis. In + /// vitae est dui. Donec felis nibh, blandit at nibh eu, tempor suscipit + /// nisl. Vestibulum ornare porta libero, eu faucibus purus iaculis ut. Ut + /// quis tincidunt nunc, in mollis purus. Nulla sed interdum quam. Nunc + /// vitae cursus ex. + pub struct SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { + pub a: u32, + } -impl SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { - /// ``` - /// let x = SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { a: 0 }; - /// ``` + impl SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { + /// ``` + /// let x = SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { a: 0 }; + /// ``` pub fn foo(&self) {} } } diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml index 21874f786f1ad..c35b38747dfaf 100644 --- a/src/test/rustdoc-gui/type-declation-overflow.goml +++ b/src/test/rustdoc-gui/type-declation-overflow.goml @@ -7,6 +7,10 @@ assert-property: ("body", {"scrollWidth": "1100"}) // However, since there is overflow in the type declaration, its scroll width is bigger. assert-property: (".item-decl pre", {"scrollWidth": "1324"}) +// In the table-ish view on the module index, the name should not be wrapped more than necessary. +goto: file://|DOC_PATH|/lib2/too_long/index.html +assert-property: (".item-table .struct", {"offsetWidth": "684"}) + // We now make the same check on type declaration... goto: file://|DOC_PATH|/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html assert-property: ("body", {"scrollWidth": "1100"}) diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index 4b03fe1549413..ff4da5251a9b2 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -20,7 +20,7 @@ LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f | | | lifetime `'f` defined here LL | ap - | ^^ returning this value requires that `'1` must outlive `'f` + | ^^ function was supposed to return data with lifetime `'f` but it is returning data with lifetime `'1` | = note: requirement occurs because of the type VaListImpl<'_>, which makes the generic argument '_ invariant = note: the struct VaListImpl<'f> is invariant over the parameter 'f diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-1.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-1.rs index 36dd78dd2b19a..d20e79b9db338 100644 --- a/src/test/ui/conditional-compilation/cfg-arg-invalid-1.rs +++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-1.rs @@ -1,3 +1,3 @@ // compile-flags: --cfg a(b=c) -// error-pattern: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`) +// error-pattern: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\") fn main() {} diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-1.stderr b/src/test/ui/conditional-compilation/cfg-arg-invalid-1.stderr index 1e7922a9ff155..3a12e97868000 100644 --- a/src/test/ui/conditional-compilation/cfg-arg-invalid-1.stderr +++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-1.stderr @@ -1,2 +1,2 @@ -error: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`) +error: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\") diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-9.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-9.rs new file mode 100644 index 0000000000000..628b335c87302 --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-9.rs @@ -0,0 +1,4 @@ +// Test for missing quotes around value, issue #66450. +// compile-flags: --cfg key=value +// error-pattern: invalid `--cfg` argument: `key=value` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\") +fn main() {} diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-9.stderr b/src/test/ui/conditional-compilation/cfg-arg-invalid-9.stderr new file mode 100644 index 0000000000000..985b525225839 --- /dev/null +++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-9.stderr @@ -0,0 +1,2 @@ +error: invalid `--cfg` argument: `key=value` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\") + diff --git a/src/test/ui/fn/implied-bounds-unnorm-associated-type.nll.stderr b/src/test/ui/fn/implied-bounds-unnorm-associated-type.nll.stderr index e37ec7f26651c..8096f08385c8c 100644 --- a/src/test/ui/fn/implied-bounds-unnorm-associated-type.nll.stderr +++ b/src/test/ui/fn/implied-bounds-unnorm-associated-type.nll.stderr @@ -6,7 +6,7 @@ LL | fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str { | | | lifetime `'a` defined here LL | s - | ^ returning this value requires that `'b` must outlive `'a` + | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` diff --git a/src/test/ui/issues/issue-16683.nll.stderr b/src/test/ui/issues/issue-16683.nll.stderr index 0e8f520353fba..fff681b2e0b76 100644 --- a/src/test/ui/issues/issue-16683.nll.stderr +++ b/src/test/ui/issues/issue-16683.nll.stderr @@ -1,20 +1,13 @@ -error[E0521]: borrowed data escapes outside of associated function +error: lifetime may not live long enough --> $DIR/issue-16683.rs:4:9 | LL | trait T<'a> { | -- lifetime `'a` defined here LL | fn a(&'a self) -> &'a bool; LL | fn b(&self) { - | ----- - | | - | `self` is a reference that is only valid in the associated function body - | let's call the lifetime of this reference `'1` + | - let's call the lifetime of this reference `'1` LL | self.a(); - | ^^^^^^^^ - | | - | `self` escapes the associated function body here - | argument requires that `'1` must outlive `'a` + | ^^^^^^^^ argument requires that `'1` must outlive `'a` error: aborting due to previous error -For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/issues/issue-17758.nll.stderr b/src/test/ui/issues/issue-17758.nll.stderr index b929fdbf3687a..613ef6b907c54 100644 --- a/src/test/ui/issues/issue-17758.nll.stderr +++ b/src/test/ui/issues/issue-17758.nll.stderr @@ -1,20 +1,13 @@ -error[E0521]: borrowed data escapes outside of associated function +error: lifetime may not live long enough --> $DIR/issue-17758.rs:7:9 | LL | trait Foo<'a> { | -- lifetime `'a` defined here LL | fn foo(&'a self); LL | fn bar(&self) { - | ----- - | | - | `self` is a reference that is only valid in the associated function body - | let's call the lifetime of this reference `'1` + | - let's call the lifetime of this reference `'1` LL | self.foo(); - | ^^^^^^^^^^ - | | - | `self` escapes the associated function body here - | argument requires that `'1` must outlive `'a` + | ^^^^^^^^^^ argument requires that `'1` must outlive `'a` error: aborting due to previous error -For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/issues/issue-47377.stderr b/src/test/ui/issues/issue-47377.stderr index a7b8b1ca86167..4f0fd948e7604 100644 --- a/src/test/ui/issues/issue-47377.stderr +++ b/src/test/ui/issues/issue-47377.stderr @@ -7,10 +7,11 @@ LL | let _a = b + ", World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let _a = b.to_owned() + ", World!"; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-47380.stderr b/src/test/ui/issues/issue-47380.stderr index f6222c77e2e25..b04ac5536c41f 100644 --- a/src/test/ui/issues/issue-47380.stderr +++ b/src/test/ui/issues/issue-47380.stderr @@ -7,10 +7,11 @@ LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-5100.stderr b/src/test/ui/issues/issue-5100.stderr index de71e1d1a6666..c87a3e348a2e9 100644 --- a/src/test/ui/issues/issue-5100.stderr +++ b/src/test/ui/issues/issue-5100.stderr @@ -59,10 +59,8 @@ LL | &(true, false) => () error[E0618]: expected function, found `(char, char)` --> $DIR/issue-5100.rs:48:14 | -LL | let v = [('a', 'b') - | ______________-^^^^^^^^^ -LL | | ('c', 'd'), - | |_______________________- call expression requires function +LL | let v = [('a', 'b') + | ^^^^^^^^^^- help: consider separating array elements with a comma: `,` error[E0308]: mismatched types --> $DIR/issue-5100.rs:55:19 diff --git a/src/test/ui/issues/issue-52213.nll.stderr b/src/test/ui/issues/issue-52213.nll.stderr index 359f91309d4f3..da31bcd547507 100644 --- a/src/test/ui/issues/issue-52213.nll.stderr +++ b/src/test/ui/issues/issue-52213.nll.stderr @@ -7,7 +7,7 @@ LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { | lifetime `'a` defined here LL | match (&t,) { LL | ((u,),) => u, - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/match/match-ref-mut-invariance.nll.stderr b/src/test/ui/match/match-ref-mut-invariance.nll.stderr index 1dc29d2088cea..c8a7876dc54c2 100644 --- a/src/test/ui/match/match-ref-mut-invariance.nll.stderr +++ b/src/test/ui/match/match-ref-mut-invariance.nll.stderr @@ -6,7 +6,7 @@ LL | impl<'b> S<'b> { LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | -- lifetime `'a` defined here LL | match self.0 { ref mut x => x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` = note: requirement occurs because of a mutable reference to &i32 diff --git a/src/test/ui/match/match-ref-mut-let-invariance.nll.stderr b/src/test/ui/match/match-ref-mut-let-invariance.nll.stderr index 8b87c3da28b02..11ddf1487dd7a 100644 --- a/src/test/ui/match/match-ref-mut-let-invariance.nll.stderr +++ b/src/test/ui/match/match-ref-mut-let-invariance.nll.stderr @@ -7,7 +7,7 @@ LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | -- lifetime `'a` defined here LL | let ref mut x = self.0; LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` = note: requirement occurs because of a mutable reference to &i32 diff --git a/src/test/ui/nll/issue-52113.stderr b/src/test/ui/nll/issue-52113.stderr index dcf0338673483..f70ae2edd7fac 100644 --- a/src/test/ui/nll/issue-52113.stderr +++ b/src/test/ui/nll/issue-52113.stderr @@ -7,7 +7,7 @@ LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> i | lifetime `'a` defined here ... LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/nll/issue-55394.nll.stderr b/src/test/ui/nll/issue-55394.nll.stderr index d0723047ac08c..24b8c84b4a96a 100644 --- a/src/test/ui/nll/issue-55394.nll.stderr +++ b/src/test/ui/nll/issue-55394.nll.stderr @@ -6,7 +6,7 @@ LL | fn new(bar: &mut Bar) -> Self { | | | let's call the lifetime of this reference `'1` LL | Foo { bar } - | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` + | ^^^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/nll/issue-67007-escaping-data.rs b/src/test/ui/nll/issue-67007-escaping-data.rs index 8c21737e05fe8..99b6d512261b8 100644 --- a/src/test/ui/nll/issue-67007-escaping-data.rs +++ b/src/test/ui/nll/issue-67007-escaping-data.rs @@ -14,7 +14,7 @@ struct Consumer<'tcx>(&'tcx ()); impl<'tcx> Consumer<'tcx> { fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) { - let other = self.use_fcx(fcx); //~ ERROR borrowed data + let other = self.use_fcx(fcx); //~ ERROR lifetime may not live long enough fcx.use_it(other); } diff --git a/src/test/ui/nll/issue-67007-escaping-data.stderr b/src/test/ui/nll/issue-67007-escaping-data.stderr index 2834d6fb0d214..ce067e23aa34a 100644 --- a/src/test/ui/nll/issue-67007-escaping-data.stderr +++ b/src/test/ui/nll/issue-67007-escaping-data.stderr @@ -1,21 +1,14 @@ -error[E0521]: borrowed data escapes outside of associated function +error: lifetime may not live long enough --> $DIR/issue-67007-escaping-data.rs:17:21 | LL | impl<'tcx> Consumer<'tcx> { | ---- lifetime `'tcx` defined here LL | fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) { - | -- ----- --- `fcx` is a reference that is only valid in the associated function body - | | | - | | `self` declared here, outside of the associated function body - | lifetime `'a` defined here + | -- lifetime `'a` defined here LL | let other = self.use_fcx(fcx); - | ^^^^^^^^^^^^^^^^^ - | | - | `fcx` escapes the associated function body here - | argument requires that `'a` must outlive `'tcx` + | ^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'tcx` | = help: consider adding the following bound: `'a: 'tcx` error: aborting due to previous error -For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/nll/mir_check_cast_closure.stderr b/src/test/ui/nll/mir_check_cast_closure.stderr index 113e220e5137e..f34cafe308d3e 100644 --- a/src/test/ui/nll/mir_check_cast_closure.stderr +++ b/src/test/ui/nll/mir_check_cast_closure.stderr @@ -7,7 +7,7 @@ LL | fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 { | lifetime `'a` defined here LL | let g: fn(_, _) -> _ = |_x, y| y; LL | g - | ^ returning this value requires that `'b` must outlive `'a` + | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` diff --git a/src/test/ui/nll/outlives-suggestion-more.stderr b/src/test/ui/nll/outlives-suggestion-more.stderr index a80e59d4822fb..7f98aa5801d07 100644 --- a/src/test/ui/nll/outlives-suggestion-more.stderr +++ b/src/test/ui/nll/outlives-suggestion-more.stderr @@ -6,7 +6,7 @@ LL | fn foo1<'a, 'b, 'c, 'd>(x: &'a usize, y: &'b usize) -> (&'c usize, &'d usiz | | | lifetime `'a` defined here LL | (x, y) - | ^^^^^^ returning this value requires that `'a` must outlive `'c` + | ^^^^^^ function was supposed to return data with lifetime `'c` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'c` @@ -18,7 +18,7 @@ LL | fn foo1<'a, 'b, 'c, 'd>(x: &'a usize, y: &'b usize) -> (&'c usize, &'d usiz | | | lifetime `'b` defined here LL | (x, y) - | ^^^^^^ returning this value requires that `'b` must outlive `'d` + | ^^^^^^ function was supposed to return data with lifetime `'d` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'd` @@ -35,7 +35,7 @@ LL | fn foo2<'a, 'b, 'c>(x: &'a usize, y: &'b usize) -> (&'c usize, &'static usi | | | lifetime `'a` defined here LL | (x, y) - | ^^^^^^ returning this value requires that `'a` must outlive `'c` + | ^^^^^^ function was supposed to return data with lifetime `'c` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'c` diff --git a/src/test/ui/nll/outlives-suggestion-simple.rs b/src/test/ui/nll/outlives-suggestion-simple.rs index 41e4d83aa9213..496cf92400c54 100644 --- a/src/test/ui/nll/outlives-suggestion-simple.rs +++ b/src/test/ui/nll/outlives-suggestion-simple.rs @@ -70,7 +70,7 @@ pub struct Foo2<'a> { impl<'a> Foo2<'a> { // should not produce outlives suggestions to name 'self fn get_bar(&self) -> Bar2 { - Bar2::new(&self) //~ERROR borrowed data escapes outside of associated function + Bar2::new(&self) //~ERROR lifetime may not live long enough } } diff --git a/src/test/ui/nll/outlives-suggestion-simple.stderr b/src/test/ui/nll/outlives-suggestion-simple.stderr index 3b2017d2d03a1..8e6e4f1a47623 100644 --- a/src/test/ui/nll/outlives-suggestion-simple.stderr +++ b/src/test/ui/nll/outlives-suggestion-simple.stderr @@ -6,7 +6,7 @@ LL | fn foo1<'a, 'b>(x: &'a usize) -> &'b usize { | | | lifetime `'a` defined here LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -53,7 +53,7 @@ LL | fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) { | lifetime `'a` defined here ... LL | (x, x) - | ^^^^^^ returning this value requires that `'a` must outlive `'b` + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -73,7 +73,7 @@ LL | impl<'a> Bar<'a> { LL | pub fn get<'b>(&self) -> &'b usize { | -- lifetime `'b` defined here LL | self.x - | ^^^^^^ returning this value requires that `'a` must outlive `'b` + | ^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -85,28 +85,20 @@ LL | impl<'a> Baz<'a> { LL | fn get<'b>(&'b self) -> &'a i32 { | -- lifetime `'b` defined here LL | self.x - | ^^^^^^ returning this value requires that `'b` must outlive `'a` + | ^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` -error[E0521]: borrowed data escapes outside of associated function +error: lifetime may not live long enough --> $DIR/outlives-suggestion-simple.rs:73:9 | LL | impl<'a> Foo2<'a> { | -- lifetime `'a` defined here LL | // should not produce outlives suggestions to name 'self LL | fn get_bar(&self) -> Bar2 { - | ----- - | | - | `self` declared here, outside of the associated function body - | `self` is a reference that is only valid in the associated function body - | let's call the lifetime of this reference `'1` + | - let's call the lifetime of this reference `'1` LL | Bar2::new(&self) - | ^^^^^^^^^^^^^^^^ - | | - | `self` escapes the associated function body here - | argument requires that `'1` must outlive `'a` + | ^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a` error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/nll/type-alias-free-regions.nll.stderr b/src/test/ui/nll/type-alias-free-regions.nll.stderr index bde73b0589416..45fd5a2f1d657 100644 --- a/src/test/ui/nll/type-alias-free-regions.nll.stderr +++ b/src/test/ui/nll/type-alias-free-regions.nll.stderr @@ -6,7 +6,7 @@ LL | impl<'a> FromBox<'a> for C<'a> { LL | fn from_box(b: Box) -> Self { | - has type `Box>` LL | C { f: b } - | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` + | ^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` error: lifetime may not live long enough --> $DIR/type-alias-free-regions.rs:27:9 @@ -16,7 +16,7 @@ LL | impl<'a> FromTuple<'a> for C<'a> { LL | fn from_tuple(b: (B,)) -> Self { | - has type `(Box<&'1 isize>,)` LL | C { f: Box::new(b.0) } - | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'a` + | ^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/type-check-pointer-coercions.stderr b/src/test/ui/nll/type-check-pointer-coercions.stderr index ccb3d33ac4064..b392c2007d398 100644 --- a/src/test/ui/nll/type-check-pointer-coercions.stderr +++ b/src/test/ui/nll/type-check-pointer-coercions.stderr @@ -6,7 +6,7 @@ LL | fn shared_to_const<'a, 'b>(x: &&'a i32) -> *const &'b i32 { | | | lifetime `'a` defined here LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -18,7 +18,7 @@ LL | fn unique_to_const<'a, 'b>(x: &mut &'a i32) -> *const &'b i32 { | | | lifetime `'a` defined here LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -47,7 +47,7 @@ LL | fn unique_to_mut<'a, 'b>(x: &mut &'a i32) -> *mut &'b i32 { | lifetime `'a` defined here LL | // Two errors because *mut is invariant LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` = note: requirement occurs because of a mutable pointer to &i32 @@ -64,7 +64,7 @@ LL | fn mut_to_const<'a, 'b>(x: *mut &'a i32) -> *const &'b i32 { | | | lifetime `'a` defined here LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -77,7 +77,7 @@ LL | fn array_elem<'a, 'b>(x: &'a i32) -> *const &'b i32 { | lifetime `'a` defined here ... LL | y - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -90,7 +90,7 @@ LL | fn array_coerce<'a, 'b>(x: &'a i32) -> *const [&'b i32; 3] { | lifetime `'a` defined here ... LL | y - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -103,7 +103,7 @@ LL | fn nested_array<'a, 'b>(x: &'a i32) -> *const [&'b i32; 2] { | lifetime `'a` defined here ... LL | y - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/nll/user-annotations/wf-self-type.stderr b/src/test/ui/nll/user-annotations/wf-self-type.stderr index 33bb1c519b16e..902b4c687554a 100644 --- a/src/test/ui/nll/user-annotations/wf-self-type.stderr +++ b/src/test/ui/nll/user-annotations/wf-self-type.stderr @@ -6,7 +6,7 @@ LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { | | | lifetime `'a` defined here LL | Foo::xmute(u) - | ^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` diff --git a/src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr index 900cdfca24438..61e96f59fed91 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-elision.nll.stderr @@ -7,7 +7,7 @@ LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { | lifetime `'a` defined here ... LL | ss - | ^^ returning this value requires that `'a` must outlive `'b` + | ^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/regions/region-object-lifetime-2.nll.stderr b/src/test/ui/regions/region-object-lifetime-2.nll.stderr index db45a03ad18fb..d95289f3f9def 100644 --- a/src/test/ui/regions/region-object-lifetime-2.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-2.nll.stderr @@ -6,7 +6,7 @@ LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { | | | lifetime `'a` defined here LL | x.borrowed() - | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + | ^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr index 7e8f78067e08a..92588819076d3 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr @@ -31,7 +31,7 @@ LL | fn d<'a,'b>(v: &'a [u8]) -> Box { | | | lifetime `'a` defined here LL | Box::new(v) - | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + | ^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr index 62032bcb6092c..246b6483c21a8 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr @@ -1,18 +1,13 @@ -error[E0521]: borrowed data escapes outside of function +error: lifetime may not live long enough --> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:5 | LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { - | -- -- - - `b` is a reference that is only valid in the function body - | | | | - | | | `a` declared here, outside of the function body - | | lifetime `'b` defined here + | -- -- lifetime `'b` defined here + | | | lifetime `'a` defined here LL | // Here the value provided for 'y is 'b, and hence 'b:'a does not hold. LL | f.method(b); - | ^^^^^^^^^^^ - | | - | `b` escapes the function body here - | argument requires that `'b` must outlive `'a` + | ^^^^^^^^^^^ argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` = note: requirement occurs because of the type Inv<'_>, which makes the generic argument '_ invariant @@ -21,4 +16,3 @@ LL | f.method(b); error: aborting due to previous error -For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/regions/regions-bounds.nll.stderr b/src/test/ui/regions/regions-bounds.nll.stderr index dd702755c7e7b..84226a5755319 100644 --- a/src/test/ui/regions/regions-bounds.nll.stderr +++ b/src/test/ui/regions/regions-bounds.nll.stderr @@ -6,7 +6,7 @@ LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { | | | lifetime `'a` defined here LL | return e; - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -18,7 +18,7 @@ LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { | | | lifetime `'a` defined here LL | return e; - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr index c2bd3bbf823d2..25566742099c2 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr @@ -7,7 +7,7 @@ LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'c` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'c` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'c` diff --git a/src/test/ui/regions/regions-creating-enums4.nll.stderr b/src/test/ui/regions/regions-creating-enums4.nll.stderr index dda374c90d937..91cf57e099df9 100644 --- a/src/test/ui/regions/regions-creating-enums4.nll.stderr +++ b/src/test/ui/regions/regions-creating-enums4.nll.stderr @@ -6,7 +6,7 @@ LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { | | | lifetime `'a` defined here LL | Ast::Add(x, y) - | ^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b` + | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/regions/regions-early-bound-error-method.nll.stderr b/src/test/ui/regions/regions-early-bound-error-method.nll.stderr index 4957bcf3f7371..7f10c051f2998 100644 --- a/src/test/ui/regions/regions-early-bound-error-method.nll.stderr +++ b/src/test/ui/regions/regions-early-bound-error-method.nll.stderr @@ -6,7 +6,7 @@ LL | impl<'a> Box<'a> { LL | fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize { | -- lifetime `'b` defined here LL | g2.get() - | ^^^^^^^^ returning this value requires that `'b` must outlive `'a` + | ^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr index 106d3df274435..f7c75033c0486 100644 --- a/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr @@ -9,7 +9,7 @@ LL | / match self.next { LL | | Some(ref next) => next.get(), LL | | None => &self.val LL | | } - | |_________^ returning this value requires that `'a` must outlive `'b` + | |_________^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/src/test/ui/regions/regions-infer-not-param.nll.stderr b/src/test/ui/regions/regions-infer-not-param.nll.stderr index e211f9d1391f9..3183aee23d936 100644 --- a/src/test/ui/regions/regions-infer-not-param.nll.stderr +++ b/src/test/ui/regions/regions-infer-not-param.nll.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/regions-infer-not-param.rs:15:54 | LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } - | -- -- lifetime `'b` defined here ^ returning this value requires that `'a` must outlive `'b` + | -- -- lifetime `'b` defined here ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | | | lifetime `'a` defined here | @@ -25,7 +25,7 @@ error: lifetime may not live long enough --> $DIR/regions-infer-not-param.rs:19:63 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } - | -- -- lifetime `'b` defined here ^ returning this value requires that `'a` must outlive `'b` + | -- -- lifetime `'b` defined here ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | | | lifetime `'a` defined here | diff --git a/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr b/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr index bf325d5601348..26f0fcae638d0 100644 --- a/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr +++ b/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr @@ -7,7 +7,7 @@ LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | lifetime `'a` defined here LL | // Without knowing 'a:'b, we can't coerce LL | x - | ^ returning this value requires that `'a` must outlive `'b` + | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` = note: requirement occurs because of a mutable reference to dyn Dummy @@ -23,7 +23,7 @@ LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dum | lifetime `'a` defined here LL | // We can't coerce because it is packed in `Wrapper` LL | x - | ^ returning this value requires that `'b` must outlive `'a` + | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` = note: requirement occurs because of a mutable reference to dyn Dummy diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index 92e86bf5d6c91..e2e7ce1ed18e7 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -7,10 +7,11 @@ LL | let x = "Hello " + "World!"; | | `+` cannot be used to concatenate two `&str` strings | &str | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let x = "Hello ".to_owned() + "World!"; - | ~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `World` to `World` --> $DIR/issue-39018.rs:8:26 @@ -46,10 +47,10 @@ LL | let x = "Hello " + "World!".to_owned(); | | `+` cannot be used to concatenate a `&str` with a `String` | &str | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left +help: create an owned `String` on the left and add a borrow on the right | LL | let x = "Hello ".to_owned() + &"World!".to_owned(); - | ~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ + error[E0369]: cannot add `&String` to `&String` --> $DIR/issue-39018.rs:26:16 @@ -60,10 +61,12 @@ LL | let _ = &a + &b; | | `+` cannot be used to concatenate two `&str` strings | &String | -help: String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: remove the borrow to obtain an owned `String` | -LL | let _ = a + &b; - | ~ +LL - let _ = &a + &b; +LL + let _ = a + &b; + | error[E0369]: cannot add `String` to `&String` --> $DIR/issue-39018.rs:27:16 @@ -74,10 +77,11 @@ LL | let _ = &a + b; | | `+` cannot be used to concatenate a `&str` with a `String` | &String | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left +help: remove the borrow on the left and add one on the right | -LL | let _ = a + &b; - | ~ ~~ +LL - let _ = &a + b; +LL + let _ = a + &b; + | error[E0308]: mismatched types --> $DIR/issue-39018.rs:29:17 @@ -97,10 +101,10 @@ LL | let _ = e + b; | | `+` cannot be used to concatenate a `&str` with a `String` | &String | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left +help: create an owned `String` on the left and add a borrow on the right | LL | let _ = e.to_owned() + &b; - | ~~~~~~~~~~~~ ~~ + | +++++++++++ + error[E0369]: cannot add `&String` to `&String` --> $DIR/issue-39018.rs:31:15 @@ -111,10 +115,11 @@ LL | let _ = e + &b; | | `+` cannot be used to concatenate two `&str` strings | &String | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let _ = e.to_owned() + &b; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&str` to `&String` --> $DIR/issue-39018.rs:32:15 @@ -125,10 +130,11 @@ LL | let _ = e + d; | | `+` cannot be used to concatenate two `&str` strings | &String | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let _ = e.to_owned() + d; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&&str` to `&String` --> $DIR/issue-39018.rs:33:15 @@ -139,10 +145,11 @@ LL | let _ = e + &d; | | `+` cannot be used to concatenate two `&str` strings | &String | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let _ = e.to_owned() + &d; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&&str` to `&&str` --> $DIR/issue-39018.rs:34:16 @@ -169,10 +176,11 @@ LL | let _ = c + &d; | | `+` cannot be used to concatenate two `&str` strings | &str | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let _ = c.to_owned() + &d; - | ~~~~~~~~~~~~ + | +++++++++++ error[E0369]: cannot add `&str` to `&str` --> $DIR/issue-39018.rs:37:15 @@ -183,10 +191,11 @@ LL | let _ = c + d; | | `+` cannot be used to concatenate two `&str` strings | &str | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let _ = c.to_owned() + d; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to 14 previous errors diff --git a/src/test/ui/str/str-concat-on-double-ref.stderr b/src/test/ui/str/str-concat-on-double-ref.stderr index dee28897f4ddd..bd354679f7888 100644 --- a/src/test/ui/str/str-concat-on-double-ref.stderr +++ b/src/test/ui/str/str-concat-on-double-ref.stderr @@ -7,10 +7,11 @@ LL | let c = a + b; | | `+` cannot be used to concatenate two `&str` strings | &String | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let c = a.to_owned() + b; - | ~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr index 480f442fedd28..bf277362dbab2 100644 --- a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr +++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr @@ -7,10 +7,11 @@ LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔ | | `+` cannot be used to concatenate two `&str` strings | &str | -help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference | LL | let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!"; - | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++ error: aborting due to previous error diff --git a/src/test/ui/tuple/array-diagnostics.rs b/src/test/ui/tuple/array-diagnostics.rs new file mode 100644 index 0000000000000..1929dab073169 --- /dev/null +++ b/src/test/ui/tuple/array-diagnostics.rs @@ -0,0 +1,7 @@ +fn main() { + let _tmp = [ + ("C200B40A82", 3), + ("C200B40A83", 4) //~ ERROR: expected function, found `(&'static str, {integer})` [E0618] + ("C200B40A8537", 5), + ]; +} diff --git a/src/test/ui/tuple/array-diagnostics.stderr b/src/test/ui/tuple/array-diagnostics.stderr new file mode 100644 index 0000000000000..a10d7af470c7c --- /dev/null +++ b/src/test/ui/tuple/array-diagnostics.stderr @@ -0,0 +1,9 @@ +error[E0618]: expected function, found `(&'static str, {integer})` + --> $DIR/array-diagnostics.rs:4:9 + | +LL | ("C200B40A83", 4) + | ^^^^^^^^^^^^^^^^^- help: consider separating array elements with a comma: `,` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0618`. diff --git a/src/test/ui/variance/variance-contravariant-arg-object.nll.stderr b/src/test/ui/variance/variance-contravariant-arg-object.nll.stderr index 91d4fd2e971fa..3315eaaf1c006 100644 --- a/src/test/ui/variance/variance-contravariant-arg-object.nll.stderr +++ b/src/test/ui/variance/variance-contravariant-arg-object.nll.stderr @@ -7,7 +7,7 @@ LL | fn get_min_from_max<'min, 'max>(v: Box>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` @@ -20,7 +20,7 @@ LL | fn get_max_from_min<'min, 'max, G>(v: Box>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` diff --git a/src/test/ui/variance/variance-covariant-arg-object.nll.stderr b/src/test/ui/variance/variance-covariant-arg-object.nll.stderr index 37fdea960be7c..b116b8e263fd2 100644 --- a/src/test/ui/variance/variance-covariant-arg-object.nll.stderr +++ b/src/test/ui/variance/variance-covariant-arg-object.nll.stderr @@ -7,7 +7,7 @@ LL | fn get_min_from_max<'min, 'max>(v: Box>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` @@ -20,7 +20,7 @@ LL | fn get_max_from_min<'min, 'max, G>(v: Box>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` diff --git a/src/test/ui/variance/variance-invariant-arg-object.nll.stderr b/src/test/ui/variance/variance-invariant-arg-object.nll.stderr index f6265980af7da..303c7f3388a74 100644 --- a/src/test/ui/variance/variance-invariant-arg-object.nll.stderr +++ b/src/test/ui/variance/variance-invariant-arg-object.nll.stderr @@ -7,7 +7,7 @@ LL | fn get_min_from_max<'min, 'max>(v: Box>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` @@ -20,7 +20,7 @@ LL | fn get_max_from_min<'min, 'max, G>(v: Box>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` diff --git a/src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr b/src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr index eddd4b217c088..837c70ca31367 100644 --- a/src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr +++ b/src/test/ui/variance/variance-use-contravariant-struct-1.nll.stderr @@ -7,7 +7,7 @@ LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` diff --git a/src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr b/src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr index a86c1b93a73b8..bab858c5acb37 100644 --- a/src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr +++ b/src/test/ui/variance/variance-use-covariant-struct-1.nll.stderr @@ -7,7 +7,7 @@ LL | fn foo<'min,'max>(v: SomeStruct<&'min ()>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` diff --git a/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr b/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr index 6890cb115c398..f1df2a88b6bab 100644 --- a/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr +++ b/src/test/ui/variance/variance-use-invariant-struct-1.nll.stderr @@ -7,7 +7,7 @@ LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` = note: requirement occurs because of the type SomeStruct<&()>, which makes the generic argument &() invariant @@ -23,7 +23,7 @@ LL | fn bar<'min,'max>(v: SomeStruct<&'min ()>) | lifetime `'min` defined here ... LL | v - | ^ returning this value requires that `'min` must outlive `'max` + | ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min` | = help: consider adding the following bound: `'min: 'max` = note: requirement occurs because of the type SomeStruct<&()>, which makes the generic argument &() invariant diff --git a/src/test/ui/wf/wf-static-method.nll.stderr b/src/test/ui/wf/wf-static-method.nll.stderr index 9c066a7bdb06c..265043111956a 100644 --- a/src/test/ui/wf/wf-static-method.nll.stderr +++ b/src/test/ui/wf/wf-static-method.nll.stderr @@ -7,7 +7,7 @@ LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () { | lifetime `'a` defined here ... LL | u - | ^ returning this value requires that `'b` must outlive `'a` + | ^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` @@ -33,7 +33,7 @@ LL | impl<'a, 'b> Evil<'a, 'b> { | lifetime `'a` defined here LL | fn inherent_evil(u: &'b u32) -> &'a u32 { LL | u - | ^ returning this value requires that `'b` must outlive `'a` + | ^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` @@ -45,7 +45,7 @@ LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 { | | | lifetime `'a` defined here LL | <()>::static_evil(b) - | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` @@ -57,7 +57,7 @@ LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 { | | | lifetime `'a` defined here LL | ::static_evil(b) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` @@ -69,7 +69,7 @@ LL | fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 { | | | lifetime `'a` defined here LL | ::inherent_evil(b) - | ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a` + | ^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a`