Skip to content

Rollup of 7 pull requests #113205

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

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
168de14
Make simd_shuffle_indices use valtrees
oli-obk Jun 16, 2023
acdfec6
Move mir const to valtree conversion to its own method.
oli-obk Jun 20, 2023
1c992c0
Assert that we don't convert unevaluated MIR promoteds to unevaluated…
oli-obk Jun 26, 2023
368f517
Set `channel = nightly` in dist profile
jyn514 Jun 30, 2023
5318545
document that the panic in collect_intra_doc_links is load-bearing
jyn514 Jun 30, 2023
91bc3f0
No need to distinguish LocalTy from Ty
compiler-errors Jun 30, 2023
4fbd6d5
Merge `un_derefer` into `MovePathLookup`
beepster4096 Jun 21, 2023
44a8a8d
Better messages for next in a iterator inside for loops
chenyukang Jun 29, 2023
4189faa
add typecheck for iterator
chenyukang Jun 30, 2023
f748aa5
Update browser-ui-test version to 0.16.8
GuillaumeGomez Jun 30, 2023
60c657f
Improve search-result-display.goml test
GuillaumeGomez Jun 30, 2023
53aadc0
Rollup merge of #112718 - oli-obk:SIMD-destructure_mir_const, r=cjgillot
Dylan-DPC Jun 30, 2023
b2ce846
Rollup merge of #112882 - DrMeepster:new_un_derefer, r=oli-obk
Dylan-DPC Jun 30, 2023
3d5558a
Rollup merge of #113174 - chenyukang:yukang-fix-102972-loop-next, r=c…
Dylan-DPC Jun 30, 2023
b3a7187
Rollup merge of #113185 - jyn514:dist-channel, r=ozkanonur
Dylan-DPC Jun 30, 2023
1f13953
Rollup merge of #113186 - jyn514:intra-doc-panic, r=petrochenkov
Dylan-DPC Jun 30, 2023
3179126
Rollup merge of #113187 - compiler-errors:local-ty, r=b-naber
Dylan-DPC Jun 30, 2023
aaee83a
Rollup merge of #113191 - GuillaumeGomez:update-browser-ui-test, r=no…
Dylan-DPC Jun 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 74 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::iter;

use either::Either;
use hir::PatField;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{
Expand Down Expand Up @@ -28,6 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::ObligationCtxt;
use std::iter;

use crate::borrow_set::TwoPhaseActivation;
use crate::borrowck_errors;
Expand Down Expand Up @@ -992,6 +992,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
issued_borrow.borrowed_place,
&issued_spans,
);
self.explain_iterator_advancement_in_for_loop_if_applicable(
&mut err,
span,
&issued_spans,
);
err
}

Expand Down Expand Up @@ -1279,6 +1284,73 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}

/// Suggest using `while let` for call `next` on an iterator in a for loop.
///
/// For example:
/// ```ignore (illustrative)
///
/// for x in iter {
/// ...
/// iter.next()
/// }
/// ```
pub(crate) fn explain_iterator_advancement_in_for_loop_if_applicable(
&self,
err: &mut Diagnostic,
span: Span,
issued_spans: &UseSpans<'tcx>,
) {
let issue_span = issued_spans.args_or_use();
let tcx = self.infcx.tcx;
let hir = tcx.hir();

let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return };
let typeck_results = tcx.typeck(self.mir_def_id());

struct ExprFinder<'hir> {
issue_span: Span,
expr_span: Span,
body_expr: Option<&'hir hir::Expr<'hir>>,
loop_bind: Option<Symbol>,
}
impl<'hir> Visitor<'hir> for ExprFinder<'hir> {
fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
if let hir::ExprKind::Loop(hir::Block{ stmts: [stmt, ..], ..}, _, hir::LoopSource::ForLoop, _) = ex.kind &&
let hir::StmtKind::Expr(hir::Expr{ kind: hir::ExprKind::Match(call, [_, bind, ..], _), ..}) = stmt.kind &&
let hir::ExprKind::Call(path, _args) = call.kind &&
let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IteratorNext, _, _, )) = path.kind &&
let hir::PatKind::Struct(path, [field, ..], _) = bind.pat.kind &&
let hir::QPath::LangItem(LangItem::OptionSome, _, _) = path &&
let PatField { pat: hir::Pat{ kind: hir::PatKind::Binding(_, _, ident, ..), .. }, ..} = field &&
self.issue_span.source_equal(call.span) {
self.loop_bind = Some(ident.name);
}

if let hir::ExprKind::MethodCall(body_call, _recv, ..) = ex.kind &&
body_call.ident.name == sym::next && ex.span.source_equal(self.expr_span) {
self.body_expr = Some(ex);
}

hir::intravisit::walk_expr(self, ex);
}
}
let mut finder =
ExprFinder { expr_span: span, issue_span, loop_bind: None, body_expr: None };
finder.visit_expr(hir.body(body_id).value);

if let Some(loop_bind) = finder.loop_bind &&
let Some(body_expr) = finder.body_expr &&
let Some(def_id) = typeck_results.type_dependent_def_id(body_expr.hir_id) &&
let Some(trait_did) = tcx.trait_of_item(def_id) &&
tcx.is_diagnostic_item(sym::Iterator, trait_did) {
err.note(format!(
"a for loop advances the iterator for you, the result is stored in `{}`.",
loop_bind
));
err.help("if you want to call `next` on a iterator within the loop, consider using `while let`.");
}
}

/// Suggest using closure argument instead of capture.
///
/// For example:
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Avoid pointing to the same function in multiple different
// error messages.
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
self.explain_iterator_advancement_in_for_loop_if_applicable(
err,
span,
&move_spans,
);

let func = tcx.def_path_str(method_did);
err.subdiagnostic(CaptureReasonNote::FuncTakeSelf {
func,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ fn do_mir_borrowck<'tcx>(

let (move_data, move_errors): (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>) =
match MoveData::gather_moves(&body, tcx, param_env) {
Ok((_, move_data)) => (move_data, Vec::new()),
Ok(move_data) => (move_data, Vec::new()),
Err((move_data, move_errors)) => (move_data, move_errors),
};
let promoted_errors = promoted
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,13 +870,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// promotes any complex rvalues to constants.
if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
if let mir::Operand::Constant(constant) = arg {
let c = self.eval_mir_constant(constant);
let (llval, ty) = self.simd_shuffle_indices(
&bx,
constant.span,
self.monomorphize(constant.ty()),
c,
);
let (llval, ty) = self.simd_shuffle_indices(&bx, constant);
return OperandRef {
val: Immediate(llval),
layout: bx.layout_of(ty),
Expand Down
50 changes: 33 additions & 17 deletions compiler/rustc_codegen_ssa/src/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use rustc_middle::mir;
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::{self, Ty};
use rustc_span::source_map::Span;
use rustc_target::abi::Abi;

use super::FunctionCx;
Expand Down Expand Up @@ -59,22 +58,40 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
})
}

/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition
/// that the given `constant` is an `ConstantKind::Unevaluated` and must be convertible to
/// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
pub fn eval_unevaluated_mir_constant_to_valtree(
&self,
constant: &mir::Constant<'tcx>,
) -> Result<Option<ty::ValTree<'tcx>>, ErrorHandled> {
let uv = match constant.literal {
mir::ConstantKind::Unevaluated(uv, _) => uv.shrink(),
other => span_bug!(constant.span, "{other:#?}"),
};
let uv = self.monomorphize(uv);
self.cx.tcx().const_eval_resolve_for_typeck(
ty::ParamEnv::reveal_all(),
uv,
Some(constant.span),
)
}

/// process constant containing SIMD shuffle indices
pub fn simd_shuffle_indices(
&mut self,
bx: &Bx,
span: Span,
ty: Ty<'tcx>,
constant: Result<ConstValue<'tcx>, ErrorHandled>,
constant: &mir::Constant<'tcx>,
) -> (Bx::Value, Ty<'tcx>) {
constant
let ty = self.monomorphize(constant.ty());
let val = self
.eval_unevaluated_mir_constant_to_valtree(constant)
.ok()
.flatten()
.map(|val| {
let field_ty = ty.builtin_index().unwrap();
let c = mir::ConstantKind::from_value(val, ty);
let values: Vec<_> = bx
.tcx()
.destructure_mir_constant(ty::ParamEnv::reveal_all(), c)
.fields
let values: Vec<_> = val
.unwrap_branch()
.iter()
.map(|field| {
if let Some(prim) = field.try_to_scalar() {
Expand All @@ -88,15 +105,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
})
.collect();
let llval = bx.const_struct(&values, false);
(llval, c.ty())
bx.const_struct(&values, false)
})
.unwrap_or_else(|_| {
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span });
.unwrap_or_else(|| {
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
// We've errored, so we don't have to produce working code.
let ty = self.monomorphize(ty);
let llty = bx.backend_type(bx.layout_of(ty));
(bx.const_undef(llty), ty)
})
bx.const_undef(llty)
});
(val, ty)
}
}
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ pub(crate) fn try_destructure_mir_constant<'tcx>(
param_env: ty::ParamEnv<'tcx>,
val: mir::ConstantKind<'tcx>,
) -> InterpResult<'tcx, mir::DestructuredConstant<'tcx>> {
trace!("destructure_mir_constant: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, CanAccessStatics::No);
let op = ecx.eval_mir_constant(&val, None, None)?;

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::callee::{self, DeferredCallResolution};
use crate::errors::CtorIsPrivate;
use crate::method::{self, MethodCallee, SelfSource};
use crate::rvalue_scopes;
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy};
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, RawTy};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
Expand Down Expand Up @@ -135,7 +135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("{:p}", self)
}

pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
pub fn local_ty(&self, span: Span, nid: hir::HirId) -> Ty<'tcx> {
self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
})
Expand Down Expand Up @@ -1152,7 +1152,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);

if let Res::Local(hid) = res {
let ty = self.local_ty(span, hid).decl_ty;
let ty = self.local_ty(span, hid);
let ty = self.normalize(span, ty);
self.write_ty(hir_id, ty);
return (ty, res);
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use crate::method::MethodCallee;
use crate::TupleArgumentsFlag::*;
use crate::{errors, Expectation::*};
use crate::{
struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, Needs, RawTy,
TupleArgumentsFlag,
struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, Needs, RawTy, TupleArgumentsFlag,
};
use rustc_ast as ast;
use rustc_data_structures::fx::FxIndexSet;
Expand Down Expand Up @@ -1423,7 +1422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// See #44848.
let ref_bindings = pat.contains_explicit_ref_binding();

let local_ty = self.local_ty(init.span, hir_id).revealed_ty;
let local_ty = self.local_ty(init.span, hir_id);
if let Some(m) = ref_bindings {
// Somewhat subtle: if we have a `ref` binding in the pattern,
// we want to avoid introducing coercions for the RHS. This is
Expand Down Expand Up @@ -1453,7 +1452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) {
// Determine and write the type which we'll check the pattern against.
let decl_ty = self.local_ty(decl.span, decl.hir_id).decl_ty;
let decl_ty = self.local_ty(decl.span, decl.hir_id);
self.write_ty(decl.hir_id, decl_ty);

// Type check the initializer.
Expand Down Expand Up @@ -1799,9 +1798,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let err = self.tcx.ty_error(guar);
self.write_ty(hir_id, err);
self.write_ty(pat.hir_id, err);
let local_ty = LocalTy { decl_ty: err, revealed_ty: err };
self.locals.borrow_mut().insert(hir_id, local_ty);
self.locals.borrow_mut().insert(pat.hir_id, local_ty);
self.locals.borrow_mut().insert(hir_id, err);
self.locals.borrow_mut().insert(pat.hir_id, err);
}
}

Expand Down
23 changes: 10 additions & 13 deletions compiler/rustc_hir_typeck/src/gather_locals.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{FnCtxt, LocalTy};
use crate::FnCtxt;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::PatKind;
Expand Down Expand Up @@ -48,31 +48,28 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
Self { fcx, outermost_fn_param_pat: None }
}

fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
match ty_opt {
None => {
// Infer the variable's type.
let var_ty = self.fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
});
self.fcx
.locals
.borrow_mut()
.insert(nid, LocalTy { decl_ty: var_ty, revealed_ty: var_ty });
self.fcx.locals.borrow_mut().insert(nid, var_ty);
var_ty
}
Some(typ) => {
// Take type that the user specified.
self.fcx.locals.borrow_mut().insert(nid, typ);
typ.revealed_ty
typ
}
}
}

/// Allocates a [LocalTy] for a declaration, which may have a type annotation. If it does have
/// a type annotation, then the LocalTy stored will be the resolved type. This may be found
/// again during type checking by querying [FnCtxt::local_ty] for the same hir_id.
/// Allocates a type for a declaration, which may have a type annotation. If it does have
/// a type annotation, then the [`Ty`] stored will be the resolved type. This may be found
/// again during type checking by querying [`FnCtxt::local_ty`] for the same hir_id.
fn declare(&mut self, decl: Declaration<'tcx>) {
let local_ty = match decl.ty {
Some(ref ty) => {
Expand All @@ -87,7 +84,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
.user_provided_types_mut()
.insert(ty.hir_id, c_ty);

Some(LocalTy { decl_ty: o_ty.normalized, revealed_ty: o_ty.normalized })
Some(o_ty.normalized)
}
None => None,
};
Expand All @@ -96,7 +93,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
debug!(
"local variable {:?} is assigned type {}",
decl.pat,
self.fcx.ty_to_string(self.fcx.locals.borrow().get(&decl.hir_id).unwrap().decl_ty)
self.fcx.ty_to_string(*self.fcx.locals.borrow().get(&decl.hir_id).unwrap())
);
}
}
Expand Down Expand Up @@ -151,7 +148,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
debug!(
"pattern binding {} is assigned to {} with type {:?}",
ident,
self.fcx.ty_to_string(self.fcx.locals.borrow().get(&p.hir_id).unwrap().decl_ty),
self.fcx.ty_to_string(*self.fcx.locals.borrow().get(&p.hir_id).unwrap()),
var_ty
);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/inherited.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct Inherited<'tcx> {

pub(super) typeck_results: RefCell<ty::TypeckResults<'tcx>>,

pub(super) locals: RefCell<HirIdMap<super::LocalTy<'tcx>>>,
pub(super) locals: RefCell<HirIdMap<Ty<'tcx>>>,

pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,

Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,6 @@ macro_rules! type_error_struct {
})
}

/// The type of a local binding, including the revealed type for anon types.
#[derive(Copy, Clone, Debug)]
pub struct LocalTy<'tcx> {
decl_ty: Ty<'tcx>,
revealed_ty: Ty<'tcx>,
}

/// If this `DefId` is a "primary tables entry", returns
/// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`.
///
Expand Down
Loading