Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #122966

Merged
merged 38 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d3299af
transmute: caution against int2ptr transmutation
RalfJung Mar 12, 2024
982918f
Handle str literals written with `'` lexed as lifetime
estebank Mar 9, 2024
4a10b01
Use shorter span for existing `'` -> `"` structured suggestion
estebank Mar 9, 2024
999a0dc
review comment: `str` -> string in messages
estebank Mar 13, 2024
6f388ef
Extend test to trigger on 2015, 2018 and 2021 editions
estebank Mar 14, 2024
ea1883d
Silence redundant error on char literal that was meant to be a string…
estebank Mar 14, 2024
f4d30b1
fix rustdoc test
estebank Mar 17, 2024
f4adb1e
add notes on how to store 'ptr or int'
RalfJung Mar 14, 2024
1fcf2ea
Uniquify ReError on input mode in canonicalizer
compiler-errors Mar 22, 2024
da8a39a
Failing test
compiler-errors Mar 8, 2024
78ebb93
Fix validation on substituted callee bodies in MIR inliner
compiler-errors Mar 19, 2024
12e3629
add test for #99945
matthiaskrgr Mar 23, 2024
2f9a240
add test for opaque type with non-universal region substs #101852
matthiaskrgr Mar 23, 2024
e54bff7
add test for #104779 opaque types, patterns and subtyping ICE: Index…
matthiaskrgr Mar 23, 2024
f1f287f
add test for ICE "raw ptr comparison should already be caught in the…
matthiaskrgr Mar 23, 2024
f8aeac8
add test for #106423
matthiaskrgr Mar 23, 2024
cc422ce
add test for ICE #106444
matthiaskrgr Mar 23, 2024
f2bc9c5
add test for #106874 ICE BoundUniversalRegionError
matthiaskrgr Mar 23, 2024
368bfb2
add test for #107228
matthiaskrgr Mar 23, 2024
0d3ef80
`rustdoc --test`: Prevent reaching the maximum size of command-line b…
GuillaumeGomez Mar 21, 2024
33735d5
Prevent cloning more than necessary `RustdocOptions` fields
GuillaumeGomez Mar 22, 2024
86fe400
Put temporary directory into one common function
GuillaumeGomez Mar 23, 2024
773084f
Rename `RustdocTestOptions` into `IndividualTestOptions`
GuillaumeGomez Mar 23, 2024
9aea37d
address review feedback
matthiaskrgr Mar 23, 2024
246f746
Add test in `higher-ranked`
Luv-Ray Mar 23, 2024
188c46a
regression test for #103626
kadiwa4 Feb 19, 2024
5fab016
Add `Rustdoc` into `run-make-support`
GuillaumeGomez Mar 23, 2024
bc4f169
Add regression test for #122722
GuillaumeGomez Mar 23, 2024
e74b01e
core/panicking: fix outdated comment
RalfJung Mar 23, 2024
5167581
Rollup merge of #121281 - kadiwa4:test_103626, r=estebank,lcnr
matthiaskrgr Mar 24, 2024
3d9ee88
Rollup merge of #122168 - compiler-errors:inline-coroutine-body-valid…
matthiaskrgr Mar 24, 2024
1164c27
Rollup merge of #122217 - estebank:issue-119685, r=fmease
matthiaskrgr Mar 24, 2024
2dcc968
Rollup merge of #122379 - RalfJung:int2ptr-transmute, r=m-ou-se
matthiaskrgr Mar 24, 2024
73038c0
Rollup merge of #122840 - GuillaumeGomez:rustdoc-test-too-many-args, …
matthiaskrgr Mar 24, 2024
cb03714
Rollup merge of #122907 - compiler-errors:uniquify-reerror, r=lcnr
matthiaskrgr Mar 24, 2024
d8c2242
Rollup merge of #122942 - Luv-Ray:master, r=lcnr
matthiaskrgr Mar 24, 2024
2463ad0
Rollup merge of #122943 - matthiaskrgr:ice-tests-9xxxx-to-12xxxx, r=f…
matthiaskrgr Mar 24, 2024
6f16b41
Rollup merge of #122963 - RalfJung:core-panicking, r=m-ou-se
matthiaskrgr Mar 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
cfg_checker.check_cleanup_control_flow();

// Also run the TypeChecker.
for (location, msg) in validate_types(tcx, self.mir_phase, param_env, body) {
for (location, msg) in validate_types(tcx, self.mir_phase, param_env, body, body) {
cfg_checker.fail(location, msg);
}

Expand Down Expand Up @@ -541,19 +541,25 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {

/// A faster version of the validation pass that only checks those things which may break when
/// instantiating any generic parameters.
///
/// `caller_body` is used to detect cycles in MIR inlining and MIR validation before
/// `optimized_mir` is available.
pub fn validate_types<'tcx>(
tcx: TyCtxt<'tcx>,
mir_phase: MirPhase,
param_env: ty::ParamEnv<'tcx>,
body: &Body<'tcx>,
caller_body: &Body<'tcx>,
) -> Vec<(Location, String)> {
let mut type_checker = TypeChecker { body, tcx, param_env, mir_phase, failures: Vec::new() };
let mut type_checker =
TypeChecker { body, caller_body, tcx, param_env, mir_phase, failures: Vec::new() };
type_checker.visit_body(body);
type_checker.failures
}

struct TypeChecker<'a, 'tcx> {
body: &'a Body<'tcx>,
caller_body: &'a Body<'tcx>,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
mir_phase: MirPhase,
Expand Down Expand Up @@ -705,8 +711,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
&ty::Coroutine(def_id, args) => {
let f_ty = if let Some(var) = parent_ty.variant_index {
let gen_body = if def_id == self.body.source.def_id() {
self.body
// If we're currently validating an inlined copy of this body,
// then it will no longer be parameterized over the original
// args of the coroutine. Otherwise, we prefer to use this body
// since we may be in the process of computing this MIR in the
// first place.
let gen_body = if def_id == self.caller_body.source.def_id() {
self.caller_body
} else {
self.tcx.optimized_mir(def_id)
};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ infer_lifetime_param_suggestion_elided = each elided lifetime in input position

infer_meant_byte_literal = if you meant to write a byte literal, prefix with `b`
infer_meant_char_literal = if you meant to write a `char` literal, use single quotes
infer_meant_str_literal = if you meant to write a `str` literal, use double quotes
infer_meant_str_literal = if you meant to write a string literal, use double quotes
infer_mismatched_static_lifetime = incompatible lifetime on type
infer_more_targeted = {$has_param_name ->
[true] `{$param_name}`
Expand Down
13 changes: 5 additions & 8 deletions compiler/rustc_infer/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,15 +1339,12 @@ pub enum TypeErrorAdditionalDiags {
span: Span,
code: String,
},
#[suggestion(
infer_meant_str_literal,
code = "\"{code}\"",
applicability = "machine-applicable"
)]
#[multipart_suggestion(infer_meant_str_literal, applicability = "machine-applicable")]
MeantStrLiteral {
#[primary_span]
span: Span,
code: String,
#[suggestion_part(code = "\"")]
start: Span,
#[suggestion_part(code = "\"")]
end: Span,
},
#[suggestion(
infer_consider_specifying_length,
Expand Down
14 changes: 4 additions & 10 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2079,16 +2079,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// If a string was expected and the found expression is a character literal,
// perhaps the user meant to write `"s"` to specify a string literal.
(ty::Ref(_, r, _), ty::Char) if r.is_str() => {
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
if let Some(code) =
code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
{
suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral {
span,
code: escape_literal(code),
})
}
}
suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral {
start: span.with_hi(span.lo() + BytePos(1)),
end: span.with_lo(span.hi() - BytePos(1)),
})
}
// For code `if Some(..) = expr `, the type mismatch may be expected `bool` but found `()`,
// we try to suggest to add the missing `let` for `if let Some(..) = expr`
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_lexer/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<'a> Cursor<'a> {
/// If requested position doesn't exist, `EOF_CHAR` is returned.
/// However, getting `EOF_CHAR` doesn't always mean actual end of file,
/// it should be checked with `is_eof` method.
pub(crate) fn first(&self) -> char {
pub fn first(&self) -> char {
// `.next()` optimizes better than `.nth(0)`
self.chars.clone().next().unwrap_or(EOF_CHAR)
}
Expand All @@ -59,6 +59,15 @@ impl<'a> Cursor<'a> {
iter.next().unwrap_or(EOF_CHAR)
}

/// Peeks the third symbol from the input stream without consuming it.
pub fn third(&self) -> char {
// `.next()` optimizes better than `.nth(1)`
let mut iter = self.chars.clone();
iter.next();
iter.next();
iter.next().unwrap_or(EOF_CHAR)
}

/// Checks if there is nothing more to consume.
pub(crate) fn is_eof(&self) -> bool {
self.chars.as_str().is_empty()
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,9 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
let mut by_move_body = body.clone();
MakeByMoveBody { tcx, by_ref_fields, by_move_coroutine_ty }.visit_body(&mut by_move_body);
dump_mir(tcx, false, "coroutine_by_move", &0, &by_move_body, |_, _| Ok(()));
by_move_body.source = mir::MirSource {
instance: InstanceDef::CoroutineKindShim {
coroutine_def_id: coroutine_def_id.to_def_id(),
},
promoted: None,
};
by_move_body.source = mir::MirSource::from_instance(InstanceDef::CoroutineKindShim {
coroutine_def_id: coroutine_def_id.to_def_id(),
});
body.coroutine.as_mut().unwrap().by_move_body = Some(by_move_body);
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ impl<'tcx> Inliner<'tcx> {
MirPhase::Runtime(RuntimePhase::Optimized),
self.param_env,
&callee_body,
&caller_body,
)
.is_empty()
{
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_next_trait_solver/src/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
// FIXME: We should investigate the perf implications of not uniquifying
// `ReErased`. We may be able to short-circuit registering region
// obligations if we encounter a `ReErased` on one side, for example.
ty::ReStatic | ty::ReErased => match self.canonicalize_mode {
ty::ReStatic | ty::ReErased | ty::ReError(_) => match self.canonicalize_mode {
CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
CanonicalizeMode::Response { .. } => return r,
},
Expand Down Expand Up @@ -277,7 +277,6 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
}
}
}
ty::ReError(_) => return r,
};

let existing_bound_var = match self.canonicalize_mode {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ parse_more_than_one_char = character literal may only contain one codepoint
.remove_non = consider removing the non-printing characters
.use_double_quotes = if you meant to write a {$is_byte ->
[true] byte string
*[false] `str`
*[false] string
} literal, use double quotes

parse_multiple_skipped_lines = multiple lines skipped by escaped newline
Expand Down Expand Up @@ -833,6 +833,7 @@ parse_unknown_prefix = prefix `{$prefix}` is unknown
.label = unknown prefix
.note = prefixed identifiers and literals are reserved since Rust 2021
.suggestion_br = use `br` for a raw byte string
.suggestion_str = if you meant to write a string literal, use double quotes
.suggestion_whitespace = consider inserting whitespace here

parse_unknown_start_of_token = unknown start of token: {$escaped}
Expand Down
22 changes: 21 additions & 1 deletion compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,17 @@ pub enum UnknownPrefixSugg {
style = "verbose"
)]
Whitespace(#[primary_span] Span),
#[multipart_suggestion(
parse_suggestion_str,
applicability = "maybe-incorrect",
style = "verbose"
)]
MeantStr {
#[suggestion_part(code = "\"")]
start: Span,
#[suggestion_part(code = "\"")]
end: Span,
},
}

#[derive(Diagnostic)]
Expand Down Expand Up @@ -2198,12 +2209,21 @@ pub enum MoreThanOneCharSugg {
ch: String,
},
#[suggestion(parse_use_double_quotes, code = "{sugg}", applicability = "machine-applicable")]
Quotes {
QuotesFull {
#[primary_span]
span: Span,
is_byte: bool,
sugg: String,
},
#[multipart_suggestion(parse_use_double_quotes, applicability = "machine-applicable")]
Quotes {
#[suggestion_part(code = "{prefix}\"")]
start: Span,
#[suggestion_part(code = "\"")]
end: Span,
is_byte: bool,
prefix: &'static str,
},
}

#[derive(Subdiagnostic)]
Expand Down
57 changes: 52 additions & 5 deletions compiler/rustc_parse/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub(crate) fn parse_token_trees<'psess, 'src>(
cursor,
override_span,
nbsp_is_whitespace: false,
last_lifetime: None,
};
let (stream, res, unmatched_delims) =
tokentrees::TokenTreesReader::parse_all_token_trees(string_reader);
Expand Down Expand Up @@ -105,6 +106,10 @@ struct StringReader<'psess, 'src> {
/// in this file, it's safe to treat further occurrences of the non-breaking
/// space character as whitespace.
nbsp_is_whitespace: bool,

/// Track the `Span` for the leading `'` of the last lifetime. Used for
/// diagnostics to detect possible typo where `"` was meant.
last_lifetime: Option<Span>,
}

impl<'psess, 'src> StringReader<'psess, 'src> {
Expand All @@ -130,6 +135,18 @@ impl<'psess, 'src> StringReader<'psess, 'src> {

debug!("next_token: {:?}({:?})", token.kind, self.str_from(start));

if let rustc_lexer::TokenKind::Semi
| rustc_lexer::TokenKind::LineComment { .. }
| rustc_lexer::TokenKind::BlockComment { .. }
| rustc_lexer::TokenKind::CloseParen
| rustc_lexer::TokenKind::CloseBrace
| rustc_lexer::TokenKind::CloseBracket = token.kind
{
// Heuristic: we assume that it is unlikely we're dealing with an unterminated
// string surrounded by single quotes.
self.last_lifetime = None;
}

// Now "cook" the token, converting the simple `rustc_lexer::TokenKind` enum into a
// rich `rustc_ast::TokenKind`. This turns strings into interned symbols and runs
// additional validation.
Expand Down Expand Up @@ -247,6 +264,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
// expansion purposes. See #12512 for the gory details of why
// this is necessary.
let lifetime_name = self.str_from(start);
self.last_lifetime = Some(self.mk_sp(start, start + BytePos(1)));
if starts_with_number {
let span = self.mk_sp(start, self.pos);
self.dcx().struct_err("lifetimes cannot start with a number")
Expand Down Expand Up @@ -395,10 +413,21 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
match kind {
rustc_lexer::LiteralKind::Char { terminated } => {
if !terminated {
self.dcx()
let mut err = self
.dcx()
.struct_span_fatal(self.mk_sp(start, end), "unterminated character literal")
.with_code(E0762)
.emit()
.with_code(E0762);
if let Some(lt_sp) = self.last_lifetime {
err.multipart_suggestion(
"if you meant to write a string literal, use double quotes",
vec![
(lt_sp, "\"".to_string()),
(self.mk_sp(start, start + BytePos(1)), "\"".to_string()),
],
Applicability::MaybeIncorrect,
);
}
err.emit()
}
self.cook_unicode(token::Char, Mode::Char, start, end, 1, 1) // ' '
}
Expand Down Expand Up @@ -669,15 +698,33 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
let expn_data = prefix_span.ctxt().outer_expn_data();

if expn_data.edition >= Edition::Edition2021 {
let mut silence = false;
// In Rust 2021, this is a hard error.
let sugg = if prefix == "rb" {
Some(errors::UnknownPrefixSugg::UseBr(prefix_span))
} else if expn_data.is_root() {
Some(errors::UnknownPrefixSugg::Whitespace(prefix_span.shrink_to_hi()))
if self.cursor.first() == '\''
&& let Some(start) = self.last_lifetime
&& self.cursor.third() != '\''
{
// An "unclosed `char`" error will be emitted already, silence redundant error.
silence = true;
Some(errors::UnknownPrefixSugg::MeantStr {
start,
end: self.mk_sp(self.pos, self.pos + BytePos(1)),
})
} else {
Some(errors::UnknownPrefixSugg::Whitespace(prefix_span.shrink_to_hi()))
}
} else {
None
};
self.dcx().emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg });
let err = errors::UnknownPrefix { span: prefix_span, prefix, sugg };
if silence {
self.dcx().create_err(err).delay_as_bug();
} else {
self.dcx().emit_err(err);
}
} else {
// Before Rust 2021, only emit a lint for migration.
self.psess.buffer_lint_with_diagnostic(
Expand Down
20 changes: 15 additions & 5 deletions compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,21 @@ pub(crate) fn emit_unescape_error(
}
escaped.push(c);
}
let sugg = format!("{prefix}\"{escaped}\"");
MoreThanOneCharSugg::Quotes {
span: full_lit_span,
is_byte: mode == Mode::Byte,
sugg,
if escaped.len() != lit.len() || full_lit_span.is_empty() {
let sugg = format!("{prefix}\"{escaped}\"");
MoreThanOneCharSugg::QuotesFull {
span: full_lit_span,
is_byte: mode == Mode::Byte,
sugg,
}
} else {
MoreThanOneCharSugg::Quotes {
start: full_lit_span
.with_hi(full_lit_span.lo() + BytePos((prefix.len() + 1) as u32)),
end: full_lit_span.with_lo(full_lit_span.hi() - BytePos(1)),
is_byte: mode == Mode::Byte,
prefix,
}
}
});
dcx.emit_err(UnescapeError::MoreThanOneChar {
Expand Down
Loading
Loading