Skip to content

Commit

Permalink
Auto merge of #116605 - GuillaumeGomez:rollup-12ba2o6, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #109422 (rustdoc-search: add impl disambiguator to duplicate assoc items)
 - #116250 (On type error of closure call argument, point at earlier calls that affected inference)
 - #116444 (add test for const-eval error in dead code during monomorphization)
 - #116503 (Update docs for mips target tier demotion.)
 - #116559 (Mark `new_in` as `const` for BTree collections)
 - #116560 (In smir use `FxIndexMap` to store indexed ids)
 - #116574 (Update books)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 10, 2023
2 parents 5b88d65 + 49dd50b commit c30b28b
Show file tree
Hide file tree
Showing 38 changed files with 700 additions and 109 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4504,6 +4504,7 @@ dependencies = [
name = "rustc_smir"
version = "0.0.0"
dependencies = [
"rustc_data_structures",
"rustc_driver",
"rustc_hir",
"rustc_interface",
Expand Down
1 change: 1 addition & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ Compatibility Notes
this should only impact users of other registries, or people who don't publish
to a registry.
[#12291](https://github.com/rust-lang/cargo/pull/12291)
- [Demoted `mips*-unknown-linux-gnu*` targets from host tier 2 to target tier 3 support.](https://github.com/rust-lang/rust/pull/113274)

Version 1.71.1 (2023-08-03)
===========================
Expand Down
71 changes: 69 additions & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{ExprKind, Node, QPath};
use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
Expand All @@ -28,7 +29,7 @@ use rustc_infer::infer::TypeTrace;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, IsSuggestable, Ty};
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{self, sym, BytePos, Span};
Expand Down Expand Up @@ -722,6 +723,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut err,
fn_def_id,
callee_ty,
call_expr,
None,
Some(mismatch_idx),
is_method,
);
Expand Down Expand Up @@ -826,6 +829,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut err,
fn_def_id,
callee_ty,
call_expr,
Some(expected_ty),
Some(expected_idx.as_usize()),
is_method,
);
Expand Down Expand Up @@ -1208,7 +1213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

// Call out where the function is defined
self.label_fn_like(&mut err, fn_def_id, callee_ty, None, is_method);
self.label_fn_like(&mut err, fn_def_id, callee_ty, call_expr, None, None, is_method);

// And add a suggestion block for all of the parameters
let suggestion_text = match suggestion_text {
Expand Down Expand Up @@ -1899,6 +1904,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err: &mut Diagnostic,
callable_def_id: Option<DefId>,
callee_ty: Option<Ty<'tcx>>,
call_expr: &'tcx hir::Expr<'tcx>,
expected_ty: Option<Ty<'tcx>>,
// A specific argument should be labeled, instead of all of them
expected_idx: Option<usize>,
is_method: bool,
Expand Down Expand Up @@ -2015,6 +2022,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let param = expected_idx
.and_then(|expected_idx| self.tcx.hir().body(*body).params.get(expected_idx));
let (kind, span) = if let Some(param) = param {
// Try to find earlier invocations of this closure to find if the type mismatch
// is because of inference. If we find one, point at them.
let mut call_finder = FindClosureArg { tcx: self.tcx, calls: vec![] };
let node = self.tcx
.opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id))
.and_then(|hir_id| self.tcx.hir().find(hir_id));
match node {
Some(hir::Node::Item(item)) => call_finder.visit_item(item),
Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item),
Some(hir::Node::ImplItem(item)) => call_finder.visit_impl_item(item),
_ => {}
}
let typeck = self.typeck_results.borrow();
for (rcvr, args) in call_finder.calls {
if let Some(rcvr_ty) = typeck.node_type_opt(rcvr.hir_id)
&& let ty::Closure(call_def_id, _) = rcvr_ty.kind()
&& def_id == *call_def_id
&& let Some(idx) = expected_idx
&& let Some(arg) = args.get(idx)
&& let Some(arg_ty) = typeck.node_type_opt(arg.hir_id)
&& let Some(expected_ty) = expected_ty
&& self.can_eq(self.param_env, arg_ty, expected_ty)
{
let mut sp: MultiSpan = vec![arg.span].into();
sp.push_span_label(
arg.span,
format!("expected because this argument is of type `{arg_ty}`"),
);
sp.push_span_label(rcvr.span, "in this closure call");
err.span_note(
sp,
format!(
"expected because the closure was earlier called with an \
argument of type `{arg_ty}`",
),
);
break;
}
}

("closure parameter", param.span)
} else {
("closure", self.tcx.def_span(def_id))
Expand All @@ -2028,3 +2075,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}

struct FindClosureArg<'tcx> {
tcx: TyCtxt<'tcx>,
calls: Vec<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
}

impl<'tcx> Visitor<'tcx> for FindClosureArg<'tcx> {
type NestedFilter = rustc_middle::hir::nested_filter::All;

fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
}

fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
if let hir::ExprKind::Call(rcvr, args) = ex.kind {
self.calls.push((rcvr, args));
}
hir::intravisit::walk_expr(self, ex);
}
}
1 change: 1 addition & 0 deletions compiler/rustc_smir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.0.0"
edition = "2021"

[dependencies]
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_driver = { path = "../rustc_driver" }
rustc_hir = { path = "../rustc_hir" }
rustc_interface = { path = "../rustc_interface" }
Expand Down
72 changes: 43 additions & 29 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.

use std::ops::{ControlFlow, Index};

use crate::rustc_internal;
use crate::rustc_smir::Tables;
use rustc_data_structures::fx;
use rustc_driver::{Callbacks, Compilation, RunCompiler};
use rustc_interface::{interface, Queries};
use rustc_middle::mir::interpret::AllocId;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::{CrateNum, DefId};
use rustc_span::Span;
use stable_mir::ty::IndexedVal;
use stable_mir::CompilerError;
use std::fmt::Debug;
use std::hash::Hash;
use std::ops::{ControlFlow, Index};

impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
type Output = DefId;

#[inline(always)]
fn index(&self, index: stable_mir::DefId) -> &Self::Output {
&self.def_ids[index.0]
&self.def_ids[index]
}
}

Expand All @@ -29,7 +32,7 @@ impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {

#[inline(always)]
fn index(&self, index: stable_mir::ty::Span) -> &Self::Output {
&self.spans[index.0]
&self.spans[index]
}
}

Expand Down Expand Up @@ -95,36 +98,15 @@ impl<'tcx> Tables<'tcx> {
}

fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
// FIXME: this becomes inefficient when we have too many ids
for (i, &d) in self.def_ids.iter().enumerate() {
if d == did {
return stable_mir::DefId(i);
}
}
let id = self.def_ids.len();
self.def_ids.push(did);
stable_mir::DefId(id)
self.def_ids.create_or_fetch(did)
}

fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::AllocId {
// FIXME: this becomes inefficient when we have too many ids
if let Some(i) = self.alloc_ids.iter().position(|a| *a == aid) {
return stable_mir::AllocId(i);
};
let id = self.def_ids.len();
self.alloc_ids.push(aid);
stable_mir::AllocId(id)
self.alloc_ids.create_or_fetch(aid)
}

pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
for (i, &sp) in self.spans.iter().enumerate() {
if sp == span {
return stable_mir::ty::Span(i);
}
}
let id = self.spans.len();
self.spans.push(span);
stable_mir::ty::Span(id)
self.spans.create_or_fetch(span)
}
}

Expand All @@ -134,7 +116,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {

pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
stable_mir::run(
Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] },
Tables {
tcx,
def_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
alloc_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
spans: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
types: vec![],
},
f,
);
}
Expand Down Expand Up @@ -197,3 +185,29 @@ where
})
}
}

/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra
/// safety features added.
pub struct IndexMap<K, V> {
index_map: fx::FxIndexMap<K, V>,
}

impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> IndexMap<K, V> {
pub fn create_or_fetch(&mut self, key: K) -> V {
let len = self.index_map.len();
let v = self.index_map.entry(key).or_insert(V::to_val(len));
*v
}
}

impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V>
for IndexMap<K, V>
{
type Output = K;

fn index(&self, index: V) -> &Self::Output {
let (k, v) = self.index_map.get_index(index.to_index()).unwrap();
assert_eq!(*v, index, "Provided value doesn't match with indexed value");
k
}
}
7 changes: 4 additions & 3 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.

use crate::rustc_internal::IndexMap;
use crate::rustc_smir::hir::def::DefKind;
use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
use rustc_hir as hir;
Expand Down Expand Up @@ -201,9 +202,9 @@ impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {

pub struct Tables<'tcx> {
pub tcx: TyCtxt<'tcx>,
pub def_ids: Vec<DefId>,
pub alloc_ids: Vec<AllocId>,
pub spans: Vec<rustc_span::Span>,
pub def_ids: IndexMap<DefId, stable_mir::DefId>,
pub alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
pub spans: IndexMap<rustc_span::Span, Span>,
pub types: Vec<MaybeStable<stable_mir::ty::TyKind, Ty<'tcx>>>,
}

Expand Down
26 changes: 23 additions & 3 deletions compiler/stable_mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use std::fmt;
use std::fmt::Debug;

use self::ty::{
GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind,
GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty,
TyKind,
};

#[macro_use]
Expand All @@ -41,7 +42,7 @@ pub type CrateNum = usize;

/// A unique identification number for each item accessible for the current compilation unit.
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct DefId(pub usize);
pub struct DefId(usize);

impl Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand All @@ -52,9 +53,28 @@ impl Debug for DefId {
}
}

impl IndexedVal for DefId {
fn to_val(index: usize) -> Self {
DefId(index)
}

fn to_index(&self) -> usize {
self.0
}
}

/// A unique identification number for each provenance
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct AllocId(pub usize);
pub struct AllocId(usize);

impl IndexedVal for AllocId {
fn to_val(index: usize) -> Self {
AllocId(index)
}
fn to_index(&self) -> usize {
self.0
}
}

/// A list of crate items.
pub type CrateItems = Vec<CrateItem>;
Expand Down
17 changes: 16 additions & 1 deletion compiler/stable_mir/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub struct Placeholder<T> {
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Span(pub usize);
pub struct Span(usize);

impl Debug for Span {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Expand All @@ -86,6 +86,15 @@ impl Debug for Span {
}
}

impl IndexedVal for Span {
fn to_val(index: usize) -> Self {
Span(index)
}
fn to_index(&self) -> usize {
self.0
}
}

#[derive(Clone, Debug)]
pub enum TyKind {
RigidTy(RigidTy),
Expand Down Expand Up @@ -565,3 +574,9 @@ pub enum ImplPolarity {
Negative,
Reservation,
}

pub trait IndexedVal {
fn to_val(index: usize) -> Self;

fn to_index(&self) -> usize;
}
2 changes: 1 addition & 1 deletion library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
/// map.insert(1, "a");
/// ```
#[unstable(feature = "btreemap_alloc", issue = "32838")]
pub fn new_in(alloc: A) -> BTreeMap<K, V, A> {
pub const fn new_in(alloc: A) -> BTreeMap<K, V, A> {
BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(alloc), _marker: PhantomData }
}
}
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/collections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
/// let mut set: BTreeSet<i32> = BTreeSet::new_in(Global);
/// ```
#[unstable(feature = "btreemap_alloc", issue = "32838")]
pub fn new_in(alloc: A) -> BTreeSet<T, A> {
pub const fn new_in(alloc: A) -> BTreeSet<T, A> {
BTreeSet { map: BTreeMap::new_in(alloc) }
}

Expand Down
2 changes: 1 addition & 1 deletion src/doc/reference
Loading

0 comments on commit c30b28b

Please sign in to comment.