Skip to content

Commit c68032f

Browse files
committed
Auto merge of #141944 - matthiaskrgr:rollup-e7xhp6w, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #140715 (Clarify &mut-methods' docs on sync::OnceLock) - #141677 (Async drop - type instead of async drop fn, fixes #140484) - #141741 (Overhaul `UsePath`) - #141873 (Fixed a typo in `ManuallyDrop`'s doc) - #141876 (Don't declare variables in `ExprKind::Let` in invalid positions) - #141886 (Add missing 2015 edition directives) - #141889 (Add missing `dyn` keywords to tests that do not test for them) - #141891 (Fix borrowck mentioning a name from an external macro we (deliberately) don't save) r? `@ghost` `@rustbot` modify labels: rollup
2 parents b17dba4 + f3622ea commit c68032f

File tree

61 files changed

+380
-192
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+380
-192
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ use rustc_ast::ptr::P;
33
use rustc_ast::visit::AssocCtxt;
44
use rustc_ast::*;
55
use rustc_errors::ErrorGuaranteed;
6-
use rustc_hir::def::{DefKind, Res};
6+
use rustc_hir::def::{DefKind, PerNS, Res};
77
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
88
use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin};
99
use rustc_index::{IndexSlice, IndexVec};
10+
use rustc_middle::span_bug;
1011
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
1112
use rustc_span::edit_distance::find_best_match_for_name;
1213
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
@@ -527,7 +528,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
527528
}
528529
UseTreeKind::Glob => {
529530
let res = self.expect_full_res(id);
530-
let res = smallvec![self.lower_res(res)];
531+
let res = self.lower_res(res);
532+
// Put the result in the appropriate namespace.
533+
let res = match res {
534+
Res::Def(DefKind::Mod | DefKind::Trait, _) => {
535+
PerNS { type_ns: Some(res), value_ns: None, macro_ns: None }
536+
}
537+
Res::Def(DefKind::Enum, _) => {
538+
PerNS { type_ns: None, value_ns: Some(res), macro_ns: None }
539+
}
540+
Res::Err => {
541+
// Propagate the error to all namespaces, just to be sure.
542+
let err = Some(Res::Err);
543+
PerNS { type_ns: err, value_ns: err, macro_ns: err }
544+
}
545+
_ => span_bug!(path.span, "bad glob res {:?}", res),
546+
};
531547
let path = Path { segments, span: path.span, tokens: None };
532548
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
533549
hir::ItemKind::Use(path, hir::UseKind::Glob)
@@ -601,7 +617,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
601617
} else {
602618
// For non-empty lists we can just drop all the data, the prefix is already
603619
// present in HIR as a part of nested imports.
604-
self.arena.alloc(hir::UsePath { res: smallvec![], segments: &[], span })
620+
self.arena.alloc(hir::UsePath { res: PerNS::default(), segments: &[], span })
605621
};
606622
hir::ItemKind::Use(path, hir::UseKind::ListStem)
607623
}

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
6464
use rustc_session::parse::{add_feature_diagnostics, feature_err};
6565
use rustc_span::symbol::{Ident, Symbol, kw, sym};
6666
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
67-
use smallvec::{SmallVec, smallvec};
67+
use smallvec::SmallVec;
6868
use thin_vec::ThinVec;
6969
use tracing::{debug, instrument, trace};
7070

@@ -705,14 +705,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
705705
self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
706706
}
707707

708-
fn lower_import_res(&mut self, id: NodeId, span: Span) -> SmallVec<[Res; 3]> {
709-
let res = self.resolver.get_import_res(id).present_items();
710-
let res: SmallVec<_> = res.map(|res| self.lower_res(res)).collect();
711-
if res.is_empty() {
708+
fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {
709+
let per_ns = self.resolver.get_import_res(id);
710+
let per_ns = per_ns.map(|res| res.map(|res| self.lower_res(res)));
711+
if per_ns.is_empty() {
712+
// Propagate the error to all namespaces, just to be sure.
712713
self.dcx().span_delayed_bug(span, "no resolution for an import");
713-
return smallvec![Res::Err];
714+
let err = Some(Res::Err);
715+
return PerNS { type_ns: err, value_ns: err, macro_ns: err };
714716
}
715-
res
717+
per_ns
716718
}
717719

718720
fn make_lang_item_qpath(

compiler/rustc_ast_lowering/src/path.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::sync::Arc;
22

33
use rustc_ast::{self as ast, *};
4-
use rustc_hir::def::{DefKind, PartialRes, Res};
4+
use rustc_hir::def::{DefKind, PartialRes, PerNS, Res};
55
use rustc_hir::def_id::DefId;
66
use rustc_hir::{self as hir, GenericArg};
77
use rustc_middle::{span_bug, ty};
88
use rustc_session::parse::add_feature_diagnostics;
99
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym};
10-
use smallvec::{SmallVec, smallvec};
10+
use smallvec::smallvec;
1111
use tracing::{debug, instrument};
1212

1313
use super::errors::{
@@ -226,11 +226,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
226226

227227
pub(crate) fn lower_use_path(
228228
&mut self,
229-
res: SmallVec<[Res; 3]>,
229+
res: PerNS<Option<Res>>,
230230
p: &Path,
231231
param_mode: ParamMode,
232232
) -> &'hir hir::UsePath<'hir> {
233-
assert!((1..=3).contains(&res.len()));
233+
assert!(!res.is_empty());
234234
self.arena.alloc(hir::UsePath {
235235
res,
236236
segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -840,14 +840,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
840840
} else {
841841
bug!("not an upvar")
842842
};
843-
err.span_label(
844-
*span,
845-
format!(
846-
"calling `{}` requires mutable binding due to {}",
847-
self.describe_place(the_place_err).unwrap(),
848-
reason
849-
),
850-
);
843+
// sometimes we deliberately don't store the name of a place when coming from a macro in
844+
// another crate. We generally want to limit those diagnostics a little, to hide
845+
// implementation details (such as those from pin!() or format!()). In that case show a
846+
// slightly different error message, or none at all if something else happened. In other
847+
// cases the message is likely not useful.
848+
if let Some(place_name) = self.describe_place(the_place_err) {
849+
err.span_label(
850+
*span,
851+
format!("calling `{place_name}` requires mutable binding due to {reason}"),
852+
);
853+
} else if span.from_expansion() {
854+
err.span_label(
855+
*span,
856+
format!("a call in this macro requires a mutable binding due to {reason}",),
857+
);
858+
}
851859
}
852860
}
853861

compiler/rustc_hir/src/arena.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ macro_rules! arena_types {
88
[] asm_template: rustc_ast::InlineAsmTemplatePiece,
99
[] attribute: rustc_hir::Attribute,
1010
[] owner_info: rustc_hir::OwnerInfo<'tcx>,
11-
[] use_path: rustc_hir::UsePath<'tcx>,
1211
[] lit: rustc_hir::Lit,
1312
[] macro_def: rustc_ast::MacroDef,
1413
]);

compiler/rustc_hir/src/def.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ impl<CTX: crate::HashStableContext> ToStableHashKey<CTX> for Namespace {
584584
}
585585

586586
/// Just a helper ‒ separate structure for each namespace.
587-
#[derive(Copy, Clone, Default, Debug)]
587+
#[derive(Copy, Clone, Default, Debug, HashStable_Generic)]
588588
pub struct PerNS<T> {
589589
pub value_ns: T,
590590
pub type_ns: T,
@@ -596,10 +596,16 @@ impl<T> PerNS<T> {
596596
PerNS { value_ns: f(self.value_ns), type_ns: f(self.type_ns), macro_ns: f(self.macro_ns) }
597597
}
598598

599+
/// Note: Do you really want to use this? Often you know which namespace a
600+
/// name will belong in, and you can consider just that namespace directly,
601+
/// rather than iterating through all of them.
599602
pub fn into_iter(self) -> IntoIter<T, 3> {
600603
[self.value_ns, self.type_ns, self.macro_ns].into_iter()
601604
}
602605

606+
/// Note: Do you really want to use this? Often you know which namespace a
607+
/// name will belong in, and you can consider just that namespace directly,
608+
/// rather than iterating through all of them.
603609
pub fn iter(&self) -> IntoIter<&T, 3> {
604610
[&self.value_ns, &self.type_ns, &self.macro_ns].into_iter()
605611
}
@@ -634,6 +640,10 @@ impl<T> PerNS<Option<T>> {
634640
}
635641

636642
/// Returns an iterator over the items which are `Some`.
643+
///
644+
/// Note: Do you really want to use this? Often you know which namespace a
645+
/// name will belong in, and you can consider just that namespace directly,
646+
/// rather than iterating through all of them.
637647
pub fn present_items(self) -> impl Iterator<Item = T> {
638648
[self.type_ns, self.value_ns, self.macro_ns].into_iter().flatten()
639649
}

compiler/rustc_hir/src/hir.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use thin_vec::ThinVec;
3030
use tracing::debug;
3131

3232
use crate::LangItem;
33-
use crate::def::{CtorKind, DefKind, Res};
33+
use crate::def::{CtorKind, DefKind, PerNS, Res};
3434
use crate::def_id::{DefId, LocalDefIdMap};
3535
pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
3636
use crate::intravisit::{FnKind, VisitorExt};
@@ -347,7 +347,7 @@ pub struct Path<'hir, R = Res> {
347347
}
348348

349349
/// Up to three resolutions for type, value and macro namespaces.
350-
pub type UsePath<'hir> = Path<'hir, SmallVec<[Res; 3]>>;
350+
pub type UsePath<'hir> = Path<'hir, PerNS<Option<Res>>>;
351351

352352
impl Path<'_> {
353353
pub fn is_global(&self) -> bool {
@@ -2370,6 +2370,10 @@ impl Expr<'_> {
23702370
// Lang item paths cannot currently be local variables or statics.
23712371
ExprKind::Path(QPath::LangItem(..)) => false,
23722372

2373+
// Suppress errors for bad expressions.
2374+
ExprKind::Err(_guar)
2375+
| ExprKind::Let(&LetExpr { recovered: ast::Recovered::Yes(_guar), .. }) => true,
2376+
23732377
// Partially qualified paths in expressions can only legally
23742378
// refer to associated items which are always rvalues.
23752379
ExprKind::Path(QPath::TypeRelative(..))
@@ -2401,8 +2405,7 @@ impl Expr<'_> {
24012405
| ExprKind::Binary(..)
24022406
| ExprKind::Yield(..)
24032407
| ExprKind::Cast(..)
2404-
| ExprKind::DropTemps(..)
2405-
| ExprKind::Err(_) => false,
2408+
| ExprKind::DropTemps(..) => false,
24062409
}
24072410
}
24082411

compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,7 @@ pub fn walk_use<'v, V: Visitor<'v>>(
11481148
hir_id: HirId,
11491149
) -> V::Result {
11501150
let UsePath { segments, ref res, span } = *path;
1151-
for &res in res {
1151+
for res in res.present_items() {
11521152
try_visit!(visitor.visit_path(&Path { segments, res, span }, hir_id));
11531153
}
11541154
V::Result::output()

compiler/rustc_lint/src/internal.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -328,16 +328,19 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr {
328328
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
329329
let rustc_hir::ItemKind::Use(path, kind) = item.kind else { return };
330330

331-
let is_mod_inherent = |def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id);
331+
let is_mod_inherent = |res: Res| {
332+
res.opt_def_id()
333+
.is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id))
334+
};
332335

333336
// Path segments except for the final.
334-
if let Some(seg) =
335-
path.segments.iter().find(|seg| seg.res.opt_def_id().is_some_and(is_mod_inherent))
336-
{
337+
if let Some(seg) = path.segments.iter().find(|seg| is_mod_inherent(seg.res)) {
337338
cx.emit_span_lint(USAGE_OF_TYPE_IR_INHERENT, seg.ident.span, TypeIrInherentUsage);
338339
}
339340
// Final path resolutions, like `use rustc_type_ir::inherent`
340-
else if path.res.iter().any(|res| res.opt_def_id().is_some_and(is_mod_inherent)) {
341+
else if let Some(type_ns) = path.res.type_ns
342+
&& is_mod_inherent(type_ns)
343+
{
341344
cx.emit_span_lint(
342345
USAGE_OF_TYPE_IR_INHERENT,
343346
path.segments.last().unwrap().ident.span,
@@ -346,13 +349,12 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr {
346349
}
347350

348351
let (lo, hi, snippet) = match path.segments {
349-
[.., penultimate, segment]
350-
if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>
351-
{
352+
[.., penultimate, segment] if is_mod_inherent(penultimate.res) => {
352353
(segment.ident.span, item.kind.ident().unwrap().span, "*")
353354
}
354355
[.., segment]
355-
if path.res.iter().flat_map(Res::opt_def_id).any(is_mod_inherent)
356+
if let Some(type_ns) = path.res.type_ns
357+
&& is_mod_inherent(type_ns)
356358
&& let rustc_hir::UseKind::Single(ident) = kind =>
357359
{
358360
let (lo, snippet) =

compiler/rustc_lint/src/unqualified_local_imports.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use rustc_hir::def::{DefKind, Res};
21
use rustc_hir::{self as hir};
32
use rustc_session::{declare_lint, declare_lint_pass};
43
use rustc_span::kw;
@@ -47,17 +46,15 @@ declare_lint_pass!(UnqualifiedLocalImports => [UNQUALIFIED_LOCAL_IMPORTS]);
4746
impl<'tcx> LateLintPass<'tcx> for UnqualifiedLocalImports {
4847
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
4948
let hir::ItemKind::Use(path, _kind) = item.kind else { return };
50-
// `path` has three resolutions for the type, module, value namespaces.
51-
// Check if any of them qualifies: local crate, and not a macro.
52-
// (Macros can't be imported any other way so we don't complain about them.)
53-
let is_local_import = |res: &Res| {
54-
matches!(
55-
res,
56-
hir::def::Res::Def(def_kind, def_id)
57-
if def_id.is_local() && !matches!(def_kind, DefKind::Macro(_)),
58-
)
59-
};
60-
if !path.res.iter().any(is_local_import) {
49+
// Check the type and value namespace resolutions for a local crate.
50+
let is_local_import = matches!(
51+
path.res.type_ns,
52+
Some(hir::def::Res::Def(_, def_id)) if def_id.is_local()
53+
) || matches!(
54+
path.res.value_ns,
55+
Some(hir::def::Res::Def(_, def_id)) if def_id.is_local()
56+
);
57+
if !is_local_import {
6158
return;
6259
}
6360
// So this does refer to something local. Let's check whether it starts with `self`,

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,26 +1047,21 @@ fn find_fallback_pattern_typo<'tcx>(
10471047
let hir::ItemKind::Use(path, _) = item.kind else {
10481048
continue;
10491049
};
1050-
for res in &path.res {
1051-
if let Res::Def(DefKind::Const, id) = res
1052-
&& infcx.can_eq(param_env, ty, cx.tcx.type_of(id).instantiate_identity())
1053-
{
1054-
if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) {
1055-
// The original const is accessible, suggest using it directly.
1056-
let item_name = cx.tcx.item_name(*id);
1057-
accessible.push(item_name);
1058-
accessible_path.push(with_no_trimmed_paths!(cx.tcx.def_path_str(id)));
1059-
} else if cx
1060-
.tcx
1061-
.visibility(item.owner_id)
1062-
.is_accessible_from(parent, cx.tcx)
1063-
{
1064-
// The const is accessible only through the re-export, point at
1065-
// the `use`.
1066-
let ident = item.kind.ident().unwrap();
1067-
imported.push(ident.name);
1068-
imported_spans.push(ident.span);
1069-
}
1050+
if let Some(value_ns) = path.res.value_ns
1051+
&& let Res::Def(DefKind::Const, id) = value_ns
1052+
&& infcx.can_eq(param_env, ty, cx.tcx.type_of(id).instantiate_identity())
1053+
{
1054+
if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) {
1055+
// The original const is accessible, suggest using it directly.
1056+
let item_name = cx.tcx.item_name(id);
1057+
accessible.push(item_name);
1058+
accessible_path.push(with_no_trimmed_paths!(cx.tcx.def_path_str(id)));
1059+
} else if cx.tcx.visibility(item.owner_id).is_accessible_from(parent, cx.tcx) {
1060+
// The const is accessible only through the re-export, point at
1061+
// the `use`.
1062+
let ident = item.kind.ident().unwrap();
1063+
imported.push(ident.name);
1064+
imported_spans.push(ident.span);
10701065
}
10711066
}
10721067
}

compiler/rustc_mir_transform/src/elaborate_drop.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{fmt, iter, mem};
22

33
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
4+
use rustc_hir::def::DefKind;
45
use rustc_hir::lang_items::LangItem;
56
use rustc_index::Idx;
67
use rustc_middle::mir::*;
@@ -254,8 +255,19 @@ where
254255
// impl_item_refs may be empty if drop fn is not implemented in 'impl AsyncDrop for ...'
255256
// (#140974).
256257
// Such code will report error, so just generate sync drop here and return
257-
let Some(drop_fn_def_id) =
258-
tcx.associated_item_def_ids(drop_trait).into_iter().nth(0).copied()
258+
let Some(drop_fn_def_id) = tcx
259+
.associated_item_def_ids(drop_trait)
260+
.first()
261+
.and_then(|def_id| {
262+
if tcx.def_kind(def_id) == DefKind::AssocFn
263+
&& tcx.check_args_compatible(*def_id, trait_args)
264+
{
265+
Some(def_id)
266+
} else {
267+
None
268+
}
269+
})
270+
.copied()
259271
else {
260272
tcx.dcx().span_delayed_bug(
261273
self.elaborator.body().span,

compiler/rustc_passes/src/check_export.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'tcx> Visitor<'tcx> for ExportableItemCollector<'tcx> {
132132
self.add_exportable(def_id);
133133
}
134134
hir::ItemKind::Use(path, _) => {
135-
for res in &path.res {
135+
for res in path.res.present_items() {
136136
// Only local items are exportable.
137137
if let Some(res_id) = res.opt_def_id()
138138
&& let Some(res_id) = res_id.as_local()

0 commit comments

Comments
 (0)