Skip to content

Commit

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

Rollup of 5 pull requests

Successful merges:

 - rust-lang#116911 (Suggest relaxing implicit `type Assoc: Sized;` bound)
 - rust-lang#116961 (Typo suggestion to change bindings with leading underscore)
 - rust-lang#116964 (Add stable Instance::body() and RustcInternal trait)
 - rust-lang#116992 (Mention the syntax for `use` on `mod foo;` if `foo` doesn't exist)
 - rust-lang#116995 (Point at assoc fn definition on type param divergence)

Failed merges:

 - rust-lang#116974 (coverage: Fix inconsistent handling of function signature spans)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 21, 2023
2 parents 249624b + 6d69a20 commit d7af966
Show file tree
Hide file tree
Showing 32 changed files with 346 additions and 29 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_expand/messages.ftl
Expand Up @@ -86,6 +86,7 @@ expand_module_circular =
expand_module_file_not_found =
file not found for module `{$name}`
.help = to create the module `{$name}`, create file "{$default_path}" or "{$secondary_path}"
.note = if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead
expand_module_in_block =
cannot declare a non-inline module inside a block unless it has a path attribute
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_expand/src/errors.rs
Expand Up @@ -350,6 +350,7 @@ pub(crate) struct ModuleInBlockName {
#[derive(Diagnostic)]
#[diag(expand_module_file_not_found, code = "E0583")]
#[help]
#[note]
pub(crate) struct ModuleFileNotFound {
#[primary_span]
pub span: Span,
Expand Down
24 changes: 5 additions & 19 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Expand Up @@ -1557,38 +1557,24 @@ fn compare_number_of_generics<'tcx>(
DiagnosticId::Error("E0049".into()),
);

let mut suffix = None;

let msg =
format!("expected {trait_count} {kind} parameter{}", pluralize!(trait_count),);
if let Some(spans) = trait_spans {
let mut spans = spans.iter();
if let Some(span) = spans.next() {
err.span_label(
*span,
format!(
"expected {} {} parameter{}",
trait_count,
kind,
pluralize!(trait_count),
),
);
err.span_label(*span, msg);
}
for span in spans {
err.span_label(*span, "");
}
} else {
suffix = Some(format!(", expected {trait_count}"));
err.span_label(tcx.def_span(trait_.def_id), msg);
}

if let Some(span) = span {
err.span_label(
span,
format!(
"found {} {} parameter{}{}",
impl_count,
kind,
pluralize!(impl_count),
suffix.unwrap_or_default(),
),
format!("found {} {} parameter{}", impl_count, kind, pluralize!(impl_count),),
);
}

Expand Down
17 changes: 15 additions & 2 deletions compiler/rustc_resolve/src/diagnostics.rs
Expand Up @@ -1511,17 +1511,30 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
),
);
}

let (span, sugg, post) = if let SuggestionTarget::SimilarlyNamed = suggestion.target
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
&& let Some(span) = suggestion.span
&& let Some(candidate) = suggestion.candidate.as_str().strip_prefix("_")
&& snippet == candidate
{
// When the suggested binding change would be from `x` to `_x`, suggest changing the
// original binding definition instead. (#60164)
(span, snippet, ", consider changing it")
} else {
(span, suggestion.candidate.to_string(), "")
};
let msg = match suggestion.target {
SuggestionTarget::SimilarlyNamed => format!(
"{} {} with a similar name exists",
"{} {} with a similar name exists{post}",
suggestion.res.article(),
suggestion.res.descr()
),
SuggestionTarget::SingleItem => {
format!("maybe you meant this {}", suggestion.res.descr())
}
};
err.span_suggestion(span, msg, suggestion.candidate, Applicability::MaybeIncorrect);
err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect);
true
}

Expand Down
61 changes: 61 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -0,0 +1,61 @@
//! Module containing the translation from stable mir constructs to the rustc counterpart.
//!
//! This module will only include a few constructs to allow users to invoke internal rustc APIs
//! due to incomplete stable coverage.

// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
use crate::rustc_smir::{MaybeStable, Tables};
use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty};
use stable_mir::DefId;

use super::RustcInternal;

impl<'tcx> RustcInternal<'tcx> for DefId {
type T = rustc_span::def_id::DefId;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
tables.def_ids[*self]
}
}

impl<'tcx> RustcInternal<'tcx> for GenericArgs {
type T = rustc_ty::GenericArgsRef<'tcx>;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
tables.tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables)))
}
}

impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
type T = rustc_ty::GenericArg<'tcx>;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
match self {
GenericArgKind::Lifetime(reg) => reg.internal(tables).into(),
GenericArgKind::Type(ty) => ty.internal(tables).into(),
GenericArgKind::Const(cnst) => cnst.internal(tables).into(),
}
}
}

impl<'tcx> RustcInternal<'tcx> for Region {
type T = rustc_ty::Region<'tcx>;
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
todo!()
}
}

impl<'tcx> RustcInternal<'tcx> for Ty {
type T = InternalTy<'tcx>;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
match tables.types[self.0] {
MaybeStable::Stable(_) => todo!(),
MaybeStable::Rustc(ty) => ty,
}
}
}

impl<'tcx> RustcInternal<'tcx> for Const {
type T = rustc_ty::Const<'tcx>;
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
todo!()
}
}
10 changes: 10 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Expand Up @@ -20,6 +20,8 @@ use std::fmt::Debug;
use std::hash::Hash;
use std::ops::{ControlFlow, Index};

mod internal;

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

Expand Down Expand Up @@ -231,3 +233,11 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
k
}
}

/// Trait used to translate a stable construct to its rustc counterpart.
///
/// This is basically a mirror of [crate::rustc_smir::Stable].
pub(crate) trait RustcInternal<'tcx> {
type T;
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
}
55 changes: 55 additions & 0 deletions compiler/rustc_smir/src/rustc_smir/builder.rs
@@ -0,0 +1,55 @@
//! Logic required to produce a monomorphic stable body.
//!
//! We first retrieve and monomorphize the rustc body representation, i.e., we generate a
//! monomorphic body using internal representation.
//! After that, we convert the internal representation into a stable one.
use crate::rustc_smir::{Stable, Tables};
use rustc_middle::mir;
use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::ty::{self, Ty, TyCtxt};

/// Builds a monomorphic body for a given instance.
pub struct BodyBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
instance: ty::Instance<'tcx>,
}

impl<'tcx> BodyBuilder<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
BodyBuilder { tcx, instance }
}

pub fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
let mut body = self.tcx.instance_mir(self.instance.def).clone();
let generics = self.tcx.generics_of(self.instance.def_id());
if generics.requires_monomorphization(self.tcx) {
self.visit_body(&mut body);
}
body.stable(tables)
}

fn monomorphize<T>(&self, value: T) -> T
where
T: ty::TypeFoldable<TyCtxt<'tcx>>,
{
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(value),
)
}
}

impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, _location: mir::Location) {
*ct = self.monomorphize(*ct);
}

fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: mir::visit::TyContext) {
*ty = self.monomorphize(*ty);
}

fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
}
22 changes: 18 additions & 4 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Expand Up @@ -7,7 +7,7 @@
//!
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.

use crate::rustc_internal::IndexMap;
use crate::rustc_internal::{IndexMap, RustcInternal};
use crate::rustc_smir::hir::def::DefKind;
use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
use rustc_hir as hir;
Expand All @@ -26,6 +26,7 @@ use stable_mir::{self, opaque, Context, Filename};
use tracing::debug;

mod alloc;
mod builder;

impl<'tcx> Context for Tables<'tcx> {
fn local_crate(&self) -> stable_mir::Crate {
Expand Down Expand Up @@ -171,8 +172,9 @@ impl<'tcx> Context for Tables<'tcx> {
}
}

fn instance_body(&mut self, _def: InstanceDef) -> Body {
todo!("Monomorphize the body")
fn instance_body(&mut self, def: InstanceDef) -> Body {
let instance = self.instances[def];
builder::BodyBuilder::new(self.tcx, instance).build(self)
}

fn instance_ty(&mut self, def: InstanceDef) -> stable_mir::ty::Ty {
Expand All @@ -195,9 +197,21 @@ impl<'tcx> Context for Tables<'tcx> {
let def_id = self[def_id];
let generics = self.tcx.generics_of(def_id);
let result = generics.requires_monomorphization(self.tcx);
println!("req {result}: {def_id:?}");
result
}

fn resolve_instance(
&mut self,
def: stable_mir::ty::FnDef,
args: &stable_mir::ty::GenericArgs,
) -> Option<stable_mir::mir::mono::Instance> {
let def_id = def.0.internal(self);
let args_ref = args.internal(self);
match Instance::resolve(self.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
Ok(Some(instance)) => Some(instance.stable(self)),
Ok(None) | Err(_) => None,
}
}
}

#[derive(Clone)]
Expand Down
Expand Up @@ -2665,6 +2665,29 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Check for foreign traits being reachable.
self.tcx.visible_parent_map(()).get(&def_id).is_some()
};
if Some(def_id) == self.tcx.lang_items().sized_trait()
&& let Some(hir::Node::TraitItem(hir::TraitItem {
ident,
kind: hir::TraitItemKind::Type(bounds, None),
..
})) = tcx.hir().get_if_local(item_def_id)
// Do not suggest relaxing if there is an explicit `Sized` obligation.
&& !bounds.iter()
.filter_map(|bound| bound.trait_ref())
.any(|tr| tr.trait_def_id() == self.tcx.lang_items().sized_trait())
{
let (span, separator) = if let [.., last] = bounds {
(last.span().shrink_to_hi(), " +")
} else {
(ident.span.shrink_to_hi(), ":")
};
err.span_suggestion_verbose(
span,
"consider relaxing the implicit `Sized` restriction",
format!("{separator} ?Sized"),
Applicability::MachineApplicable,
);
}
if let DefKind::Trait = tcx.def_kind(item_def_id)
&& !visible_item
{
Expand Down
7 changes: 7 additions & 0 deletions compiler/stable_mir/src/error.rs
Expand Up @@ -4,6 +4,7 @@
//! - [CompilerError]: This represents errors that can be raised when invoking the compiler.
//! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.

use std::convert::From;
use std::fmt::{Debug, Display, Formatter};
use std::{error, fmt};

Expand Down Expand Up @@ -31,6 +32,12 @@ impl Error {
}
}

impl From<&str> for Error {
fn from(value: &str) -> Self {
Self(value.into())
}
}

impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
Expand Down
4 changes: 4 additions & 0 deletions compiler/stable_mir/src/lib.rs
Expand Up @@ -39,6 +39,7 @@ pub mod visitor;

pub use error::*;
use mir::mono::Instance;
use ty::{FnDef, GenericArgs};

/// Use String for now but we should replace it.
pub type Symbol = String;
Expand Down Expand Up @@ -233,6 +234,9 @@ pub trait Context {

/// Item requires monomorphization.
fn requires_monomorphization(&self, def_id: DefId) -> bool;

/// Resolve an instance from the given function definition and generic arguments.
fn resolve_instance(&mut self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
}

// A thread local variable that stores a pointer to the tables mapping between TyCtxt
Expand Down
27 changes: 26 additions & 1 deletion compiler/stable_mir/src/mir/body.rs
Expand Up @@ -5,9 +5,11 @@ use crate::{ty::Ty, Span};
#[derive(Clone, Debug)]
pub struct Body {
pub blocks: Vec<BasicBlock>,
pub locals: Vec<LocalDecl>,
pub locals: LocalDecls,
}

type LocalDecls = Vec<LocalDecl>;

#[derive(Clone, Debug)]
pub struct LocalDecl {
pub ty: Ty,
Expand Down Expand Up @@ -344,6 +346,7 @@ pub enum Operand {
#[derive(Clone, Debug)]
pub struct Place {
pub local: Local,
/// projection out of a place (access a field, deref a pointer, etc)
pub projection: String,
}

Expand Down Expand Up @@ -462,3 +465,25 @@ pub enum NullOp {
/// Returns the offset of a field.
OffsetOf(Vec<FieldIdx>),
}

impl Operand {
pub fn ty(&self, locals: &LocalDecls) -> Ty {
match self {
Operand::Copy(place) | Operand::Move(place) => place.ty(locals),
Operand::Constant(c) => c.ty(),
}
}
}

impl Constant {
pub fn ty(&self) -> Ty {
self.literal.ty
}
}

impl Place {
pub fn ty(&self, locals: &LocalDecls) -> Ty {
let _start_ty = locals[self.local].ty;
todo!("Implement projection")
}
}

0 comments on commit d7af966

Please sign in to comment.