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 #122113

Merged
merged 22 commits into from Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d911613
Allow bootstrap cache path to be set by environment variable
jefferyto Oct 13, 2023
c98e25b
Add a build option to specify the bootstrap cache
lu-zero Mar 4, 2024
39887d3
Do not try to format removed files
clubby789 Mar 5, 2024
ebc45c8
Uplift some feeding out of associated_type_for_impl_trait_in_impl and…
compiler-errors Mar 5, 2024
7396fd1
Clarify how lowering `if` produces then/else blocks
Zalathar Mar 6, 2024
3402f39
Clarify lowering the `else` arm into the else block
Zalathar Mar 6, 2024
250e697
Additional comments for lowering `if`
Zalathar Mar 6, 2024
e81df3f
loongarch: add frecipe and relax target feature
heiher Mar 5, 2024
533add8
add missing PartialOrd impl doc for array
KonradHoeffner Mar 6, 2024
1061c8d
remove outdated fixme comment
fee1-dead Mar 6, 2024
5a4ff27
Fix redundant import errors for preload extern crate
chenyukang Mar 4, 2024
9957736
Note why we're using a new thread in a test
ChrisDenton Mar 6, 2024
0a80f9a
Update src/bootstrap/src/utils/change_tracker.rs
lu-zero Mar 6, 2024
550b8a2
Rollup merge of #121958 - chenyukang:yukang-fix-121915-import, r=petr…
matthiaskrgr Mar 6, 2024
24a2169
Rollup merge of #121976 - lu-zero:bootstrap-cache, r=onur-ozkan
matthiaskrgr Mar 6, 2024
daf89d0
Rollup merge of #122022 - heiher:loongarch-features, r=petrochenkov
matthiaskrgr Mar 6, 2024
03ec79b
Rollup merge of #122026 - clubby789:fmt-removed, r=onur-ozkan
matthiaskrgr Mar 6, 2024
34cffae
Rollup merge of #122027 - compiler-errors:rpitit-cycle, r=spastorino
matthiaskrgr Mar 6, 2024
37782da
Rollup merge of #122063 - Zalathar:lower-if, r=oli-obk
matthiaskrgr Mar 6, 2024
6279ef2
Rollup merge of #122074 - KonradHoeffner:patch-2, r=jhpratt
matthiaskrgr Mar 6, 2024
75ebe83
Rollup merge of #122082 - fee1-dead-contrib:rm-outdated-note, r=compi…
matthiaskrgr Mar 6, 2024
3827584
Rollup merge of #122091 - ChrisDenton:comment, r=RalfJung
matthiaskrgr Mar 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 37 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Expand Up @@ -14,6 +14,43 @@ use rustc_span::Span;
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
use rustc_hir::*;

// For an RPITIT, synthesize generics which are equal to the opaque's generics
// and parent fn's generics compressed into one list.
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
tcx.opt_rpitit_info(def_id.to_def_id())
{
let trait_def_id = tcx.parent(fn_def_id);
let opaque_ty_generics = tcx.generics_of(opaque_def_id);
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
let mut params = opaque_ty_generics.params.clone();

let parent_generics = tcx.generics_of(trait_def_id);
let parent_count = parent_generics.parent_count + parent_generics.params.len();

let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();

for param in &mut params {
param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
- opaque_ty_parent_count as u32;
}

trait_fn_params.extend(params);
params = trait_fn_params;

let param_def_id_to_index =
params.iter().map(|param| (param.def_id, param.index)).collect();

return ty::Generics {
parent: Some(trait_def_id),
parent_count,
params,
param_def_id_to_index,
has_self: opaque_ty_generics.has_self,
has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
host_effect_index: parent_generics.host_effect_index,
};
}

let hir_id = tcx.local_def_id_to_hir_id(def_id);

let node = tcx.hir_node(hir_id);
Expand Down
39 changes: 24 additions & 15 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Expand Up @@ -5,7 +5,7 @@ use rustc_hir::HirId;
use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::Ident;
use rustc_span::{Span, DUMMY_SP};

Expand Down Expand Up @@ -350,22 +350,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
// If we are computing `type_of` the synthesized associated type for an RPITIT in the impl
// side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the
// associated type in the impl.
if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) =
tcx.opt_rpitit_info(def_id.to_def_id())
{
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
Ok(map) => {
let assoc_item = tcx.associated_item(def_id);
return map[&assoc_item.trait_item_def_id.unwrap()];
}
Err(_) => {
return ty::EarlyBinder::bind(Ty::new_error_with_message(
tcx,
DUMMY_SP,
"Could not collect return position impl trait in trait tys",
));
match tcx.opt_rpitit_info(def_id.to_def_id()) {
Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => {
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
Ok(map) => {
let assoc_item = tcx.associated_item(def_id);
return map[&assoc_item.trait_item_def_id.unwrap()];
}
Err(_) => {
return ty::EarlyBinder::bind(Ty::new_error_with_message(
tcx,
DUMMY_SP,
"Could not collect return position impl trait in trait tys",
));
}
}
}
// For an RPITIT in a trait, just return the corresponding opaque.
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
return ty::EarlyBinder::bind(Ty::new_opaque(
tcx,
opaque_def_id,
ty::GenericArgs::identity_for_item(tcx, opaque_def_id),
));
}
None => {}
}

let hir_id = tcx.local_def_id_to_hir_id(def_id);
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_lint/src/context/diagnostics.rs
Expand Up @@ -143,7 +143,11 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
BuiltinLintDiag::RedundantImport(spans, ident) => {
for (span, is_imported) in spans {
let introduced = if is_imported { "imported" } else { "defined" };
diag.span_label(span, format!("the item `{ident}` is already {introduced} here"));
let span_msg = if span.is_dummy() { "by prelude" } else { "here" };
diag.span_label(
span,
format!("the item `{ident}` is already {introduced} {span_msg}"),
);
}
}
BuiltinLintDiag::DeprecatedMacro(suggestion, span) => {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Expand Up @@ -826,15 +826,15 @@ rustc_queries! {
/// creates and returns the associated items that correspond to each impl trait in return position
/// of the implemented trait.
query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] {
desc { |tcx| "creating associated items for impl trait in trait returned by `{}`", tcx.def_path_str(fn_def_id) }
desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) }
cache_on_disk_if { fn_def_id.is_local() }
separate_provide_extern
}

/// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding
/// associated item.
query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId {
desc { |tcx| "creates the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
desc { |tcx| "creating the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
cache_on_disk_if { true }
}

Expand Down
81 changes: 45 additions & 36 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Expand Up @@ -58,52 +58,61 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.thir[scrutinee].span,
),
ExprKind::If { cond, then, else_opt, if_then_scope } => {
let then_blk;
let then_span = this.thir[then].span;
let then_source_info = this.source_info(then_span);
let condition_scope = this.local_scope();

let mut else_blk = unpack!(
then_blk = this.in_scope(
(if_then_scope, then_source_info),
LintLevel::Inherited,
|this| {
let source_info = if this.is_let(cond) {
let variable_scope =
this.new_source_scope(then_span, LintLevel::Inherited, None);
this.source_scope = variable_scope;
SourceInfo { span: then_span, scope: variable_scope }
} else {
this.source_info(then_span)
};
let (then_block, else_block) =
this.in_if_then_scope(condition_scope, then_span, |this| {
let then_blk = unpack!(this.then_else_break(
block,
cond,
Some(condition_scope), // Temp scope
condition_scope,
source_info,
true, // Declare `let` bindings normally
));

this.expr_into_dest(destination, then_blk, then)
});
then_block.and(else_block)
},
)
let then_and_else_blocks = this.in_scope(
(if_then_scope, then_source_info),
LintLevel::Inherited,
|this| {
// FIXME: Does this need extra logic to handle let-chains?
let source_info = if this.is_let(cond) {
let variable_scope =
this.new_source_scope(then_span, LintLevel::Inherited, None);
this.source_scope = variable_scope;
SourceInfo { span: then_span, scope: variable_scope }
} else {
this.source_info(then_span)
};

// Lower the condition, and have it branch into `then` and `else` blocks.
let (then_block, else_block) =
this.in_if_then_scope(condition_scope, then_span, |this| {
let then_blk = unpack!(this.then_else_break(
block,
cond,
Some(condition_scope), // Temp scope
condition_scope,
source_info,
true, // Declare `let` bindings normally
));

// Lower the `then` arm into its block.
this.expr_into_dest(destination, then_blk, then)
});

// Pack `(then_block, else_block)` into `BlockAnd<BasicBlock>`.
then_block.and(else_block)
},
);

else_blk = if let Some(else_opt) = else_opt {
unpack!(this.expr_into_dest(destination, else_blk, else_opt))
// Unpack `BlockAnd<BasicBlock>` into `(then_blk, else_blk)`.
let (then_blk, mut else_blk);
else_blk = unpack!(then_blk = then_and_else_blocks);

// If there is an `else` arm, lower it into `else_blk`.
if let Some(else_expr) = else_opt {
unpack!(else_blk = this.expr_into_dest(destination, else_blk, else_expr));
} else {
// Body of the `if` expression without an `else` clause must return `()`, thus
// we implicitly generate an `else {}` if it is not specified.
// There is no `else` arm, so we know both arms have type `()`.
// Generate the implicit `else {}` by assigning unit.
let correct_si = this.source_info(expr_span.shrink_to_hi());
this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx);
else_blk
};
}

// The `then` and `else` arms have been lowered into their respective
// blocks, so make both of them meet up in a new block.
let join_block = this.cfg.start_new_block();
this.cfg.goto(then_blk, source_info, join_block);
this.cfg.goto(else_blk, source_info, join_block);
Expand Down
146 changes: 77 additions & 69 deletions compiler/rustc_resolve/src/check_unused.rs
Expand Up @@ -137,6 +137,81 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
self.check_import_as_underscore(item, *id);
}
}

fn report_unused_extern_crate_items(
&mut self,
maybe_unused_extern_crates: FxHashMap<ast::NodeId, Span>,
) {
let tcx = self.r.tcx();
for extern_crate in &self.extern_crate_items {
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');

// If the crate is fully unused, we suggest removing it altogether.
// We do this in any edition.
if warn_if_unused {
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
self.r.lint_buffer.buffer_lint_with_diagnostic(
UNUSED_EXTERN_CRATES,
extern_crate.id,
span,
"unused extern crate",
BuiltinLintDiag::UnusedExternCrate {
removal_span: extern_crate.span_with_attributes,
},
);
continue;
}
}

// If we are not in Rust 2018 edition, then we don't make any further
// suggestions.
if !tcx.sess.at_least_rust_2018() {
continue;
}

// If the extern crate has any attributes, they may have funky
// semantics we can't faithfully represent using `use` (most
// notably `#[macro_use]`). Ignore it.
if extern_crate.has_attrs {
continue;
}

// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
// would not insert the new name into the prelude, where other imports in the crate may be
// expecting it.
if extern_crate.renames {
continue;
}

// If the extern crate isn't in the extern prelude,
// there is no way it can be written as a `use`.
if !self
.r
.extern_prelude
.get(&extern_crate.ident)
.is_some_and(|entry| !entry.introduced_by_item)
{
continue;
}

let vis_span = extern_crate
.vis_span
.find_ancestor_inside(extern_crate.span)
.unwrap_or(extern_crate.vis_span);
let ident_span = extern_crate
.ident
.span
.find_ancestor_inside(extern_crate.span)
.unwrap_or(extern_crate.ident.span);
self.r.lint_buffer.buffer_lint_with_diagnostic(
UNUSED_EXTERN_CRATES,
extern_crate.id,
extern_crate.span,
"`extern crate` is not idiomatic in the new edition",
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
);
}
}
}

impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
Expand Down Expand Up @@ -335,6 +410,8 @@ impl Resolver<'_, '_> {
};
visit::walk_crate(&mut visitor, krate);

visitor.report_unused_extern_crate_items(maybe_unused_extern_crates);

for unused in visitor.unused_imports.values() {
let mut fixes = Vec::new();
let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) {
Expand Down Expand Up @@ -416,75 +493,6 @@ impl Resolver<'_, '_> {
);
}

for extern_crate in visitor.extern_crate_items {
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');

// If the crate is fully unused, we suggest removing it altogether.
// We do this in any edition.
if warn_if_unused {
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
UNUSED_EXTERN_CRATES,
extern_crate.id,
span,
"unused extern crate",
BuiltinLintDiag::UnusedExternCrate {
removal_span: extern_crate.span_with_attributes,
},
);
continue;
}
}

// If we are not in Rust 2018 edition, then we don't make any further
// suggestions.
if !tcx.sess.at_least_rust_2018() {
continue;
}

// If the extern crate has any attributes, they may have funky
// semantics we can't faithfully represent using `use` (most
// notably `#[macro_use]`). Ignore it.
if extern_crate.has_attrs {
continue;
}

// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
// would not insert the new name into the prelude, where other imports in the crate may be
// expecting it.
if extern_crate.renames {
continue;
}

// If the extern crate isn't in the extern prelude,
// there is no way it can be written as a `use`.
if !visitor
.r
.extern_prelude
.get(&extern_crate.ident)
.is_some_and(|entry| !entry.introduced_by_item)
{
continue;
}

let vis_span = extern_crate
.vis_span
.find_ancestor_inside(extern_crate.span)
.unwrap_or(extern_crate.vis_span);
let ident_span = extern_crate
.ident
.span
.find_ancestor_inside(extern_crate.span)
.unwrap_or(extern_crate.ident.span);
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
UNUSED_EXTERN_CRATES,
extern_crate.id,
extern_crate.span,
"`extern crate` is not idiomatic in the new edition",
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
);
}

let unused_imports = visitor.unused_imports;
let mut check_redundant_imports = FxIndexSet::default();
for module in self.arenas.local_modules().iter() {
Expand Down