Skip to content
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

Rollup of 5 pull requests #118152

Merged
merged 12 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 @@ -3067,7 +3067,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 @@ -3077,7 +3079,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 @@ -3113,11 +3115,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
Loading