Skip to content

Commit c86e7fb

Browse files
committed
Auto merge of #111342 - Dylan-DPC:rollup-b5p6wzy, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #110297 (Make `(try_)subst_and_normalize_erasing_regions` take `EarlyBinder`) - #110827 (Fix lifetime suggestion for type aliases with objects in them) - #111022 (Use smaller ints for bitflags) - #111056 (Fix some suggestions where a `Box<T>` is expected.) - #111262 (Further normalize msvc-non-utf8-ouput) - #111265 (Make generics_of has_self on RPITITs delegate to the opaque) - #111323 (Give a more helpful error when running the rustc shim directly) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents ea0c22e + 172ddcc commit c86e7fb

File tree

37 files changed

+312
-85
lines changed

37 files changed

+312
-85
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
845845
return;
846846
}
847847

848-
let Some((alias_tys, alias_span)) = self
848+
let Some((alias_tys, alias_span, lt_addition_span)) = self
849849
.infcx
850850
.tcx
851851
.return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id) else { return; };
@@ -858,10 +858,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
858858
()
859859
}
860860
if let TyKind::TraitObject(_, lt, _) = alias_ty.kind {
861-
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
861+
if lt.ident.name == kw::Empty {
862+
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
863+
} else {
864+
spans_suggs.push((lt.ident.span, "'a".to_string()));
865+
}
862866
}
863867
}
864-
spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
868+
869+
if let Some(lt_addition_span) = lt_addition_span {
870+
spans_suggs.push((lt_addition_span, "'a, ".to_string()));
871+
} else {
872+
spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
873+
}
874+
865875
diag.multipart_suggestion_verbose(
866876
format!(
867877
"to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias"

compiler/rustc_codegen_cranelift/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
361361
self.instance.subst_mir_and_normalize_erasing_regions(
362362
self.tcx,
363363
ty::ParamEnv::reveal_all(),
364-
value,
364+
ty::EarlyBinder(value),
365365
)
366366
}
367367

compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ fn make_mir_scope<'ll, 'tcx>(
9393
let callee = cx.tcx.subst_and_normalize_erasing_regions(
9494
instance.substs,
9595
ty::ParamEnv::reveal_all(),
96-
callee,
96+
ty::EarlyBinder(callee),
9797
);
9898
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
9999
cx.dbg_scope_fn(callee, callee_fn_abi, None)

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
529529
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
530530
instance.substs,
531531
ty::ParamEnv::reveal_all(),
532-
cx.tcx.type_of(impl_def_id).skip_binder(),
532+
cx.tcx.type_of(impl_def_id),
533533
);
534534

535535
// Only "class" methods are generally understood by LLVM,

compiler/rustc_codegen_ssa/src/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
111111
self.instance.subst_mir_and_normalize_erasing_regions(
112112
self.cx.tcx(),
113113
ty::ParamEnv::reveal_all(),
114-
value,
114+
ty::EarlyBinder(value),
115115
)
116116
}
117117
}

compiler/rustc_const_eval/src/interpret/eval_context.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
495495
) -> Result<T, InterpError<'tcx>> {
496496
frame
497497
.instance
498-
.try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value)
498+
.try_subst_mir_and_normalize_erasing_regions(
499+
*self.tcx,
500+
self.param_env,
501+
ty::EarlyBinder(value),
502+
)
499503
.map_err(|_| err_inval!(TooGeneric))
500504
}
501505

compiler/rustc_data_structures/src/profiling.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ use parking_lot::RwLock;
101101
use smallvec::SmallVec;
102102

103103
bitflags::bitflags! {
104-
struct EventFilter: u32 {
104+
struct EventFilter: u16 {
105105
const GENERIC_ACTIVITIES = 1 << 0;
106106
const QUERY_PROVIDERS = 1 << 1;
107107
const QUERY_CACHE_HITS = 1 << 2;

compiler/rustc_hir_typeck/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,7 @@ hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
7575
7676
hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where
7777
.note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new
78+
79+
hir_typeck_suggest_boxing_note = for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
80+
81+
hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new`

compiler/rustc_hir_typeck/src/demand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5151
|| self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty)
5252
|| self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty)
5353
|| self.suggest_no_capture_closure(err, expected, expr_ty)
54-
|| self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty)
54+
|| self.suggest_boxing_when_appropriate(err, expr.span, expr.hir_id, expected, expr_ty)
5555
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
5656
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
5757
|| self.suggest_clone_for_ref(err, expr, expr_ty, expected)

compiler/rustc_hir_typeck/src/errors.rs

+28
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,31 @@ pub struct ArgMismatchIndeterminate {
267267
#[primary_span]
268268
pub span: Span,
269269
}
270+
271+
#[derive(Subdiagnostic)]
272+
pub enum SuggestBoxing {
273+
#[note(hir_typeck_suggest_boxing_note)]
274+
#[multipart_suggestion(
275+
hir_typeck_suggest_boxing_when_appropriate,
276+
applicability = "machine-applicable"
277+
)]
278+
Unit {
279+
#[suggestion_part(code = "Box::new(())")]
280+
start: Span,
281+
#[suggestion_part(code = "")]
282+
end: Span,
283+
},
284+
#[note(hir_typeck_suggest_boxing_note)]
285+
AsyncBody,
286+
#[note(hir_typeck_suggest_boxing_note)]
287+
#[multipart_suggestion(
288+
hir_typeck_suggest_boxing_when_appropriate,
289+
applicability = "machine-applicable"
290+
)]
291+
Other {
292+
#[suggestion_part(code = "Box::new(")]
293+
start: Span,
294+
#[suggestion_part(code = ")")]
295+
end: Span,
296+
},
297+
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -1519,7 +1519,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15191519
// case we can ignore the tail expression (e.g., `'a: {
15201520
// break 'a 22; }` would not force the type of the block
15211521
// to be `()`).
1522-
let tail_expr = blk.expr.as_ref();
15231522
let coerce_to_ty = expected.coercion_target_type(self, blk.span);
15241523
let coerce = if blk.targeted_by_break {
15251524
CoerceMany::new(coerce_to_ty)
@@ -1537,13 +1536,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15371536

15381537
// check the tail expression **without** holding the
15391538
// `enclosing_breakables` lock below.
1540-
let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
1539+
let tail_expr_ty =
1540+
blk.expr.map(|expr| (expr, self.check_expr_with_expectation(expr, expected)));
15411541

15421542
let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
15431543
let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
15441544
let coerce = ctxt.coerce.as_mut().unwrap();
1545-
if let Some(tail_expr_ty) = tail_expr_ty {
1546-
let tail_expr = tail_expr.unwrap();
1545+
if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty {
15471546
let span = self.get_expr_coercion_span(tail_expr);
15481547
let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
15491548
let ty_for_diagnostic = coerce.merged_ty();
@@ -1596,6 +1595,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15961595
&self.misc(sp),
15971596
&mut |err| {
15981597
if let Some(expected_ty) = expected.only_has_type(self) {
1598+
if blk.stmts.is_empty() && blk.expr.is_none() {
1599+
self.suggest_boxing_when_appropriate(
1600+
err,
1601+
blk.span,
1602+
blk.hir_id,
1603+
expected_ty,
1604+
self.tcx.mk_unit(),
1605+
);
1606+
}
15991607
if !self.consider_removing_semicolon(blk, expected_ty, err) {
16001608
self.err_ctxt().consider_returning_binding(
16011609
blk,
@@ -1608,7 +1616,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16081616
// silence this redundant error, as we already emit E0070.
16091617

16101618
// Our block must be a `assign desugar local; assignment`
1611-
if let Some(hir::Node::Block(hir::Block {
1619+
if let hir::Block {
16121620
stmts:
16131621
[
16141622
hir::Stmt {
@@ -1630,7 +1638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16301638
},
16311639
],
16321640
..
1633-
})) = self.tcx.hir().find(blk.hir_id)
1641+
} = blk
16341642
{
16351643
self.comes_from_while_condition(blk.hir_id, |_| {
16361644
err.downgrade_to_delayed_bug();

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::FnCtxt;
22

3-
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
3+
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel, SuggestBoxing};
44
use crate::fluent_generated as fluent;
55
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
66
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
@@ -9,7 +9,8 @@ use rustc_hir as hir;
99
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
1010
use rustc_hir::lang_items::LangItem;
1111
use rustc_hir::{
12-
Expr, ExprKind, GenericBound, Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
12+
AsyncGeneratorKind, Expr, ExprKind, GeneratorKind, GenericBound, HirId, Node, Path, QPath,
13+
Stmt, StmtKind, TyKind, WherePredicate,
1314
};
1415
use rustc_hir_analysis::astconv::AstConv;
1516
use rustc_infer::traits::{self, StatementAsExpression};
@@ -438,33 +439,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
438439
pub(in super::super) fn suggest_boxing_when_appropriate(
439440
&self,
440441
err: &mut Diagnostic,
441-
expr: &hir::Expr<'_>,
442+
span: Span,
443+
hir_id: HirId,
442444
expected: Ty<'tcx>,
443445
found: Ty<'tcx>,
444446
) -> bool {
445-
if self.tcx.hir().is_inside_const_context(expr.hir_id) {
446-
// Do not suggest `Box::new` in const context.
447-
return false;
448-
}
449-
if !expected.is_box() || found.is_box() {
447+
// Do not suggest `Box::new` in const context.
448+
if self.tcx.hir().is_inside_const_context(hir_id) || !expected.is_box() || found.is_box() {
450449
return false;
451450
}
452-
let boxed_found = self.tcx.mk_box(found);
453-
if self.can_coerce(boxed_found, expected) {
454-
err.multipart_suggestion(
455-
"store this in the heap by calling `Box::new`",
456-
vec![
457-
(expr.span.shrink_to_lo(), "Box::new(".to_string()),
458-
(expr.span.shrink_to_hi(), ")".to_string()),
459-
],
460-
Applicability::MachineApplicable,
461-
);
462-
err.note(
463-
"for more on the distinction between the stack and the heap, read \
464-
https://doc.rust-lang.org/book/ch15-01-box.html, \
465-
https://doc.rust-lang.org/rust-by-example/std/box.html, and \
466-
https://doc.rust-lang.org/std/boxed/index.html",
467-
);
451+
if self.can_coerce(self.tcx.mk_box(found), expected) {
452+
let suggest_boxing = match found.kind() {
453+
ty::Tuple(tuple) if tuple.is_empty() => {
454+
SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span }
455+
}
456+
ty::Generator(def_id, ..)
457+
if matches!(
458+
self.tcx.generator_kind(def_id),
459+
Some(GeneratorKind::Async(AsyncGeneratorKind::Closure))
460+
) =>
461+
{
462+
SuggestBoxing::AsyncBody
463+
}
464+
_ => SuggestBoxing::Other { start: span.shrink_to_lo(), end: span.shrink_to_hi() },
465+
};
466+
err.subdiagnostic(suggest_boxing);
467+
468468
true
469469
} else {
470470
false

compiler/rustc_middle/src/ty/adt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use super::{Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, Var
2626

2727
bitflags! {
2828
#[derive(HashStable, TyEncodable, TyDecodable)]
29-
pub struct AdtFlags: u32 {
29+
pub struct AdtFlags: u16 {
3030
const NO_ADT_FLAGS = 0;
3131
/// Indicates whether the ADT is an enum.
3232
const IS_ENUM = 1 << 0;

compiler/rustc_middle/src/ty/context.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1093,11 +1093,13 @@ impl<'tcx> TyCtxt<'tcx> {
10931093
v.0
10941094
}
10951095

1096-
/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type and associated alias span when type alias is used
1096+
/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
1097+
/// its return type, and the associated alias span when type alias is used,
1098+
/// along with a span for lifetime suggestion (if there are existing generics).
10971099
pub fn return_type_impl_or_dyn_traits_with_type_alias(
10981100
self,
10991101
scope_def_id: LocalDefId,
1100-
) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span)> {
1102+
) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
11011103
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
11021104
let mut v = TraitObjectVisitor(vec![], self.hir());
11031105
// when the return type is a type alias
@@ -1111,7 +1113,7 @@ impl<'tcx> TyCtxt<'tcx> {
11111113
{
11121114
v.visit_ty(alias_ty);
11131115
if !v.0.is_empty() {
1114-
return Some((v.0, alias_generics.span));
1116+
return Some((v.0, alias_generics.span, alias_generics.span_for_lifetime_suggestion()));
11151117
}
11161118
}
11171119
return None;

compiler/rustc_middle/src/ty/instance.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl<'tcx> Instance<'tcx> {
115115
/// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
116116
pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
117117
let ty = tcx.type_of(self.def.def_id());
118-
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty.skip_binder())
118+
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty)
119119
}
120120

121121
/// Finds a crate that contains a monomorphization of this instance that
@@ -578,14 +578,15 @@ impl<'tcx> Instance<'tcx> {
578578
self.def.has_polymorphic_mir_body().then_some(self.substs)
579579
}
580580

581-
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T
581+
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
582582
where
583583
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
584584
{
585+
let v = v.map_bound(|v| *v);
585586
if let Some(substs) = self.substs_for_mir_body() {
586-
EarlyBinder(*v).subst(tcx, substs)
587+
v.subst(tcx, substs)
587588
} else {
588-
*v
589+
v.skip_binder()
589590
}
590591
}
591592

@@ -594,15 +595,15 @@ impl<'tcx> Instance<'tcx> {
594595
&self,
595596
tcx: TyCtxt<'tcx>,
596597
param_env: ty::ParamEnv<'tcx>,
597-
v: T,
598+
v: EarlyBinder<T>,
598599
) -> T
599600
where
600601
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
601602
{
602603
if let Some(substs) = self.substs_for_mir_body() {
603604
tcx.subst_and_normalize_erasing_regions(substs, param_env, v)
604605
} else {
605-
tcx.normalize_erasing_regions(param_env, v)
606+
tcx.normalize_erasing_regions(param_env, v.skip_binder())
606607
}
607608
}
608609

@@ -611,15 +612,15 @@ impl<'tcx> Instance<'tcx> {
611612
&self,
612613
tcx: TyCtxt<'tcx>,
613614
param_env: ty::ParamEnv<'tcx>,
614-
v: T,
615+
v: EarlyBinder<T>,
615616
) -> Result<T, NormalizationError<'tcx>>
616617
where
617618
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
618619
{
619620
if let Some(substs) = self.substs_for_mir_body() {
620621
tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v)
621622
} else {
622-
tcx.try_normalize_erasing_regions(param_env, v)
623+
tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
623624
}
624625
}
625626

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1739,7 +1739,7 @@ pub struct Destructor {
17391739

17401740
bitflags! {
17411741
#[derive(HashStable, TyEncodable, TyDecodable)]
1742-
pub struct VariantFlags: u32 {
1742+
pub struct VariantFlags: u8 {
17431743
const NO_VARIANT_FLAGS = 0;
17441744
/// Indicates whether the field list of this variant is `#[non_exhaustive]`.
17451745
const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;

0 commit comments

Comments
 (0)