Skip to content

Commit 207d955

Browse files
committed
Auto merge of rust-lang#89047 - GuillaumeGomez:rollup-29gmr02, r=GuillaumeGomez
Rollup of 10 pull requests Successful merges: - rust-lang#86422 (Emit clearer diagnostics for parens around `for` loop heads) - rust-lang#87460 (Point to closure when emitting 'cannot move out' for captured variable) - rust-lang#87566 (Recover invalid assoc type bounds using `==`) - rust-lang#88666 (Improve build command for compiler docs) - rust-lang#88899 (Do not issue E0071 if a type error has already been reported) - rust-lang#88949 (Fix handling of `hir::GenericArg::Infer` in `wrong_number_of_generic_args.rs`) - rust-lang#88953 (Add chown functions to std::os::unix::fs to change the owner and group of files) - rust-lang#88954 (Allow `panic!("{}", computed_str)` in const fn.) - rust-lang#88964 (Add rustdoc version into the help popup) - rust-lang#89012 (Suggest removing `#![feature]` for library features that have been stabilized) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents e0c38af + 101a88f commit 207d955

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+963
-330
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+6
Original file line numberDiff line numberDiff line change
@@ -702,10 +702,16 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
702702
}
703703

704704
fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
705+
// checks if `#![feature]` has been used to enable any lang feature
706+
// does not check the same for lib features unless there's at least one
707+
// declared lang feature
705708
use rustc_errors::Applicability;
706709

707710
if !sess.opts.unstable_features.is_nightly_build() {
708711
let lang_features = &sess.features_untracked().declared_lang_features;
712+
if lang_features.len() == 0 {
713+
return;
714+
}
709715
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
710716
let mut err = struct_span_err!(
711717
sess.parse_sess.span_diagnostic,

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -336,15 +336,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
336336
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
337337
{
338338
let closure_kind_ty = closure_substs.as_closure().kind_ty();
339-
let closure_kind = closure_kind_ty.to_opt_closure_kind();
340-
let capture_description = match closure_kind {
341-
Some(ty::ClosureKind::Fn) => "captured variable in an `Fn` closure",
342-
Some(ty::ClosureKind::FnMut) => "captured variable in an `FnMut` closure",
339+
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
340+
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
343341
Some(ty::ClosureKind::FnOnce) => {
344342
bug!("closure kind does not match first argument type")
345343
}
346344
None => bug!("closure kind not inferred by borrowck"),
347345
};
346+
let capture_description =
347+
format!("captured variable in an `{}` closure", closure_kind);
348348

349349
let upvar = &self.upvars[upvar_field.unwrap().index()];
350350
let upvar_hir_id = upvar.place.get_root_variable();
@@ -368,6 +368,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
368368
let mut diag = self.cannot_move_out_of(span, &place_description);
369369

370370
diag.span_label(upvar_span, "captured outer variable");
371+
diag.span_label(
372+
self.body.span,
373+
format!("captured by this `{}` closure", closure_kind),
374+
);
371375

372376
diag
373377
}

compiler/rustc_const_eval/src/const_eval/machine.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,17 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
3636
let def_id = instance.def_id();
3737
if Some(def_id) == self.tcx.lang_items().panic_fn()
3838
|| Some(def_id) == self.tcx.lang_items().panic_str()
39+
|| Some(def_id) == self.tcx.lang_items().panic_display()
3940
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
4041
{
41-
// &str
42+
// &str or &&str
4243
assert!(args.len() == 1);
4344

44-
let msg_place = self.deref_operand(&args[0])?;
45+
let mut msg_place = self.deref_operand(&args[0])?;
46+
while msg_place.layout.ty.is_ref() {
47+
msg_place = self.deref_operand(&msg_place.into())?;
48+
}
49+
4550
let msg = Symbol::intern(self.read_str(&msg_place)?);
4651
let span = self.find_closest_untracked_caller_location();
4752
let (file, line, col) = self.location_triple_for_span(span);

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+13
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,10 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
888888
if is_lang_panic_fn(tcx, callee) {
889889
self.check_op(ops::Panic);
890890

891+
// `begin_panic` and `panic_display` are generic functions that accept
892+
// types other than str. Check to enforce that only str can be used in
893+
// const-eval.
894+
891895
// const-eval of the `begin_panic` fn assumes the argument is `&str`
892896
if Some(callee) == tcx.lang_items().begin_panic_fn() {
893897
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
@@ -896,6 +900,15 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
896900
}
897901
}
898902

903+
// const-eval of the `panic_display` fn assumes the argument is `&&str`
904+
if Some(callee) == tcx.lang_items().panic_display() {
905+
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
906+
ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
907+
{}
908+
_ => self.check_op(ops::PanicNonStr),
909+
}
910+
}
911+
899912
return;
900913
}
901914

compiler/rustc_const_eval/src/transform/check_consts/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
7979
// Keep in sync with what that function handles!
8080
Some(def_id) == tcx.lang_items().panic_fn()
8181
|| Some(def_id) == tcx.lang_items().panic_str()
82+
|| Some(def_id) == tcx.lang_items().panic_display()
8283
|| Some(def_id) == tcx.lang_items().begin_panic_fn()
8384
|| Some(def_id) == tcx.lang_items().panic_fmt()
8485
|| Some(def_id) == tcx.lang_items().begin_panic_fmt()

compiler/rustc_error_codes/src/error_codes/E0071.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ form of initializer was used.
1515
For example, the code above can be fixed to:
1616

1717
```
18-
enum Foo {
19-
FirstValue(i32)
20-
}
18+
type U32 = u32;
19+
let t: U32 = 4;
20+
```
2121

22-
fn main() {
23-
let u = Foo::FirstValue(0i32);
22+
or:
2423

25-
let t = 4;
26-
}
24+
```
25+
struct U32 { value: u32 }
26+
let t = U32 { value: 4 };
2727
```

compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ language_item_table! {
283283
// a weak lang item, but do not have it defined.
284284
Panic, sym::panic, panic_fn, Target::Fn, GenericRequirement::None;
285285
PanicFmt, sym::panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None;
286+
PanicDisplay, sym::panic_display, panic_display, Target::Fn, GenericRequirement::None;
286287
PanicStr, sym::panic_str, panic_str, Target::Fn, GenericRequirement::None;
287288
ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None;
288289
PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::None;

compiler/rustc_parse/src/parser/diagnostics.rs

+26-19
Original file line numberDiff line numberDiff line change
@@ -1334,30 +1334,25 @@ impl<'a> Parser<'a> {
13341334
pub(super) fn recover_parens_around_for_head(
13351335
&mut self,
13361336
pat: P<Pat>,
1337-
expr: &Expr,
13381337
begin_paren: Option<Span>,
13391338
) -> P<Pat> {
13401339
match (&self.token.kind, begin_paren) {
13411340
(token::CloseDelim(token::Paren), Some(begin_par_sp)) => {
13421341
self.bump();
13431342

1344-
let pat_str = self
1345-
// Remove the `(` from the span of the pattern:
1346-
.span_to_snippet(pat.span.trim_start(begin_par_sp).unwrap())
1347-
.unwrap_or_else(|_| pprust::pat_to_string(&pat));
1348-
1349-
self.struct_span_err(self.prev_token.span, "unexpected closing `)`")
1350-
.span_label(begin_par_sp, "opening `(`")
1351-
.span_suggestion(
1352-
begin_par_sp.to(self.prev_token.span),
1353-
"remove parenthesis in `for` loop",
1354-
format!("{} in {}", pat_str, pprust::expr_to_string(&expr)),
1355-
// With e.g. `for (x) in y)` this would replace `(x) in y)`
1356-
// with `x) in y)` which is syntactically invalid.
1357-
// However, this is prevented before we get here.
1358-
Applicability::MachineApplicable,
1359-
)
1360-
.emit();
1343+
self.struct_span_err(
1344+
MultiSpan::from_spans(vec![begin_par_sp, self.prev_token.span]),
1345+
"unexpected parenthesis surrounding `for` loop head",
1346+
)
1347+
.multipart_suggestion(
1348+
"remove parenthesis in `for` loop",
1349+
vec![(begin_par_sp, String::new()), (self.prev_token.span, String::new())],
1350+
// With e.g. `for (x) in y)` this would replace `(x) in y)`
1351+
// with `x) in y)` which is syntactically invalid.
1352+
// However, this is prevented before we get here.
1353+
Applicability::MachineApplicable,
1354+
)
1355+
.emit();
13611356

13621357
// Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint.
13631358
pat.and_then(|pat| match pat.kind {
@@ -1955,7 +1950,19 @@ impl<'a> Parser<'a> {
19551950
}
19561951
match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
19571952
Ok(expr) => {
1958-
if token::Comma == self.token.kind || self.token.kind.should_end_const_arg() {
1953+
// Find a mistake like `MyTrait<Assoc == S::Assoc>`.
1954+
if token::EqEq == snapshot.token.kind {
1955+
err.span_suggestion(
1956+
snapshot.token.span,
1957+
"if you meant to use an associated type binding, replace `==` with `=`",
1958+
"=".to_string(),
1959+
Applicability::MaybeIncorrect,
1960+
);
1961+
let value = self.mk_expr_err(start.to(expr.span));
1962+
err.emit();
1963+
return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
1964+
} else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg()
1965+
{
19591966
// Avoid the following output by checking that we consumed a full const arg:
19601967
// help: expressions must be enclosed in braces to be used as const generic
19611968
// arguments

compiler/rustc_parse/src/parser/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2042,7 +2042,7 @@ impl<'a> Parser<'a> {
20422042
self.check_for_for_in_in_typo(self.prev_token.span);
20432043
let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
20442044

2045-
let pat = self.recover_parens_around_for_head(pat, &expr, begin_paren);
2045+
let pat = self.recover_parens_around_for_head(pat, begin_paren);
20462046

20472047
let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
20482048
attrs.extend(iattrs);

compiler/rustc_passes/src/stability.rs

+10
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,16 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
929929
let declared_lib_features = &tcx.features().declared_lib_features;
930930
let mut remaining_lib_features = FxHashMap::default();
931931
for (feature, span) in declared_lib_features {
932+
if !tcx.sess.opts.unstable_features.is_nightly_build() {
933+
struct_span_err!(
934+
tcx.sess,
935+
*span,
936+
E0554,
937+
"`#![feature]` may not be used on the {} release channel",
938+
env!("CFG_RELEASE_CHANNEL")
939+
)
940+
.emit();
941+
}
932942
if remaining_lib_features.contains_key(&feature) {
933943
// Warn if the user enables a lib feature multiple times.
934944
duplicate_feature_err(tcx.sess, *span, *feature);

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,7 @@ symbols! {
923923
panic_2021,
924924
panic_abort,
925925
panic_bounds_check,
926+
panic_display,
926927
panic_fmt,
927928
panic_handler,
928929
panic_impl,

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -532,15 +532,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
532532

533533
Some((variant, ty))
534534
} else {
535-
struct_span_err!(
536-
self.tcx.sess,
537-
path_span,
538-
E0071,
539-
"expected struct, variant or union type, found {}",
540-
ty.sort_string(self.tcx)
541-
)
542-
.span_label(path_span, "not a struct")
543-
.emit();
535+
match ty.kind() {
536+
ty::Error(_) => {
537+
// E0071 might be caused by a spelling error, which will have
538+
// already caused an error message and probably a suggestion
539+
// elsewhere. Refrain from emitting more unhelpful errors here
540+
// (issue #88844).
541+
}
542+
_ => {
543+
struct_span_err!(
544+
self.tcx.sess,
545+
path_span,
546+
E0071,
547+
"expected struct, variant or union type, found {}",
548+
ty.sort_string(self.tcx)
549+
)
550+
.span_label(path_span, "not a struct")
551+
.emit();
552+
}
553+
}
544554
None
545555
}
546556
}

compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
136136
AngleBrackets::Missing => 0,
137137
// Only lifetime arguments can be implied
138138
AngleBrackets::Implied => self.gen_args.args.len(),
139-
AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
140-
hir::GenericArg::Lifetime(_) => acc + 1,
141-
_ => acc,
142-
}),
139+
AngleBrackets::Available => self.gen_args.num_lifetime_params(),
143140
}
144141
}
145142

@@ -148,10 +145,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
148145
AngleBrackets::Missing => 0,
149146
// Only lifetime arguments can be implied
150147
AngleBrackets::Implied => 0,
151-
AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
152-
hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => acc + 1,
153-
_ => acc,
154-
}),
148+
AngleBrackets::Available => self.gen_args.num_generic_params(),
155149
}
156150
}
157151

@@ -651,7 +645,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
651645
let mut found_redundant = false;
652646
for arg in self.gen_args.args {
653647
match arg {
654-
hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => {
648+
hir::GenericArg::Type(_)
649+
| hir::GenericArg::Const(_)
650+
| hir::GenericArg::Infer(_) => {
655651
gen_arg_spans.push(arg.span());
656652
if gen_arg_spans.len() > self.num_expected_type_or_const_args() {
657653
found_redundant = true;

library/core/src/panic.rs

+9
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ pub macro panic_2015 {
2727
($msg:literal $(,)?) => (
2828
$crate::panicking::panic($msg)
2929
),
30+
// Use `panic_str` instead of `panic_display::<&str>` for non_fmt_panic lint.
3031
($msg:expr $(,)?) => (
3132
$crate::panicking::panic_str($msg)
3233
),
34+
// Special-case the single-argument case for const_panic.
35+
("{}", $arg:expr $(,)?) => (
36+
$crate::panicking::panic_display(&$arg)
37+
),
3338
($fmt:expr, $($arg:tt)+) => (
3439
$crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
3540
),
@@ -44,6 +49,10 @@ pub macro panic_2021 {
4449
() => (
4550
$crate::panicking::panic("explicit panic")
4651
),
52+
// Special-case the single-argument case for const_panic.
53+
("{}", $arg:expr $(,)?) => (
54+
$crate::panicking::panic_display(&$arg)
55+
),
4756
($($t:tt)+) => (
4857
$crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
4958
),

library/core/src/panicking.rs

+7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ pub fn panic_str(expr: &str) -> ! {
6060
panic_fmt(format_args!("{}", expr));
6161
}
6262

63+
#[inline]
64+
#[track_caller]
65+
#[cfg_attr(not(bootstrap), lang = "panic_display")] // needed for const-evaluated panics
66+
pub fn panic_display<T: fmt::Display>(x: &T) -> ! {
67+
panic_fmt(format_args!("{}", *x));
68+
}
69+
6370
#[cold]
6471
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
6572
#[track_caller]

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@
258258
#![feature(const_trait_impl)]
259259
#![feature(container_error_extra)]
260260
#![feature(core_intrinsics)]
261+
#![feature(core_panic)]
261262
#![feature(custom_test_frameworks)]
262263
#![feature(decl_macro)]
263264
#![feature(doc_cfg)]

0 commit comments

Comments
 (0)