Skip to content

Commit 5466718

Browse files
committed
Auto merge of #118387 - GuillaumeGomez:rollup-hbkx6nc, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - #111133 (Detect Python-like slicing and suggest how to fix) - #114708 (Allow setting `rla` labels via `rustbot`) - #117526 (Account for `!` arm in tail `match` expr) - #118341 (Simplify indenting in THIR printing) - #118366 (Detect and reject malformed `repr(Rust)` hints) - #118375 (Add -Zunpretty=stable-mir output test) - #118381 (rustc_span: Use correct edit distance start length for suggestions) - #118384 (Address unused tuple struct fields in rustdoc) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 49b3924 + bec9f90 commit 5466718

23 files changed

+440
-36
lines changed

compiler/rustc_ast/src/token.rs

+5
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,11 @@ impl Token {
756756
)
757757
}
758758

759+
/// Returns `true` if the token is the integer literal.
760+
pub fn is_integer_lit(&self) -> bool {
761+
matches!(self.kind, Literal(Lit { kind: LitKind::Integer, .. }))
762+
}
763+
759764
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
760765
pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool {
761766
match self.ident() {

compiler/rustc_attr/src/builtin.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
985985
Ok(literal) => acc.push(ReprPacked(literal)),
986986
Err(message) => literal_error = Some(message),
987987
};
988-
} else if matches!(name, sym::C | sym::simd | sym::transparent)
988+
} else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent)
989989
|| int_type_of_word(name).is_some()
990990
{
991991
recognised = true;
@@ -1018,7 +1018,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
10181018
});
10191019
} else if matches!(
10201020
meta_item.name_or_empty(),
1021-
sym::C | sym::simd | sym::transparent
1021+
sym::Rust | sym::C | sym::simd | sym::transparent
10221022
) || int_type_of_word(meta_item.name_or_empty()).is_some()
10231023
{
10241024
recognised = true;
@@ -1043,7 +1043,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
10431043
);
10441044
} else if matches!(
10451045
meta_item.name_or_empty(),
1046-
sym::C | sym::simd | sym::transparent
1046+
sym::Rust | sym::C | sym::simd | sym::transparent
10471047
) || int_type_of_word(meta_item.name_or_empty()).is_some()
10481048
{
10491049
recognised = true;

compiler/rustc_hir_typeck/src/_match.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
139139
&cause,
140140
Some(arm.body),
141141
arm_ty,
142-
|err| self.suggest_removing_semicolon_for_coerce(err, expr, arm_ty, prior_arm),
142+
|err| {
143+
self.explain_never_type_coerced_to_unit(err, arm, arm_ty, prior_arm, expr);
144+
},
143145
false,
144146
);
145147

@@ -177,6 +179,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
177179
coercion.complete(self)
178180
}
179181

182+
fn explain_never_type_coerced_to_unit(
183+
&self,
184+
err: &mut Diagnostic,
185+
arm: &hir::Arm<'tcx>,
186+
arm_ty: Ty<'tcx>,
187+
prior_arm: Option<(Option<hir::HirId>, Ty<'tcx>, Span)>,
188+
expr: &hir::Expr<'tcx>,
189+
) {
190+
if let hir::ExprKind::Block(block, _) = arm.body.kind
191+
&& let Some(expr) = block.expr
192+
&& let arm_tail_ty = self.node_ty(expr.hir_id)
193+
&& arm_tail_ty.is_never()
194+
&& !arm_ty.is_never()
195+
{
196+
err.span_label(
197+
expr.span,
198+
format!(
199+
"this expression is of type `!`, but it is coerced to `{arm_ty}` due to its \
200+
surrounding expression",
201+
),
202+
);
203+
self.suggest_mismatched_types_on_tail(
204+
err,
205+
expr,
206+
arm_ty,
207+
prior_arm.map_or(arm_tail_ty, |(_, ty, _)| ty),
208+
expr.hir_id,
209+
);
210+
}
211+
self.suggest_removing_semicolon_for_coerce(err, expr, arm_ty, prior_arm)
212+
}
213+
180214
fn suggest_removing_semicolon_for_coerce(
181215
&self,
182216
diag: &mut Diagnostic,

compiler/rustc_hir_typeck/src/coercion.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
17151715
// label pointing out the cause for the type coercion will be wrong
17161716
// as prior return coercions would not be relevant (#57664).
17171717
let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) {
1718+
fcx.suggest_missing_semicolon(&mut err, expr, expected, false);
17181719
let pointing_at_return_type =
17191720
fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id);
17201721
if let (Some(cond_expr), true, false) = (

compiler/rustc_hir_typeck/src/expr.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -663,8 +663,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663663
coerce.coerce_forced_unit(
664664
self,
665665
&cause,
666-
|err| {
667-
self.suggest_mismatched_types_on_tail(err, expr, ty, e_ty, target_id);
666+
|mut err| {
667+
self.suggest_missing_semicolon(&mut err, expr, e_ty, false);
668+
self.suggest_mismatched_types_on_tail(
669+
&mut err, expr, ty, e_ty, target_id,
670+
);
668671
let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty }));
669672
self.annotate_loop_expected_due_to_inference(err, expr, error);
670673
if let Some(val) = ty_kind_suggestion(ty) {

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7272
blk_id: hir::HirId,
7373
) -> bool {
7474
let expr = expr.peel_drop_temps();
75-
self.suggest_missing_semicolon(err, expr, expected, false);
7675
let mut pointing_at_return_type = false;
7776
if let hir::ExprKind::Break(..) = expr.kind {
7877
// `break` type mismatches provide better context for tail `loop` expressions.

compiler/rustc_mir_build/src/thir/print.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ const INDENT: &str = " ";
3131

3232
macro_rules! print_indented {
3333
($writer:ident, $s:expr, $indent_lvl:expr) => {
34-
let indent = (0..$indent_lvl).map(|_| INDENT).collect::<Vec<_>>().concat();
35-
writeln!($writer, "{}{}", indent, $s).expect("unable to write to ThirPrinter");
34+
$writer.indent($indent_lvl);
35+
writeln!($writer, "{}", $s).expect("unable to write to ThirPrinter");
3636
};
3737
}
3838

@@ -48,6 +48,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
4848
Self { thir, fmt: String::new() }
4949
}
5050

51+
fn indent(&mut self, level: usize) {
52+
for _ in 0..level {
53+
self.fmt.push_str(INDENT);
54+
}
55+
}
56+
5157
fn print(&mut self) {
5258
print_indented!(self, "params: [", 0);
5359
for param in self.thir.params.iter() {

compiler/rustc_parse/src/parser/stmt.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -567,20 +567,37 @@ impl<'a> Parser<'a> {
567567
snapshot.recover_diff_marker();
568568
}
569569
if self.token == token::Colon {
570-
// if next token is following a colon, it's likely a path
571-
// and we can suggest a path separator
572-
self.bump();
573-
if self.token.span.lo() == self.prev_token.span.hi() {
570+
// if a previous and next token of the current one is
571+
// integer literal (e.g. `1:42`), it's likely a range
572+
// expression for Pythonistas and we can suggest so.
573+
if self.prev_token.is_integer_lit()
574+
&& self.may_recover()
575+
&& self.look_ahead(1, |token| token.is_integer_lit())
576+
{
577+
// FIXME(hkmatsumoto): Might be better to trigger
578+
// this only when parsing an index expression.
574579
err.span_suggestion_verbose(
575-
self.prev_token.span,
576-
"maybe write a path separator here",
577-
"::",
580+
self.token.span,
581+
"you might have meant a range expression",
582+
"..",
578583
Applicability::MaybeIncorrect,
579584
);
580-
}
581-
if self.sess.unstable_features.is_nightly_build() {
582-
// FIXME(Nilstrieb): Remove this again after a few months.
583-
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
585+
} else {
586+
// if next token is following a colon, it's likely a path
587+
// and we can suggest a path separator
588+
self.bump();
589+
if self.token.span.lo() == self.prev_token.span.hi() {
590+
err.span_suggestion_verbose(
591+
self.prev_token.span,
592+
"maybe write a path separator here",
593+
"::",
594+
Applicability::MaybeIncorrect,
595+
);
596+
}
597+
if self.sess.unstable_features.is_nightly_build() {
598+
// FIXME(Nilstrieb): Remove this again after a few months.
599+
err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
600+
}
584601
}
585602
}
586603

compiler/rustc_span/src/edit_distance.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ fn find_best_match_for_name_impl(
188188
return Some(*c);
189189
}
190190

191-
let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
191+
// `fn edit_distance()` use `chars()` to calculate edit distance, so we must
192+
// also use `chars()` (and not `str::len()`) to calculate length here.
193+
let lookup_len = lookup.chars().count();
194+
195+
let mut dist = dist.unwrap_or_else(|| cmp::max(lookup_len, 3) / 3);
192196
let mut best = None;
193197
// store the candidates with the same distance, only for `use_substring_score` current.
194198
let mut next_candidates = vec![];

src/librustdoc/clean/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1821,11 +1821,8 @@ fn maybe_expand_private_type_alias<'tcx>(
18211821
}
18221822
_ => None,
18231823
});
1824-
if let Some(ct) = const_ {
1825-
args.insert(
1826-
param.def_id.to_def_id(),
1827-
SubstParam::Constant(clean_const(ct, cx)),
1828-
);
1824+
if let Some(_) = const_ {
1825+
args.insert(param.def_id.to_def_id(), SubstParam::Constant);
18291826
}
18301827
// FIXME(const_generics_defaults)
18311828
indices.consts += 1;

src/librustdoc/clean/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2546,7 +2546,7 @@ pub(crate) enum TypeBindingKind {
25462546
pub(crate) enum SubstParam {
25472547
Type(Type),
25482548
Lifetime(Lifetime),
2549-
Constant(Constant),
2549+
Constant,
25502550
}
25512551

25522552
impl SubstParam {

src/tools/tidy/src/ui_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
1111
const ENTRY_LIMIT: usize = 900;
1212
// FIXME: The following limits should be reduced eventually.
1313
const ISSUES_ENTRY_LIMIT: usize = 1852;
14-
const ROOT_ENTRY_LIMIT: usize = 867;
14+
const ROOT_ENTRY_LIMIT: usize = 868;
1515

1616
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
1717
"rs", // test source files
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fn never() -> ! {
2+
loop {}
3+
}
4+
5+
fn bar(a: bool) {
6+
match a {
7+
true => 1,
8+
false => {
9+
never() //~ ERROR `match` arms have incompatible types
10+
}
11+
}
12+
}
13+
fn main() {
14+
bar(true);
15+
bar(false);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0308]: `match` arms have incompatible types
2+
--> $DIR/match-tail-expr-never-type-error.rs:9:13
3+
|
4+
LL | fn bar(a: bool) {
5+
| - help: try adding a return type: `-> i32`
6+
LL | / match a {
7+
LL | | true => 1,
8+
| | - this is found to be of type `{integer}`
9+
LL | | false => {
10+
LL | | never()
11+
| | ^^^^^^^
12+
| | |
13+
| | expected integer, found `()`
14+
| | this expression is of type `!`, but it is coerced to `()` due to its surrounding expression
15+
LL | | }
16+
LL | | }
17+
| |_____- `match` arms have incompatible types
18+
19+
error: aborting due to 1 previous error
20+
21+
For more information about this error, try `rustc --explain E0308`.

tests/ui/repr/issue-83921-ice.rs renamed to tests/ui/repr/malformed-repr-hints.rs

+9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ struct S3;
1919
//~^ ERROR: incorrect `repr(align)` attribute format
2020
struct S4;
2121

22+
// Regression test for issue #118334:
23+
#[repr(Rust(u8))]
24+
//~^ ERROR: invalid representation hint
25+
#[repr(Rust(0))]
26+
//~^ ERROR: invalid representation hint
27+
#[repr(Rust = 0)]
28+
//~^ ERROR: invalid representation hint
29+
struct S5;
30+
2231
#[repr(i8())]
2332
//~^ ERROR: invalid representation hint
2433
enum E1 { A, B }
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,64 @@
11
error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
2-
--> $DIR/issue-83921-ice.rs:6:8
2+
--> $DIR/malformed-repr-hints.rs:6:8
33
|
44
LL | #[repr(packed())]
55
| ^^^^^^^^
66

77
error[E0589]: invalid `repr(align)` attribute: `align` needs an argument
8-
--> $DIR/issue-83921-ice.rs:10:8
8+
--> $DIR/malformed-repr-hints.rs:10:8
99
|
1010
LL | #[repr(align)]
1111
| ^^^^^ help: supply an argument here: `align(...)`
1212

1313
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
14-
--> $DIR/issue-83921-ice.rs:14:8
14+
--> $DIR/malformed-repr-hints.rs:14:8
1515
|
1616
LL | #[repr(align(2, 4))]
1717
| ^^^^^^^^^^^
1818

1919
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
20-
--> $DIR/issue-83921-ice.rs:18:8
20+
--> $DIR/malformed-repr-hints.rs:18:8
2121
|
2222
LL | #[repr(align())]
2323
| ^^^^^^^
2424

25+
error[E0552]: invalid representation hint: `Rust` does not take a parenthesized argument list
26+
--> $DIR/malformed-repr-hints.rs:23:8
27+
|
28+
LL | #[repr(Rust(u8))]
29+
| ^^^^^^^^
30+
31+
error[E0552]: invalid representation hint: `Rust` does not take a parenthesized argument list
32+
--> $DIR/malformed-repr-hints.rs:25:8
33+
|
34+
LL | #[repr(Rust(0))]
35+
| ^^^^^^^
36+
37+
error[E0552]: invalid representation hint: `Rust` does not take a value
38+
--> $DIR/malformed-repr-hints.rs:27:8
39+
|
40+
LL | #[repr(Rust = 0)]
41+
| ^^^^^^^^
42+
2543
error[E0552]: invalid representation hint: `i8` does not take a parenthesized argument list
26-
--> $DIR/issue-83921-ice.rs:22:8
44+
--> $DIR/malformed-repr-hints.rs:31:8
2745
|
2846
LL | #[repr(i8())]
2947
| ^^^^
3048

3149
error[E0552]: invalid representation hint: `u32` does not take a parenthesized argument list
32-
--> $DIR/issue-83921-ice.rs:26:8
50+
--> $DIR/malformed-repr-hints.rs:35:8
3351
|
3452
LL | #[repr(u32(42))]
3553
| ^^^^^^^
3654

3755
error[E0552]: invalid representation hint: `i64` does not take a value
38-
--> $DIR/issue-83921-ice.rs:30:8
56+
--> $DIR/malformed-repr-hints.rs:39:8
3957
|
4058
LL | #[repr(i64 = 2)]
4159
| ^^^^^^^
4260

43-
error: aborting due to 7 previous errors
61+
error: aborting due to 10 previous errors
4462

4563
Some errors have detailed explanations: E0552, E0589, E0693.
4664
For more information about an error, try `rustc --explain E0552`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// compile-flags: -Z unpretty=stable-mir
2+
// check-pass
3+
4+
fn foo(i:i32) -> i32 {
5+
i + 1
6+
}
7+
8+
fn bar(vec: &mut Vec<i32>) -> Vec<i32> {
9+
let mut new_vec = vec.clone();
10+
new_vec.push(1);
11+
new_vec
12+
}
13+
14+
fn main(){}

0 commit comments

Comments
 (0)