Skip to content

Commit

Permalink
Auto merge of rust-lang#118152 - matthiaskrgr:rollup-bqcck4w, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 5 pull requests

Successful merges:

 - rust-lang#117972 (Add VarDebugInfo to Stable MIR)
 - rust-lang#118109 (rustdoc-search: simplify `checkPath` and `sortResults`)
 - rust-lang#118110 (Document `DefiningAnchor` a bit more)
 - rust-lang#118112 (Don't ICE when ambiguity is found when selecting `Index` implementation in typeck)
 - rust-lang#118135 (Remove quotation from filename in stable_mir)

Failed merges:

 - rust-lang#118012 (Add support for global allocation in smir)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Nov 22, 2023
2 parents fec80b4 + 914891f commit ed10a53
Show file tree
Hide file tree
Showing 17 changed files with 286 additions and 115 deletions.
22 changes: 18 additions & 4 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3063,7 +3063,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return None;
};

self.commit_if_ok(|_| {
self.commit_if_ok(|snapshot| {
let outer_universe = self.universe();

let ocx = ObligationCtxt::new(self);
let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id);
let impl_trait_ref =
Expand All @@ -3073,7 +3075,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Match the impl self type against the base ty. If this fails,
// we just skip this impl, since it's not particularly useful.
let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref);
ocx.eq(&cause, self.param_env, impl_trait_ref.self_ty(), base_ty)?;
ocx.eq(&cause, self.param_env, base_ty, impl_trait_ref.self_ty())?;

// Register the impl's predicates. One of these predicates
// must be unsatisfied, or else we wouldn't have gotten here
Expand Down Expand Up @@ -3109,11 +3111,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Ty::new_projection(self.tcx, index_trait_output_def_id, impl_trait_ref.args),
);

let errors = ocx.select_where_possible();
let true_errors = ocx.select_where_possible();

// Do a leak check -- we can't really report report a useful error here,
// but it at least avoids an ICE when the error has to do with higher-ranked
// lifetimes.
self.leak_check(outer_universe, Some(snapshot))?;

// Bail if we have ambiguity errors, which we can't report in a useful way.
let ambiguity_errors = ocx.select_all_or_error();
if true_errors.is_empty() && !ambiguity_errors.is_empty() {
return Err(NoSolution);
}

// There should be at least one error reported. If not, we
// will still delay a span bug in `report_fulfillment_errors`.
Ok::<_, NoSolution>((
self.err_ctxt().report_fulfillment_errors(errors),
self.err_ctxt().report_fulfillment_errors(true_errors),
impl_trait_ref.args.type_at(1),
element_ty,
))
Expand Down
21 changes: 17 additions & 4 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,13 +956,26 @@ pub enum CodegenObligationError {
FulfillmentError,
}

/// Defines the treatment of opaque types in a given inference context.
///
/// This affects both what opaques are allowed to be defined, but also whether
/// opaques are replaced with inference vars eagerly in the old solver (e.g.
/// in projection, and in the signature during function type-checking).
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
pub enum DefiningAnchor {
/// `DefId` of the item.
/// Define opaques which are in-scope of the `LocalDefId`. Also, eagerly
/// replace opaque types in `replace_opaque_types_with_inference_vars`.
Bind(LocalDefId),
/// When opaque types are not resolved, we `Bubble` up, meaning
/// return the opaque/hidden type pair from query, for caller of query to handle it.
/// In contexts where we don't currently know what opaques are allowed to be
/// defined, such as (old solver) canonical queries, we will simply allow
/// opaques to be defined, but "bubble" them up in the canonical response or
/// otherwise treat them to be handled later.
///
/// We do not eagerly replace opaque types in `replace_opaque_types_with_inference_vars`,
/// which may affect what predicates pass and fail in the old trait solver.
Bubble,
/// Used to catch type mismatch errors when handling opaque types.
/// Do not allow any opaques to be defined. This is used to catch type mismatch
/// errors when handling opaque types, and also should be used when we would
/// otherwise reveal opaques (such as [`Reveal::All`] reveal mode).
Error,
}
71 changes: 61 additions & 10 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use rustc_middle::ty::{self, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, Variance
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_target::abi::FieldIdx;
use stable_mir::mir::mono::InstanceDef;
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
use stable_mir::mir::{
Body, ConstOperand, CopyNonOverlapping, Statement, UserTypeProjection, VarDebugInfoFragment,
VariantIdx,
};
use stable_mir::ty::{
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
Expand Down Expand Up @@ -69,15 +72,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> {

fn get_filename(&self, span: &Span) -> Filename {
let tables = self.0.borrow();
opaque(
&tables
.tcx
.sess
.source_map()
.span_to_filename(tables[*span])
.display(rustc_span::FileNameDisplayPreference::Local)
.to_string(),
)
tables
.tcx
.sess
.source_map()
.span_to_filename(tables[*span])
.display(rustc_span::FileNameDisplayPreference::Local)
.to_string()
}

fn get_lines(&self, span: &Span) -> LineInfo {
Expand Down Expand Up @@ -444,17 +445,67 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
})
.collect(),
self.arg_count,
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
)
}
}

impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
type T = stable_mir::mir::VarDebugInfo;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::mir::VarDebugInfo {
name: self.name.to_string(),
source_info: self.source_info.stable(tables),
composite: self.composite.as_ref().map(|composite| composite.stable(tables)),
value: self.value.stable(tables),
argument_index: self.argument_index,
}
}
}

impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
type T = stable_mir::mir::Statement;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) }
}
}

impl<'tcx> Stable<'tcx> for mir::SourceInfo {
type T = stable_mir::mir::SourceInfo;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() }
}
}

impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
type T = stable_mir::mir::VarDebugInfoFragment;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
VarDebugInfoFragment {
ty: self.ty.stable(tables),
projection: self.projection.iter().map(|e| e.stable(tables)).collect(),
}
}
}

impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
type T = stable_mir::mir::VarDebugInfoContents;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
match self {
mir::VarDebugInfoContents::Place(place) => {
stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables))
}
mir::VarDebugInfoContents::Const(const_operand) => {
let op = ConstOperand {
span: const_operand.span.stable(tables),
user_ty: const_operand.user_ty.map(|index| index.as_usize()),
const_: const_operand.const_.stable(tables),
};
stable_mir::mir::VarDebugInfoContents::Const(op)
}
}
}
}

impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
type T = stable_mir::mir::StatementKind;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
Expand Down
2 changes: 1 addition & 1 deletion compiler/stable_mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub enum ItemKind {
Const,
}

pub type Filename = Opaque;
pub type Filename = String;

/// Holds information about an item in the crate.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Expand Down
50 changes: 47 additions & 3 deletions compiler/stable_mir/src/mir/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::mir::pretty::{function_body, pretty_statement};
use crate::ty::{
AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind,
};
use crate::{Error, Opaque, Span};
use crate::{Error, Opaque, Span, Symbol};
use std::io;

/// The SMIR representation of a single function.
Expand All @@ -19,21 +19,29 @@ pub struct Body {

// The number of arguments this function takes.
pub(super) arg_count: usize,

// Debug information pertaining to user variables, including captures.
pub(super) var_debug_info: Vec<VarDebugInfo>,
}

impl Body {
/// Constructs a `Body`.
///
/// A constructor is required to build a `Body` from outside the crate
/// because the `arg_count` and `locals` fields are private.
pub fn new(blocks: Vec<BasicBlock>, locals: LocalDecls, arg_count: usize) -> Self {
pub fn new(
blocks: Vec<BasicBlock>,
locals: LocalDecls,
arg_count: usize,
var_debug_info: Vec<VarDebugInfo>,
) -> Self {
// If locals doesn't contain enough entries, it can lead to panics in
// `ret_local`, `arg_locals`, and `inner_locals`.
assert!(
locals.len() > arg_count,
"A Body must contain at least a local for the return value and each of the function's arguments"
);
Self { blocks, locals, arg_count }
Self { blocks, locals, arg_count, var_debug_info }
}

/// Return local that holds this function's return value.
Expand Down Expand Up @@ -427,6 +435,42 @@ pub struct Place {
pub projection: Vec<ProjectionElem>,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VarDebugInfo {
pub name: Symbol,
pub source_info: SourceInfo,
pub composite: Option<VarDebugInfoFragment>,
pub value: VarDebugInfoContents,
pub argument_index: Option<u16>,
}

pub type SourceScope = u32;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SourceInfo {
pub span: Span,
pub scope: SourceScope,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VarDebugInfoFragment {
pub ty: Ty,
pub projection: Vec<ProjectionElem>,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum VarDebugInfoContents {
Place(Place),
Const(ConstOperand),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ConstOperand {
pub span: Span,
pub user_ty: Option<UserTypeAnnotationIndex>,
pub const_: Const,
}

// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
// is so it can be used for both Places (for which the projection elements are of type
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
Expand Down
28 changes: 27 additions & 1 deletion compiler/stable_mir/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,12 @@ pub trait MirVisitor {
self.super_assert_msg(msg, location)
}

fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) {
self.super_var_debug_info(var_debug_info);
}

fn super_body(&mut self, body: &Body) {
let Body { blocks, locals: _, arg_count } = body;
let Body { blocks, locals: _, arg_count, var_debug_info } = body;

for bb in blocks {
self.visit_basic_block(bb);
Expand All @@ -145,6 +149,10 @@ pub trait MirVisitor {
for (idx, arg) in body.inner_locals().iter().enumerate() {
self.visit_local_decl(idx + local_start, arg)
}

for info in var_debug_info.iter() {
self.visit_var_debug_info(info);
}
}

fn super_basic_block(&mut self, bb: &BasicBlock) {
Expand Down Expand Up @@ -382,6 +390,24 @@ pub trait MirVisitor {
let _ = args;
}

fn super_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) {
let VarDebugInfo { source_info, composite, value, name: _, argument_index: _ } =
var_debug_info;
self.visit_span(&source_info.span);
let location = Location(source_info.span);
if let Some(composite) = composite {
self.visit_ty(&composite.ty, location);
}
match value {
VarDebugInfoContents::Place(place) => {
self.visit_place(place, PlaceContext::NON_USE, location);
}
VarDebugInfoContents::Const(constant) => {
self.visit_const(&constant.const_, location);
}
}
}

fn super_assert_msg(&mut self, msg: &AssertMessage, location: Location) {
match msg {
AssertMessage::BoundsCheck { len, index } => {
Expand Down
51 changes: 29 additions & 22 deletions src/librustdoc/formats/item_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,42 @@ use crate::clean;
/// Consequently, every change to this type should be synchronized to
/// the `itemTypes` mapping table in `html/static/js/search.js`.
///
/// The search engine in search.js also uses item type numbers as a tie breaker when
/// sorting results. Keywords and primitives are given first because we want them to be easily
/// found by new users who don't know about advanced features like type filters. The rest are
/// mostly in an arbitrary order, but it's easier to test the search engine when
/// it's deterministic, and these are strictly finer-grained than language namespaces, so
/// using the path and the item type together to sort ensures that search sorting is stable.
///
/// In addition, code in `html::render` uses this enum to generate CSS classes, page prefixes, and
/// module headings. If you are adding to this enum and want to ensure that the sidebar also prints
/// a heading, edit the listing in `html/render.rs`, function `sidebar_module`. This uses an
/// ordering based on a helper function inside `item_module`, in the same file.
#[derive(Copy, PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
#[repr(u8)]
pub(crate) enum ItemType {
Module = 0,
ExternCrate = 1,
Import = 2,
Struct = 3,
Enum = 4,
Function = 5,
TypeAlias = 6,
Static = 7,
Trait = 8,
Impl = 9,
TyMethod = 10,
Method = 11,
StructField = 12,
Variant = 13,
Macro = 14,
Primitive = 15,
AssocType = 16,
Constant = 17,
AssocConst = 18,
Union = 19,
ForeignType = 20,
Keyword = 21,
Keyword = 0,
Primitive = 1,
Module = 2,
ExternCrate = 3,
Import = 4,
Struct = 5,
Enum = 6,
Function = 7,
TypeAlias = 8,
Static = 9,
Trait = 10,
Impl = 11,
TyMethod = 12,
Method = 13,
StructField = 14,
Variant = 15,
Macro = 16,
AssocType = 17,
Constant = 18,
AssocConst = 19,
Union = 20,
ForeignType = 21,
OpaqueTy = 22,
ProcAttribute = 23,
ProcDerive = 24,
Expand Down
Loading

0 comments on commit ed10a53

Please sign in to comment.