Skip to content

Commit

Permalink
Auto merge of #108934 - matthiaskrgr:rollup-vm414p5, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #106915 (Only load one CSS theme by default)
 - #108294 (Place binder correctly for arbitrary trait bound suggestion)
 - #108778 (x fmt: Don't print all modified files if there's more than 10)
 - #108854 (feat/refactor: improve errors in case of ident with number at start)
 - #108870 (Fix invalid inlining of reexport of reexport of private item)
 - #108917 (Consider target_family as pal)
 - #108922 (Add auto notification for changes to stable mir)
 - #108929 (Fix typo in span_map.rs)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 10, 2023
2 parents f37f854 + 5b3f84d commit 104f430
Show file tree
Hide file tree
Showing 25 changed files with 345 additions and 153 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
}

let param_name = trait_pred.skip_binder().self_ty().to_string();
let mut constraint = trait_pred.print_modifiers_and_trait_path().to_string();
let mut constraint = trait_pred.to_string();

if let Some((name, term)) = associated_ty {
// FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
Expand All @@ -144,7 +144,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
this requirement",
if generics.where_clause_span.is_empty() { "introducing a" } else { "extending the" },
),
format!("{} {}: {}", generics.add_where_or_trailing_comma(), param_name, constraint),
format!("{} {constraint}", generics.add_where_or_trailing_comma()),
Applicability::MaybeIncorrect,
);
true
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_parse/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,7 @@ parse_fn_ptr_with_generics = function pointer types may not have generic paramet
*[false] a
} `for` parameter list
parse_invalid_identifier_with_leading_number = expected identifier, found number literal
.label = identifiers cannot start with a number
parse_invalid_identifier_with_leading_number = identifiers cannot start with a number
parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn`
.suggestion = replace `fn` with `impl` here
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ pub(crate) struct ExpectedIdentifier {
pub token: Token,
pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
pub suggest_remove_comma: Option<SuggRemoveComma>,
pub help_cannot_start_number: Option<HelpIdentifierStartsWithNumber>,
}

impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
Expand Down Expand Up @@ -975,10 +976,18 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
sugg.add_to_diagnostic(&mut diag);
}

if let Some(help) = self.help_cannot_start_number {
help.add_to_diagnostic(&mut diag);
}

diag
}
}

#[derive(Subdiagnostic)]
#[help(parse_invalid_identifier_with_leading_number)]
pub(crate) struct HelpIdentifierStartsWithNumber;

pub(crate) struct ExpectedSemi {
pub span: Span,
pub token: Token,
Expand Down Expand Up @@ -1207,14 +1216,6 @@ pub(crate) struct SelfParamNotFirst {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_invalid_identifier_with_leading_number)]
pub(crate) struct InvalidIdentiferStartsWithNumber {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_const_generic_without_braces)]
pub(crate) struct ConstGenericWithoutBraces {
Expand Down
41 changes: 27 additions & 14 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use crate::errors::{
ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg,
ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentOnParamType,
DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, InInTypo,
IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, ParenthesesInForHead,
ParenthesesInForHeadSugg, PatternMethodParamWithoutBody, QuestionMarkInType,
QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath,
StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg,
SuggEscapeToUseAsIdentifier, SuggRemoveComma, UnexpectedConstInGenericParam,
UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets,
UseEqInstead,
GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg,
HelpIdentifierStartsWithNumber, InInTypo, IncorrectAwait, IncorrectSemicolon,
IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg,
PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens,
StructLiteralNeedingParensSugg, SuggEscapeToUseAsIdentifier, SuggRemoveComma,
UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead,
};

use crate::fluent_generated as fluent;
Expand Down Expand Up @@ -280,6 +280,7 @@ impl<'a> Parser<'a> {
TokenKind::CloseDelim(Delimiter::Brace),
TokenKind::CloseDelim(Delimiter::Parenthesis),
];

let suggest_raw = match self.token.ident() {
Some((ident, false))
if ident.is_raw_guess()
Expand All @@ -295,18 +296,19 @@ impl<'a> Parser<'a> {
_ => None,
};

let suggest_remove_comma =
if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
Some(SuggRemoveComma { span: self.token.span })
} else {
None
};
let suggest_remove_comma = (self.token == token::Comma
&& self.look_ahead(1, |t| t.is_ident()))
.then_some(SuggRemoveComma { span: self.token.span });

let help_cannot_start_number =
self.is_lit_bad_ident().then_some(HelpIdentifierStartsWithNumber);

let err = ExpectedIdentifier {
span: self.token.span,
token: self.token.clone(),
suggest_raw,
suggest_remove_comma,
help_cannot_start_number,
};
let mut err = err.into_diagnostic(&self.sess.span_diagnostic);

Expand Down Expand Up @@ -365,6 +367,17 @@ impl<'a> Parser<'a> {
err
}

/// Checks if the current token is a integer or float literal and looks like
/// it could be a invalid identifier with digits at the start.
pub(super) fn is_lit_bad_ident(&mut self) -> bool {
matches!(self.token.uninterpolate().kind, token::Literal(Lit { kind: token::LitKind::Integer | token::LitKind::Float, .. })
// ensure that the integer literal is followed by a *invalid*
// suffix: this is how we know that it is a identifier with an
// invalid beginning.
if rustc_ast::MetaItemLit::from_token(&self.token).is_none()
)
}

pub(super) fn expected_one_of_not_found(
&mut self,
edible: &[TokenKind],
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ impl<'a> Parser<'a> {
lo = self.token.span;
}

if self.is_lit_bad_ident() {
return Err(self.expected_ident_found());
}

let pat = if self.check(&token::BinOp(token::And)) || self.token.kind == token::AndAnd {
self.parse_pat_deref(expected)?
} else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
Expand Down
12 changes: 0 additions & 12 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ impl<'a> Parser<'a> {
self.bump();
}

self.report_invalid_identifier_error()?;
let (pat, colon) =
self.parse_pat_before_ty(None, RecoverComma::Yes, PatternLocation::LetBinding)?;

Expand Down Expand Up @@ -366,17 +365,6 @@ impl<'a> Parser<'a> {
Ok(P(ast::Local { ty, pat, kind, id: DUMMY_NODE_ID, span: lo.to(hi), attrs, tokens: None }))
}

/// report error for `let 1x = 123`
pub fn report_invalid_identifier_error(&mut self) -> PResult<'a, ()> {
if let token::Literal(lit) = self.token.uninterpolate().kind &&
rustc_ast::MetaItemLit::from_token(&self.token).is_none() &&
(lit.kind == token::LitKind::Integer || lit.kind == token::LitKind::Float) &&
self.look_ahead(1, |t| matches!(t.kind, token::Eq) || matches!(t.kind, token::Colon ) ) {
return Err(self.sess.create_err(errors::InvalidIdentiferStartsWithNumber { span: self.token.span }));
}
Ok(())
}

fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
if let ast::ExprKind::Binary(op, ..) = init.kind {
if op.node.lazy() {
Expand Down
8 changes: 7 additions & 1 deletion src/bootstrap/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,14 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
if !CiEnv::is_ci() && paths.is_empty() {
match get_modified_rs_files(build) {
Ok(Some(files)) => {
if files.len() <= 10 {
for file in &files {
println!("formatting modified file {file}");
}
} else {
println!("formatting {} modified files", files.len());
}
for file in files {
println!("formatting modified file {file}");
ignore_fmt.add(&format!("/{file}")).expect(&file);
}
}
Expand Down
108 changes: 66 additions & 42 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2065,23 +2065,81 @@ fn clean_bare_fn_ty<'tcx>(
BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
}

/// This visitor is used to go through only the "top level" of a item and not enter any sub
/// item while looking for a given `Ident` which is stored into `item` if found.
struct OneLevelVisitor<'hir> {
/// Get DefId of of an item's user-visible parent.
///
/// "User-visible" should account for re-exporting and inlining, which is why this function isn't
/// just `tcx.parent(def_id)`. If the provided `path` has more than one path element, the `DefId`
/// of the second-to-last will be given.
///
/// ```text
/// use crate::foo::Bar;
/// ^^^ DefId of this item will be returned
/// ```
///
/// If the provided path has only one item, `tcx.parent(def_id)` will be returned instead.
fn get_path_parent_def_id(
tcx: TyCtxt<'_>,
def_id: DefId,
path: &hir::UsePath<'_>,
) -> Option<DefId> {
if let [.., parent_segment, _] = &path.segments {
match parent_segment.res {
hir::def::Res::Def(_, parent_def_id) => Some(parent_def_id),
_ if parent_segment.ident.name == kw::Crate => {
// In case the "parent" is the crate, it'll give `Res::Err` so we need to
// circumvent it this way.
Some(tcx.parent(def_id))
}
_ => None,
}
} else {
// If the path doesn't have a parent, then the parent is the current module.
Some(tcx.parent(def_id))
}
}

/// This visitor is used to find an HIR Item based on its `use` path. This doesn't use the ordinary
/// name resolver because it does not walk all the way through a chain of re-exports.
pub(crate) struct OneLevelVisitor<'hir> {
map: rustc_middle::hir::map::Map<'hir>,
item: Option<&'hir hir::Item<'hir>>,
pub(crate) item: Option<&'hir hir::Item<'hir>>,
looking_for: Ident,
target_def_id: LocalDefId,
}

impl<'hir> OneLevelVisitor<'hir> {
fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self {
pub(crate) fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self {
Self { map, item: None, looking_for: Ident::empty(), target_def_id }
}

fn reset(&mut self, looking_for: Ident) {
self.looking_for = looking_for;
pub(crate) fn find_target(
&mut self,
tcx: TyCtxt<'_>,
def_id: DefId,
path: &hir::UsePath<'_>,
) -> Option<&'hir hir::Item<'hir>> {
let parent_def_id = get_path_parent_def_id(tcx, def_id, path)?;
let parent = self.map.get_if_local(parent_def_id)?;

// We get the `Ident` we will be looking for into `item`.
self.looking_for = path.segments[path.segments.len() - 1].ident;
// We reset the `item`.
self.item = None;

match parent {
hir::Node::Item(parent_item) => {
hir::intravisit::walk_item(self, parent_item);
}
hir::Node::Crate(m) => {
hir::intravisit::walk_mod(
self,
m,
tcx.local_def_id_to_hir_id(parent_def_id.as_local().unwrap()),
);
}
_ => return None,
}
self.item
}
}

Expand Down Expand Up @@ -2129,41 +2187,7 @@ fn get_all_import_attributes<'hir>(
add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline);
}

let def_id = if let [.., parent_segment, _] = &path.segments {
match parent_segment.res {
hir::def::Res::Def(_, def_id) => def_id,
_ if parent_segment.ident.name == kw::Crate => {
// In case the "parent" is the crate, it'll give `Res::Err` so we need to
// circumvent it this way.
tcx.parent(item.owner_id.def_id.to_def_id())
}
_ => break,
}
} else {
// If the path doesn't have a parent, then the parent is the current module.
tcx.parent(item.owner_id.def_id.to_def_id())
};

let Some(parent) = hir_map.get_if_local(def_id) else { break };

// We get the `Ident` we will be looking for into `item`.
let looking_for = path.segments[path.segments.len() - 1].ident;
visitor.reset(looking_for);

match parent {
hir::Node::Item(parent_item) => {
hir::intravisit::walk_item(&mut visitor, parent_item);
}
hir::Node::Crate(m) => {
hir::intravisit::walk_mod(
&mut visitor,
m,
tcx.local_def_id_to_hir_id(def_id.as_local().unwrap()),
);
}
_ => break,
}
if let Some(i) = visitor.item {
if let Some(i) = visitor.find_target(tcx, item.owner_id.def_id.to_def_id(), path) {
item = i;
} else {
break;
Expand Down
28 changes: 26 additions & 2 deletions src/librustdoc/html/render/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,11 +647,35 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
</noscript>\
<link rel=\"stylesheet\" \
href=\"{static_root_path}{settings_css}\">\
<script defer src=\"{static_root_path}{settings_js}\"></script>",
<script defer src=\"{static_root_path}{settings_js}\"></script>\
<link rel=\"preload\" href=\"{static_root_path}{theme_light_css}\" \
as=\"style\">\
<link rel=\"preload\" href=\"{static_root_path}{theme_dark_css}\" \
as=\"style\">\
<link rel=\"preload\" href=\"{static_root_path}{theme_ayu_css}\" \
as=\"style\">",
static_root_path = page.get_static_root_path(),
settings_css = static_files::STATIC_FILES.settings_css,
settings_js = static_files::STATIC_FILES.settings_js,
)
theme_light_css = static_files::STATIC_FILES.theme_light_css,
theme_dark_css = static_files::STATIC_FILES.theme_dark_css,
theme_ayu_css = static_files::STATIC_FILES.theme_ayu_css,
);
// Pre-load all theme CSS files, so that switching feels seamless.
//
// When loading settings.html as a popover, the equivalent HTML is
// generated in main.js.
for file in &shared.style_files {
if let Ok(theme) = file.basename() {
write!(
buf,
"<link rel=\"preload\" href=\"{root_path}{theme}{suffix}.css\" \
as=\"style\">",
root_path = page.static_root_path.unwrap_or(""),
suffix = page.resource_suffix,
);
}
}
},
&shared.style_files,
);
Expand Down
6 changes: 3 additions & 3 deletions src/librustdoc/html/render/span_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ pub(crate) enum LinkFromSrc {

/// This function will do at most two things:
///
/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
/// 1. Generate a `span` correspondence map which links an item `span` to its definition `span`.
/// 2. Collect the source code files.
///
/// It returns the `krate`, the source code files and the `span` correspondance map.
/// It returns the `krate`, the source code files and the `span` correspondence map.
///
/// Note about the `span` correspondance map: the keys are actually `(lo, hi)` of `span`s. We don't
/// Note about the `span` correspondence map: the keys are actually `(lo, hi)` of `span`s. We don't
/// need the `span` context later on, only their position, so instead of keep a whole `Span`, we
/// only keep the `lo` and `hi`.
pub(crate) fn collect_spans_and_sources(
Expand Down
Loading

0 comments on commit 104f430

Please sign in to comment.