Skip to content

Rollup of 9 pull requests #87640

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

Merged
merged 21 commits into from
Jul 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
956fd10
Cross compiling rustc_llvm on Darwin requires zlib.
MarcusCalhoun-Lopez Jun 6, 2021
886dea2
Make `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` warn by default
Aaron1011 Jul 22, 2021
cf167c9
Only emit lint for local macros
Aaron1011 Jul 24, 2021
6954f9d
Update stderr
Aaron1011 Jul 27, 2021
e70ce57
Remove unnecessary trailing semicolons from clippy tests
Aaron1011 Jul 29, 2021
5b5391e
Add some TAIT-related regression tests
JohnTitor Jul 29, 2021
5cc7702
Add docs about performance and `Iterator::map` to `[T; N]::map`
LukasKalbertodt Jul 29, 2021
c2a365d
Fix missing word in comment
Wilfred Jul 30, 2021
1bbe618
Add missing examples for NonNull
GuillaumeGomez Jul 28, 2021
5d59b44
Add warning when whitespace is not skipped after an escaped newline.
jesyspa Jul 30, 2021
578fcbd
Fix error with suggestion for how to disambiguate associated function…
rylev Jul 28, 2021
17b2f92
Tweak borrowing suggestion in `for` loop
estebank Jul 28, 2021
9391d55
Rollup merge of #86072 - MarcusCalhoun-Lopez:llvm_cross, r=nagisa
JohnTitor Jul 30, 2021
f6bc738
Rollup merge of #87385 - Aaron1011:final-enable-semi, r=petrochenkov
JohnTitor Jul 30, 2021
f7a2a22
Rollup merge of #87547 - GuillaumeGomez:nonnull-examples, r=kennytm
JohnTitor Jul 30, 2021
fb27c4c
Rollup merge of #87557 - rylev:fix-invalid-prelude-collision-error, r…
JohnTitor Jul 30, 2021
5e2655d
Rollup merge of #87559 - estebank:consider-borrowing, r=oli-obk
JohnTitor Jul 30, 2021
aa9e6aa
Rollup merge of #87596 - jesyspa:issue-87318-hidden-whitespace, r=est…
JohnTitor Jul 30, 2021
2bdc54f
Rollup merge of #87606 - JohnTitor:tait-tests, r=oli-obk
JohnTitor Jul 30, 2021
f4dfb76
Rollup merge of #87609 - LukasKalbertodt:improve-array-map-docs, r=m-…
JohnTitor Jul 30, 2021
8d5291c
Rollup merge of #87616 - Wilfred:patch-1, r=jyn514
JohnTitor Jul 30, 2021
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
24 changes: 20 additions & 4 deletions compiler/rustc_ast/src/util/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ impl LitKind {
unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| {
match unescaped_char {
Ok(c) => buf.push(c),
Err(_) => error = Err(LitError::LexerError),
Err(err) => {
if err.is_fatal() {
error = Err(LitError::LexerError);
}
}
}
});
error?;
Expand All @@ -83,7 +87,11 @@ impl LitKind {
unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| {
match unescaped_char {
Ok(c) => buf.push(c),
Err(_) => error = Err(LitError::LexerError),
Err(err) => {
if err.is_fatal() {
error = Err(LitError::LexerError);
}
}
}
});
error?;
Expand All @@ -100,7 +108,11 @@ impl LitKind {
unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| {
match unescaped_byte {
Ok(c) => buf.push(c),
Err(_) => error = Err(LitError::LexerError),
Err(err) => {
if err.is_fatal() {
error = Err(LitError::LexerError);
}
}
}
});
error?;
Expand All @@ -114,7 +126,11 @@ impl LitKind {
unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| {
match unescaped_byte {
Ok(c) => buf.push(c),
Err(_) => error = Err(LitError::LexerError),
Err(err) => {
if err.is_fatal() {
error = Err(LitError::LexerError);
}
}
}
});
error?;
Expand Down
26 changes: 19 additions & 7 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ crate struct ParserAnyMacro<'a> {
lint_node_id: NodeId,
is_trailing_mac: bool,
arm_span: Span,
/// Whether or not this macro is defined in the current crate
is_local: bool,
}

crate fn annotate_err_with_kind(
Expand Down Expand Up @@ -124,6 +126,7 @@ impl<'a> ParserAnyMacro<'a> {
lint_node_id,
arm_span,
is_trailing_mac,
is_local,
} = *self;
let snapshot = &mut parser.clone();
let fragment = match parse_ast_fragment(parser, kind) {
Expand All @@ -138,13 +141,15 @@ impl<'a> ParserAnyMacro<'a> {
// `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
// but `m!()` is allowed in expression positions (cf. issue #34706).
if kind == AstFragmentKind::Expr && parser.token == token::Semi {
parser.sess.buffer_lint_with_diagnostic(
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
parser.token.span,
lint_node_id,
"trailing semicolon in macro used in expression position",
BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
);
if is_local {
parser.sess.buffer_lint_with_diagnostic(
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
parser.token.span,
lint_node_id,
"trailing semicolon in macro used in expression position",
BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
);
}
parser.bump();
}

Expand All @@ -162,6 +167,7 @@ struct MacroRulesMacroExpander {
lhses: Vec<mbe::TokenTree>,
rhses: Vec<mbe::TokenTree>,
valid: bool,
is_local: bool,
}

impl TTMacroExpander for MacroRulesMacroExpander {
Expand All @@ -183,6 +189,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
input,
&self.lhses,
&self.rhses,
self.is_local,
)
}
}
Expand Down Expand Up @@ -210,6 +217,7 @@ fn generic_extension<'cx>(
arg: TokenStream,
lhses: &[mbe::TokenTree],
rhses: &[mbe::TokenTree],
is_local: bool,
) -> Box<dyn MacResult + 'cx> {
let sess = &cx.sess.parse_sess;

Expand Down Expand Up @@ -311,6 +319,7 @@ fn generic_extension<'cx>(
lint_node_id: cx.current_expansion.lint_node_id,
is_trailing_mac: cx.current_expansion.is_trailing_mac,
arm_span,
is_local,
});
}
Failure(token, msg) => match best_failure {
Expand Down Expand Up @@ -544,6 +553,9 @@ pub fn compile_declarative_macro(
lhses,
rhses,
valid,
// Macros defined in the current crate have a real node id,
// whereas macros from an external crate have a dummy id.
is_local: def.id != DUMMY_NODE_ID,
}))
}

Expand Down
34 changes: 30 additions & 4 deletions compiler/rustc_lexer/src/unescape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::str::Chars;
#[cfg(test)]
mod tests;

/// Errors that can occur during string unescaping.
/// Errors and warnings that can occur during string unescaping.
#[derive(Debug, PartialEq, Eq)]
pub enum EscapeError {
/// Expected 1 char, but 0 were found.
Expand Down Expand Up @@ -56,6 +56,20 @@ pub enum EscapeError {
NonAsciiCharInByte,
/// Non-ascii character in byte string literal.
NonAsciiCharInByteString,

/// After a line ending with '\', the next line contains whitespace
/// characters that are not skipped.
UnskippedWhitespaceWarning,
}

impl EscapeError {
/// Returns true for actual errors, as opposed to warnings.
pub fn is_fatal(&self) -> bool {
match self {
EscapeError::UnskippedWhitespaceWarning => false,
_ => true,
}
}
}

/// Takes a contents of a literal (without quotes) and produces a
Expand Down Expand Up @@ -283,7 +297,7 @@ where
// if unescaped '\' character is followed by '\n'.
// For details see [Rust language reference]
// (https://doc.rust-lang.org/reference/tokens.html#string-literals).
skip_ascii_whitespace(&mut chars);
skip_ascii_whitespace(&mut chars, start, callback);
continue;
}
_ => scan_escape(first_char, &mut chars, mode),
Expand All @@ -297,13 +311,25 @@ where
callback(start..end, unescaped_char);
}

fn skip_ascii_whitespace(chars: &mut Chars<'_>) {
fn skip_ascii_whitespace<F>(chars: &mut Chars<'_>, start: usize, callback: &mut F)
where
F: FnMut(Range<usize>, Result<char, EscapeError>),
{
let str = chars.as_str();
let first_non_space = str
.bytes()
.position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r')
.unwrap_or(str.len());
*chars = str[first_non_space..].chars()
let tail = &str[first_non_space..];
if let Some(c) = tail.chars().nth(0) {
// For error reporting, we would like the span to contain the character that was not
// skipped. The +1 is necessary to account for the leading \ that started the escape.
let end = start + first_non_space + c.len_utf8() + 1;
if c.is_whitespace() {
callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning));
}
}
*chars = tail.chars();
}
}

Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_lexer/src/unescape/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,25 @@ fn test_unescape_char_good() {
check(r"\u{1F63b}", '😻');
}

#[test]
fn test_unescape_str_warn() {
fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
let mut unescaped = Vec::with_capacity(literal.len());
unescape_literal(literal, Mode::Str, &mut |range, res| unescaped.push((range, res)));
assert_eq!(unescaped, expected);
}

check(
"\\\n \u{a0} x",
&[
(0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
(3..5, Ok('\u{a0}')),
(5..6, Ok(' ')),
(6..7, Ok('x')),
],
);
}

#[test]
fn test_unescape_str_good() {
fn check(literal_text: &str, expected: &str) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2799,7 +2799,7 @@ declare_lint! {
/// [issue #79813]: https://github.com/rust-lang/rust/issues/79813
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
Allow,
Warn,
"trailing semicolon in macro body used as expression",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ fn main() {
} else if target.contains("windows-gnu") {
println!("cargo:rustc-link-lib=shell32");
println!("cargo:rustc-link-lib=uuid");
} else if target.contains("netbsd") || target.contains("haiku") {
} else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") {
println!("cargo:rustc-link-lib=z");
}
cmd.args(&components);
Expand Down
69 changes: 39 additions & 30 deletions compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_middle::mir::*;
use rustc_middle::ty;
use rustc_span::source_map::DesugaringKind;
use rustc_span::{sym, Span};
use rustc_span::{sym, Span, DUMMY_SP};
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;

use crate::borrow_check::diagnostics::UseSpans;
use crate::borrow_check::prefixes::PrefixSet;
Expand Down Expand Up @@ -384,36 +385,44 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}
};
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
let def_id = match *move_place.ty(self.body, self.infcx.tcx).ty.kind() {
ty::Adt(self_def, _) => self_def.did,
ty::Foreign(def_id)
| ty::FnDef(def_id, _)
| ty::Closure(def_id, _)
| ty::Generator(def_id, ..)
| ty::Opaque(def_id, _) => def_id,
_ => return err,
let ty = move_place.ty(self.body, self.infcx.tcx).ty;
let def_id = match *ty.kind() {
ty::Adt(self_def, _) => self_def.did,
ty::Foreign(def_id)
| ty::FnDef(def_id, _)
| ty::Closure(def_id, _)
| ty::Generator(def_id, ..)
| ty::Opaque(def_id, _) => def_id,
_ => return err,
};
let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
err.span_suggestion_verbose(
span.shrink_to_hi(),
&format!(
"consider borrowing the `{}`'s content",
if is_option { "Option" } else { "Result" }
),
".as_ref()".to_string(),
Applicability::MaybeIncorrect,
);
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) {
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
Some(def_id) => type_known_to_meet_bound_modulo_regions(
&self.infcx,
self.param_env,
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.lifetimes.re_erased, ty),
def_id,
DUMMY_SP,
),
_ => false,
};
let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
err.span_suggestion(
span,
&format!(
"consider borrowing the `{}`'s content",
if is_option { "Option" } else { "Result" }
),
format!("{}.as_ref()", snippet),
Applicability::MaybeIncorrect,
);
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_)))
&& self.infcx.tcx.is_diagnostic_item(sym::vec_type, def_id)
{
// FIXME: suggest for anything that implements `IntoIterator`.
err.span_suggestion(
span,
"consider iterating over a slice of the `Vec<_>`'s content",
format!("&{}", snippet),
if suggest {
err.span_suggestion_verbose(
span.shrink_to_lo(),
&format!("consider iterating over a slice of the `{}`'s content", ty),
"&".to_string(),
Applicability::MaybeIncorrect,
);
}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ pub(crate) fn emit_unescape_error(
let msg = "invalid trailing slash in literal";
handler.struct_span_err(span, msg).span_label(span, msg).emit();
}
EscapeError::UnskippedWhitespaceWarning => {
let (c, char_span) = last_char();
let msg =
format!("non-ASCII whitespace symbol '{}' is not skipped", c.escape_unicode());
handler.struct_span_warn(span, &msg).span_label(char_span, &msg).emit();
}
}
}

Expand Down
21 changes: 18 additions & 3 deletions compiler/rustc_typeck/src/check/method/prelude2021.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_ast::Mutability;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{Ref, Ty};
use rustc_middle::ty::{Adt, Ref, Ty};
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
use rustc_span::symbol::kw::Underscore;
use rustc_span::symbol::{sym, Ident};
Expand Down Expand Up @@ -255,16 +255,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
method_name.name
));

let self_ty = self
let self_ty_name = self
.sess()
.source_map()
.span_to_snippet(self_ty_span)
.unwrap_or_else(|_| self_ty.to_string());

let self_ty_generics_count = match self_ty.kind() {
// Get the number of generics the self type has (if an Adt) unless we can determine that
// the user has written the self type with generics already which we (naively) do by looking
// for a "<" in `self_ty_name`.
Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(),
_ => 0,
};
let self_ty_generics = if self_ty_generics_count > 0 {
format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
} else {
String::new()
};
lint.span_suggestion(
span,
"disambiguate the associated function",
format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
format!(
"<{}{} as {}>::{}",
self_ty_name, self_ty_generics, trait_name, method_name.name,
),
Applicability::MachineApplicable,
);

Expand Down
Loading