Skip to content

Commit db4f116

Browse files
committed
Auto merge of rust-lang#122113 - matthiaskrgr:rollup-5d1jnwi, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#121958 (Fix redundant import errors for preload extern crate) - rust-lang#121976 (Add an option to have an external download/bootstrap cache) - rust-lang#122022 (loongarch: add frecipe and relax target feature) - rust-lang#122026 (Do not try to format removed files) - rust-lang#122027 (Uplift some feeding out of `associated_type_for_impl_trait_in_impl` and into queries) - rust-lang#122063 (Make the lowering of `thir::ExprKind::If` easier to follow) - rust-lang#122074 (Add missing PartialOrd trait implementation doc for array) - rust-lang#122082 (remove outdated fixme comment) - rust-lang#122091 (Note why we're using a new thread in `test_get_os_named_thread`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 7d3702e + 3827584 commit db4f116

File tree

31 files changed

+403
-181
lines changed

31 files changed

+403
-181
lines changed

compiler/rustc_hir_analysis/src/collect/generics_of.rs

+37
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,43 @@ use rustc_span::Span;
1414
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
1515
use rustc_hir::*;
1616

17+
// For an RPITIT, synthesize generics which are equal to the opaque's generics
18+
// and parent fn's generics compressed into one list.
19+
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
20+
tcx.opt_rpitit_info(def_id.to_def_id())
21+
{
22+
let trait_def_id = tcx.parent(fn_def_id);
23+
let opaque_ty_generics = tcx.generics_of(opaque_def_id);
24+
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
25+
let mut params = opaque_ty_generics.params.clone();
26+
27+
let parent_generics = tcx.generics_of(trait_def_id);
28+
let parent_count = parent_generics.parent_count + parent_generics.params.len();
29+
30+
let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
31+
32+
for param in &mut params {
33+
param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
34+
- opaque_ty_parent_count as u32;
35+
}
36+
37+
trait_fn_params.extend(params);
38+
params = trait_fn_params;
39+
40+
let param_def_id_to_index =
41+
params.iter().map(|param| (param.def_id, param.index)).collect();
42+
43+
return ty::Generics {
44+
parent: Some(trait_def_id),
45+
parent_count,
46+
params,
47+
param_def_id_to_index,
48+
has_self: opaque_ty_generics.has_self,
49+
has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
50+
host_effect_index: parent_generics.host_effect_index,
51+
};
52+
}
53+
1754
let hir_id = tcx.local_def_id_to_hir_id(def_id);
1855

1956
let node = tcx.hir_node(hir_id);

compiler/rustc_hir_analysis/src/collect/type_of.rs

+24-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_hir::HirId;
55
use rustc_middle::query::plumbing::CyclePlaceholder;
66
use rustc_middle::ty::print::with_forced_trimmed_paths;
77
use rustc_middle::ty::util::IntTypeExt;
8-
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
8+
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
99
use rustc_span::symbol::Ident;
1010
use rustc_span::{Span, DUMMY_SP};
1111

@@ -350,22 +350,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
350350
// If we are computing `type_of` the synthesized associated type for an RPITIT in the impl
351351
// side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the
352352
// associated type in the impl.
353-
if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) =
354-
tcx.opt_rpitit_info(def_id.to_def_id())
355-
{
356-
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
357-
Ok(map) => {
358-
let assoc_item = tcx.associated_item(def_id);
359-
return map[&assoc_item.trait_item_def_id.unwrap()];
360-
}
361-
Err(_) => {
362-
return ty::EarlyBinder::bind(Ty::new_error_with_message(
363-
tcx,
364-
DUMMY_SP,
365-
"Could not collect return position impl trait in trait tys",
366-
));
353+
match tcx.opt_rpitit_info(def_id.to_def_id()) {
354+
Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => {
355+
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
356+
Ok(map) => {
357+
let assoc_item = tcx.associated_item(def_id);
358+
return map[&assoc_item.trait_item_def_id.unwrap()];
359+
}
360+
Err(_) => {
361+
return ty::EarlyBinder::bind(Ty::new_error_with_message(
362+
tcx,
363+
DUMMY_SP,
364+
"Could not collect return position impl trait in trait tys",
365+
));
366+
}
367367
}
368368
}
369+
// For an RPITIT in a trait, just return the corresponding opaque.
370+
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
371+
return ty::EarlyBinder::bind(Ty::new_opaque(
372+
tcx,
373+
opaque_def_id,
374+
ty::GenericArgs::identity_for_item(tcx, opaque_def_id),
375+
));
376+
}
377+
None => {}
369378
}
370379

371380
let hir_id = tcx.local_def_id_to_hir_id(def_id);

compiler/rustc_lint/src/context/diagnostics.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,11 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
143143
BuiltinLintDiag::RedundantImport(spans, ident) => {
144144
for (span, is_imported) in spans {
145145
let introduced = if is_imported { "imported" } else { "defined" };
146-
diag.span_label(span, format!("the item `{ident}` is already {introduced} here"));
146+
let span_msg = if span.is_dummy() { "by prelude" } else { "here" };
147+
diag.span_label(
148+
span,
149+
format!("the item `{ident}` is already {introduced} {span_msg}"),
150+
);
147151
}
148152
}
149153
BuiltinLintDiag::DeprecatedMacro(suggestion, span) => {

compiler/rustc_middle/src/query/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -826,15 +826,15 @@ rustc_queries! {
826826
/// creates and returns the associated items that correspond to each impl trait in return position
827827
/// of the implemented trait.
828828
query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] {
829-
desc { |tcx| "creating associated items for impl trait in trait returned by `{}`", tcx.def_path_str(fn_def_id) }
829+
desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) }
830830
cache_on_disk_if { fn_def_id.is_local() }
831831
separate_provide_extern
832832
}
833833

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

compiler/rustc_mir_build/src/build/expr/into.rs

+45-36
Original file line numberDiff line numberDiff line change
@@ -58,52 +58,61 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5858
this.thir[scrutinee].span,
5959
),
6060
ExprKind::If { cond, then, else_opt, if_then_scope } => {
61-
let then_blk;
6261
let then_span = this.thir[then].span;
6362
let then_source_info = this.source_info(then_span);
6463
let condition_scope = this.local_scope();
6564

66-
let mut else_blk = unpack!(
67-
then_blk = this.in_scope(
68-
(if_then_scope, then_source_info),
69-
LintLevel::Inherited,
70-
|this| {
71-
let source_info = if this.is_let(cond) {
72-
let variable_scope =
73-
this.new_source_scope(then_span, LintLevel::Inherited, None);
74-
this.source_scope = variable_scope;
75-
SourceInfo { span: then_span, scope: variable_scope }
76-
} else {
77-
this.source_info(then_span)
78-
};
79-
let (then_block, else_block) =
80-
this.in_if_then_scope(condition_scope, then_span, |this| {
81-
let then_blk = unpack!(this.then_else_break(
82-
block,
83-
cond,
84-
Some(condition_scope), // Temp scope
85-
condition_scope,
86-
source_info,
87-
true, // Declare `let` bindings normally
88-
));
89-
90-
this.expr_into_dest(destination, then_blk, then)
91-
});
92-
then_block.and(else_block)
93-
},
94-
)
65+
let then_and_else_blocks = this.in_scope(
66+
(if_then_scope, then_source_info),
67+
LintLevel::Inherited,
68+
|this| {
69+
// FIXME: Does this need extra logic to handle let-chains?
70+
let source_info = if this.is_let(cond) {
71+
let variable_scope =
72+
this.new_source_scope(then_span, LintLevel::Inherited, None);
73+
this.source_scope = variable_scope;
74+
SourceInfo { span: then_span, scope: variable_scope }
75+
} else {
76+
this.source_info(then_span)
77+
};
78+
79+
// Lower the condition, and have it branch into `then` and `else` blocks.
80+
let (then_block, else_block) =
81+
this.in_if_then_scope(condition_scope, then_span, |this| {
82+
let then_blk = unpack!(this.then_else_break(
83+
block,
84+
cond,
85+
Some(condition_scope), // Temp scope
86+
condition_scope,
87+
source_info,
88+
true, // Declare `let` bindings normally
89+
));
90+
91+
// Lower the `then` arm into its block.
92+
this.expr_into_dest(destination, then_blk, then)
93+
});
94+
95+
// Pack `(then_block, else_block)` into `BlockAnd<BasicBlock>`.
96+
then_block.and(else_block)
97+
},
9598
);
9699

97-
else_blk = if let Some(else_opt) = else_opt {
98-
unpack!(this.expr_into_dest(destination, else_blk, else_opt))
100+
// Unpack `BlockAnd<BasicBlock>` into `(then_blk, else_blk)`.
101+
let (then_blk, mut else_blk);
102+
else_blk = unpack!(then_blk = then_and_else_blocks);
103+
104+
// If there is an `else` arm, lower it into `else_blk`.
105+
if let Some(else_expr) = else_opt {
106+
unpack!(else_blk = this.expr_into_dest(destination, else_blk, else_expr));
99107
} else {
100-
// Body of the `if` expression without an `else` clause must return `()`, thus
101-
// we implicitly generate an `else {}` if it is not specified.
108+
// There is no `else` arm, so we know both arms have type `()`.
109+
// Generate the implicit `else {}` by assigning unit.
102110
let correct_si = this.source_info(expr_span.shrink_to_hi());
103111
this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx);
104-
else_blk
105-
};
112+
}
106113

114+
// The `then` and `else` arms have been lowered into their respective
115+
// blocks, so make both of them meet up in a new block.
107116
let join_block = this.cfg.start_new_block();
108117
this.cfg.goto(then_blk, source_info, join_block);
109118
this.cfg.goto(else_blk, source_info, join_block);

compiler/rustc_resolve/src/check_unused.rs

+77-69
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,81 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
137137
self.check_import_as_underscore(item, *id);
138138
}
139139
}
140+
141+
fn report_unused_extern_crate_items(
142+
&mut self,
143+
maybe_unused_extern_crates: FxHashMap<ast::NodeId, Span>,
144+
) {
145+
let tcx = self.r.tcx();
146+
for extern_crate in &self.extern_crate_items {
147+
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
148+
149+
// If the crate is fully unused, we suggest removing it altogether.
150+
// We do this in any edition.
151+
if warn_if_unused {
152+
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
153+
self.r.lint_buffer.buffer_lint_with_diagnostic(
154+
UNUSED_EXTERN_CRATES,
155+
extern_crate.id,
156+
span,
157+
"unused extern crate",
158+
BuiltinLintDiag::UnusedExternCrate {
159+
removal_span: extern_crate.span_with_attributes,
160+
},
161+
);
162+
continue;
163+
}
164+
}
165+
166+
// If we are not in Rust 2018 edition, then we don't make any further
167+
// suggestions.
168+
if !tcx.sess.at_least_rust_2018() {
169+
continue;
170+
}
171+
172+
// If the extern crate has any attributes, they may have funky
173+
// semantics we can't faithfully represent using `use` (most
174+
// notably `#[macro_use]`). Ignore it.
175+
if extern_crate.has_attrs {
176+
continue;
177+
}
178+
179+
// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
180+
// would not insert the new name into the prelude, where other imports in the crate may be
181+
// expecting it.
182+
if extern_crate.renames {
183+
continue;
184+
}
185+
186+
// If the extern crate isn't in the extern prelude,
187+
// there is no way it can be written as a `use`.
188+
if !self
189+
.r
190+
.extern_prelude
191+
.get(&extern_crate.ident)
192+
.is_some_and(|entry| !entry.introduced_by_item)
193+
{
194+
continue;
195+
}
196+
197+
let vis_span = extern_crate
198+
.vis_span
199+
.find_ancestor_inside(extern_crate.span)
200+
.unwrap_or(extern_crate.vis_span);
201+
let ident_span = extern_crate
202+
.ident
203+
.span
204+
.find_ancestor_inside(extern_crate.span)
205+
.unwrap_or(extern_crate.ident.span);
206+
self.r.lint_buffer.buffer_lint_with_diagnostic(
207+
UNUSED_EXTERN_CRATES,
208+
extern_crate.id,
209+
extern_crate.span,
210+
"`extern crate` is not idiomatic in the new edition",
211+
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
212+
);
213+
}
214+
}
140215
}
141216

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

413+
visitor.report_unused_extern_crate_items(maybe_unused_extern_crates);
414+
338415
for unused in visitor.unused_imports.values() {
339416
let mut fixes = Vec::new();
340417
let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) {
@@ -416,75 +493,6 @@ impl Resolver<'_, '_> {
416493
);
417494
}
418495

419-
for extern_crate in visitor.extern_crate_items {
420-
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
421-
422-
// If the crate is fully unused, we suggest removing it altogether.
423-
// We do this in any edition.
424-
if warn_if_unused {
425-
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
426-
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
427-
UNUSED_EXTERN_CRATES,
428-
extern_crate.id,
429-
span,
430-
"unused extern crate",
431-
BuiltinLintDiag::UnusedExternCrate {
432-
removal_span: extern_crate.span_with_attributes,
433-
},
434-
);
435-
continue;
436-
}
437-
}
438-
439-
// If we are not in Rust 2018 edition, then we don't make any further
440-
// suggestions.
441-
if !tcx.sess.at_least_rust_2018() {
442-
continue;
443-
}
444-
445-
// If the extern crate has any attributes, they may have funky
446-
// semantics we can't faithfully represent using `use` (most
447-
// notably `#[macro_use]`). Ignore it.
448-
if extern_crate.has_attrs {
449-
continue;
450-
}
451-
452-
// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
453-
// would not insert the new name into the prelude, where other imports in the crate may be
454-
// expecting it.
455-
if extern_crate.renames {
456-
continue;
457-
}
458-
459-
// If the extern crate isn't in the extern prelude,
460-
// there is no way it can be written as a `use`.
461-
if !visitor
462-
.r
463-
.extern_prelude
464-
.get(&extern_crate.ident)
465-
.is_some_and(|entry| !entry.introduced_by_item)
466-
{
467-
continue;
468-
}
469-
470-
let vis_span = extern_crate
471-
.vis_span
472-
.find_ancestor_inside(extern_crate.span)
473-
.unwrap_or(extern_crate.vis_span);
474-
let ident_span = extern_crate
475-
.ident
476-
.span
477-
.find_ancestor_inside(extern_crate.span)
478-
.unwrap_or(extern_crate.ident.span);
479-
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
480-
UNUSED_EXTERN_CRATES,
481-
extern_crate.id,
482-
extern_crate.span,
483-
"`extern crate` is not idiomatic in the new edition",
484-
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
485-
);
486-
}
487-
488496
let unused_imports = visitor.unused_imports;
489497
let mut check_redundant_imports = FxIndexSet::default();
490498
for module in self.arenas.local_modules().iter() {

0 commit comments

Comments
 (0)