Skip to content

Commit

Permalink
Auto merge of rust-lang#111342 - Dylan-DPC:rollup-b5p6wzy, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - rust-lang#110297 (Make `(try_)subst_and_normalize_erasing_regions` take `EarlyBinder`)
 - rust-lang#110827 (Fix lifetime suggestion for type aliases with objects in them)
 - rust-lang#111022 (Use smaller ints for bitflags)
 - rust-lang#111056 (Fix some suggestions where a `Box<T>` is expected.)
 - rust-lang#111262 (Further normalize msvc-non-utf8-ouput)
 - rust-lang#111265 (Make generics_of has_self on RPITITs delegate to the opaque)
 - rust-lang#111323 (Give a more helpful error when running the rustc shim directly)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed May 8, 2023
2 parents ea0c22e + 172ddcc commit c86e7fb
Show file tree
Hide file tree
Showing 37 changed files with 312 additions and 85 deletions.
16 changes: 13 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
return;
}

let Some((alias_tys, alias_span)) = self
let Some((alias_tys, alias_span, lt_addition_span)) = self
.infcx
.tcx
.return_type_impl_or_dyn_traits_with_type_alias(suitable_region.def_id) else { return; };
Expand All @@ -858,10 +858,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
()
}
if let TyKind::TraitObject(_, lt, _) = alias_ty.kind {
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
if lt.ident.name == kw::Empty {
spans_suggs.push((lt.ident.span.shrink_to_hi(), " + 'a".to_string()));
} else {
spans_suggs.push((lt.ident.span, "'a".to_string()));
}
}
}
spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));

if let Some(lt_addition_span) = lt_addition_span {
spans_suggs.push((lt_addition_span, "'a, ".to_string()));
} else {
spans_suggs.push((alias_span.shrink_to_hi(), "<'a>".to_string()));
}

diag.multipart_suggestion_verbose(
format!(
"to declare that the trait object {captures}, you can add a lifetime parameter `'a` in the type alias"
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
self.instance.subst_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
value,
ty::EarlyBinder(value),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn make_mir_scope<'ll, 'tcx>(
let callee = cx.tcx.subst_and_normalize_erasing_regions(
instance.substs,
ty::ParamEnv::reveal_all(),
callee,
ty::EarlyBinder(callee),
);
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
cx.dbg_scope_fn(callee, callee_fn_abi, None)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
instance.substs,
ty::ParamEnv::reveal_all(),
cx.tcx.type_of(impl_def_id).skip_binder(),
cx.tcx.type_of(impl_def_id),
);

// Only "class" methods are generally understood by LLVM,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.instance.subst_mir_and_normalize_erasing_regions(
self.cx.tcx(),
ty::ParamEnv::reveal_all(),
value,
ty::EarlyBinder(value),
)
}
}
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> Result<T, InterpError<'tcx>> {
frame
.instance
.try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value)
.try_subst_mir_and_normalize_erasing_regions(
*self.tcx,
self.param_env,
ty::EarlyBinder(value),
)
.map_err(|_| err_inval!(TooGeneric))
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ use parking_lot::RwLock;
use smallvec::SmallVec;

bitflags::bitflags! {
struct EventFilter: u32 {
struct EventFilter: u16 {
const GENERIC_ACTIVITIES = 1 << 0;
const QUERY_PROVIDERS = 1 << 1;
const QUERY_CACHE_HITS = 1 << 2;
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where
.note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new
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
hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new`
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|| self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty)
|| self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty)
|| self.suggest_no_capture_closure(err, expected, expr_ty)
|| self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty)
|| self.suggest_boxing_when_appropriate(err, expr.span, expr.hir_id, expected, expr_ty)
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|| self.suggest_clone_for_ref(err, expr, expr_ty, expected)
Expand Down
28 changes: 28 additions & 0 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,31 @@ pub struct ArgMismatchIndeterminate {
#[primary_span]
pub span: Span,
}

#[derive(Subdiagnostic)]
pub enum SuggestBoxing {
#[note(hir_typeck_suggest_boxing_note)]
#[multipart_suggestion(
hir_typeck_suggest_boxing_when_appropriate,
applicability = "machine-applicable"
)]
Unit {
#[suggestion_part(code = "Box::new(())")]
start: Span,
#[suggestion_part(code = "")]
end: Span,
},
#[note(hir_typeck_suggest_boxing_note)]
AsyncBody,
#[note(hir_typeck_suggest_boxing_note)]
#[multipart_suggestion(
hir_typeck_suggest_boxing_when_appropriate,
applicability = "machine-applicable"
)]
Other {
#[suggestion_part(code = "Box::new(")]
start: Span,
#[suggestion_part(code = ")")]
end: Span,
},
}
20 changes: 14 additions & 6 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// case we can ignore the tail expression (e.g., `'a: {
// break 'a 22; }` would not force the type of the block
// to be `()`).
let tail_expr = blk.expr.as_ref();
let coerce_to_ty = expected.coercion_target_type(self, blk.span);
let coerce = if blk.targeted_by_break {
CoerceMany::new(coerce_to_ty)
Expand All @@ -1537,13 +1536,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

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

let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
let coerce = ctxt.coerce.as_mut().unwrap();
if let Some(tail_expr_ty) = tail_expr_ty {
let tail_expr = tail_expr.unwrap();
if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty {
let span = self.get_expr_coercion_span(tail_expr);
let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
let ty_for_diagnostic = coerce.merged_ty();
Expand Down Expand Up @@ -1596,6 +1595,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self.misc(sp),
&mut |err| {
if let Some(expected_ty) = expected.only_has_type(self) {
if blk.stmts.is_empty() && blk.expr.is_none() {
self.suggest_boxing_when_appropriate(
err,
blk.span,
blk.hir_id,
expected_ty,
self.tcx.mk_unit(),
);
}
if !self.consider_removing_semicolon(blk, expected_ty, err) {
self.err_ctxt().consider_returning_binding(
blk,
Expand All @@ -1608,7 +1616,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// silence this redundant error, as we already emit E0070.

// Our block must be a `assign desugar local; assignment`
if let Some(hir::Node::Block(hir::Block {
if let hir::Block {
stmts:
[
hir::Stmt {
Expand All @@ -1630,7 +1638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
},
],
..
})) = self.tcx.hir().find(blk.hir_id)
} = blk
{
self.comes_from_while_condition(blk.hir_id, |_| {
err.downgrade_to_delayed_bug();
Expand Down
48 changes: 24 additions & 24 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::FnCtxt;

use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel, SuggestBoxing};
use crate::fluent_generated as fluent;
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
Expand All @@ -9,7 +9,8 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
Expr, ExprKind, GenericBound, Node, Path, QPath, Stmt, StmtKind, TyKind, WherePredicate,
AsyncGeneratorKind, Expr, ExprKind, GeneratorKind, GenericBound, HirId, Node, Path, QPath,
Stmt, StmtKind, TyKind, WherePredicate,
};
use rustc_hir_analysis::astconv::AstConv;
use rustc_infer::traits::{self, StatementAsExpression};
Expand Down Expand Up @@ -438,33 +439,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn suggest_boxing_when_appropriate(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
span: Span,
hir_id: HirId,
expected: Ty<'tcx>,
found: Ty<'tcx>,
) -> bool {
if self.tcx.hir().is_inside_const_context(expr.hir_id) {
// Do not suggest `Box::new` in const context.
return false;
}
if !expected.is_box() || found.is_box() {
// Do not suggest `Box::new` in const context.
if self.tcx.hir().is_inside_const_context(hir_id) || !expected.is_box() || found.is_box() {
return false;
}
let boxed_found = self.tcx.mk_box(found);
if self.can_coerce(boxed_found, expected) {
err.multipart_suggestion(
"store this in the heap by calling `Box::new`",
vec![
(expr.span.shrink_to_lo(), "Box::new(".to_string()),
(expr.span.shrink_to_hi(), ")".to_string()),
],
Applicability::MachineApplicable,
);
err.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",
);
if self.can_coerce(self.tcx.mk_box(found), expected) {
let suggest_boxing = match found.kind() {
ty::Tuple(tuple) if tuple.is_empty() => {
SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span }
}
ty::Generator(def_id, ..)
if matches!(
self.tcx.generator_kind(def_id),
Some(GeneratorKind::Async(AsyncGeneratorKind::Closure))
) =>
{
SuggestBoxing::AsyncBody
}
_ => SuggestBoxing::Other { start: span.shrink_to_lo(), end: span.shrink_to_hi() },
};
err.subdiagnostic(suggest_boxing);

true
} else {
false
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use super::{Destructor, FieldDef, GenericPredicates, Ty, TyCtxt, VariantDef, Var

bitflags! {
#[derive(HashStable, TyEncodable, TyDecodable)]
pub struct AdtFlags: u32 {
pub struct AdtFlags: u16 {
const NO_ADT_FLAGS = 0;
/// Indicates whether the ADT is an enum.
const IS_ENUM = 1 << 0;
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,11 +1093,13 @@ impl<'tcx> TyCtxt<'tcx> {
v.0
}

/// 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
/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in
/// its return type, and the associated alias span when type alias is used,
/// along with a span for lifetime suggestion (if there are existing generics).
pub fn return_type_impl_or_dyn_traits_with_type_alias(
self,
scope_def_id: LocalDefId,
) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span)> {
) -> Option<(Vec<&'tcx hir::Ty<'tcx>>, Span, Option<Span>)> {
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
let mut v = TraitObjectVisitor(vec![], self.hir());
// when the return type is a type alias
Expand All @@ -1111,7 +1113,7 @@ impl<'tcx> TyCtxt<'tcx> {
{
v.visit_ty(alias_ty);
if !v.0.is_empty() {
return Some((v.0, alias_generics.span));
return Some((v.0, alias_generics.span, alias_generics.span_for_lifetime_suggestion()));
}
}
return None;
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl<'tcx> Instance<'tcx> {
/// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
let ty = tcx.type_of(self.def.def_id());
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty.skip_binder())
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty)
}

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

pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
where
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
{
let v = v.map_bound(|v| *v);
if let Some(substs) = self.substs_for_mir_body() {
EarlyBinder(*v).subst(tcx, substs)
v.subst(tcx, substs)
} else {
*v
v.skip_binder()
}
}

Expand All @@ -594,15 +595,15 @@ impl<'tcx> Instance<'tcx> {
&self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
v: T,
v: EarlyBinder<T>,
) -> T
where
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
{
if let Some(substs) = self.substs_for_mir_body() {
tcx.subst_and_normalize_erasing_regions(substs, param_env, v)
} else {
tcx.normalize_erasing_regions(param_env, v)
tcx.normalize_erasing_regions(param_env, v.skip_binder())
}
}

Expand All @@ -611,15 +612,15 @@ impl<'tcx> Instance<'tcx> {
&self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
v: T,
v: EarlyBinder<T>,
) -> Result<T, NormalizationError<'tcx>>
where
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
{
if let Some(substs) = self.substs_for_mir_body() {
tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v)
} else {
tcx.try_normalize_erasing_regions(param_env, v)
tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1739,7 +1739,7 @@ pub struct Destructor {

bitflags! {
#[derive(HashStable, TyEncodable, TyDecodable)]
pub struct VariantFlags: u32 {
pub struct VariantFlags: u8 {
const NO_VARIANT_FLAGS = 0;
/// Indicates whether the field list of this variant is `#[non_exhaustive]`.
const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
Expand Down
Loading

0 comments on commit c86e7fb

Please sign in to comment.