Skip to content

Commit d7af966

Browse files
committed
Auto merge of rust-lang#117002 - matthiaskrgr:rollup-xbnc95q, r=matthiaskrgr
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
2 parents 249624b + 6d69a20 commit d7af966

File tree

32 files changed

+346
-29
lines changed

32 files changed

+346
-29
lines changed

compiler/rustc_expand/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ expand_module_circular =
8686
expand_module_file_not_found =
8787
file not found for module `{$name}`
8888
.help = to create the module `{$name}`, create file "{$default_path}" or "{$secondary_path}"
89+
.note = if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead
8990
9091
expand_module_in_block =
9192
cannot declare a non-inline module inside a block unless it has a path attribute

compiler/rustc_expand/src/errors.rs

+1
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ pub(crate) struct ModuleInBlockName {
350350
#[derive(Diagnostic)]
351351
#[diag(expand_module_file_not_found, code = "E0583")]
352352
#[help]
353+
#[note]
353354
pub(crate) struct ModuleFileNotFound {
354355
#[primary_span]
355356
pub span: Span,

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+5-19
Original file line numberDiff line numberDiff line change
@@ -1557,38 +1557,24 @@ fn compare_number_of_generics<'tcx>(
15571557
DiagnosticId::Error("E0049".into()),
15581558
);
15591559

1560-
let mut suffix = None;
1561-
1560+
let msg =
1561+
format!("expected {trait_count} {kind} parameter{}", pluralize!(trait_count),);
15621562
if let Some(spans) = trait_spans {
15631563
let mut spans = spans.iter();
15641564
if let Some(span) = spans.next() {
1565-
err.span_label(
1566-
*span,
1567-
format!(
1568-
"expected {} {} parameter{}",
1569-
trait_count,
1570-
kind,
1571-
pluralize!(trait_count),
1572-
),
1573-
);
1565+
err.span_label(*span, msg);
15741566
}
15751567
for span in spans {
15761568
err.span_label(*span, "");
15771569
}
15781570
} else {
1579-
suffix = Some(format!(", expected {trait_count}"));
1571+
err.span_label(tcx.def_span(trait_.def_id), msg);
15801572
}
15811573

15821574
if let Some(span) = span {
15831575
err.span_label(
15841576
span,
1585-
format!(
1586-
"found {} {} parameter{}{}",
1587-
impl_count,
1588-
kind,
1589-
pluralize!(impl_count),
1590-
suffix.unwrap_or_default(),
1591-
),
1577+
format!("found {} {} parameter{}", impl_count, kind, pluralize!(impl_count),),
15921578
);
15931579
}
15941580

compiler/rustc_resolve/src/diagnostics.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1511,17 +1511,30 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15111511
),
15121512
);
15131513
}
1514+
1515+
let (span, sugg, post) = if let SuggestionTarget::SimilarlyNamed = suggestion.target
1516+
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
1517+
&& let Some(span) = suggestion.span
1518+
&& let Some(candidate) = suggestion.candidate.as_str().strip_prefix("_")
1519+
&& snippet == candidate
1520+
{
1521+
// When the suggested binding change would be from `x` to `_x`, suggest changing the
1522+
// original binding definition instead. (#60164)
1523+
(span, snippet, ", consider changing it")
1524+
} else {
1525+
(span, suggestion.candidate.to_string(), "")
1526+
};
15141527
let msg = match suggestion.target {
15151528
SuggestionTarget::SimilarlyNamed => format!(
1516-
"{} {} with a similar name exists",
1529+
"{} {} with a similar name exists{post}",
15171530
suggestion.res.article(),
15181531
suggestion.res.descr()
15191532
),
15201533
SuggestionTarget::SingleItem => {
15211534
format!("maybe you meant this {}", suggestion.res.descr())
15221535
}
15231536
};
1524-
err.span_suggestion(span, msg, suggestion.candidate, Applicability::MaybeIncorrect);
1537+
err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect);
15251538
true
15261539
}
15271540

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//! Module containing the translation from stable mir constructs to the rustc counterpart.
2+
//!
3+
//! This module will only include a few constructs to allow users to invoke internal rustc APIs
4+
//! due to incomplete stable coverage.
5+
6+
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
7+
use crate::rustc_smir::{MaybeStable, Tables};
8+
use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
9+
use stable_mir::ty::{Const, GenericArgKind, GenericArgs, Region, Ty};
10+
use stable_mir::DefId;
11+
12+
use super::RustcInternal;
13+
14+
impl<'tcx> RustcInternal<'tcx> for DefId {
15+
type T = rustc_span::def_id::DefId;
16+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
17+
tables.def_ids[*self]
18+
}
19+
}
20+
21+
impl<'tcx> RustcInternal<'tcx> for GenericArgs {
22+
type T = rustc_ty::GenericArgsRef<'tcx>;
23+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
24+
tables.tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables)))
25+
}
26+
}
27+
28+
impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
29+
type T = rustc_ty::GenericArg<'tcx>;
30+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
31+
match self {
32+
GenericArgKind::Lifetime(reg) => reg.internal(tables).into(),
33+
GenericArgKind::Type(ty) => ty.internal(tables).into(),
34+
GenericArgKind::Const(cnst) => cnst.internal(tables).into(),
35+
}
36+
}
37+
}
38+
39+
impl<'tcx> RustcInternal<'tcx> for Region {
40+
type T = rustc_ty::Region<'tcx>;
41+
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
42+
todo!()
43+
}
44+
}
45+
46+
impl<'tcx> RustcInternal<'tcx> for Ty {
47+
type T = InternalTy<'tcx>;
48+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
49+
match tables.types[self.0] {
50+
MaybeStable::Stable(_) => todo!(),
51+
MaybeStable::Rustc(ty) => ty,
52+
}
53+
}
54+
}
55+
56+
impl<'tcx> RustcInternal<'tcx> for Const {
57+
type T = rustc_ty::Const<'tcx>;
58+
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
59+
todo!()
60+
}
61+
}

compiler/rustc_smir/src/rustc_internal/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use std::fmt::Debug;
2020
use std::hash::Hash;
2121
use std::ops::{ControlFlow, Index};
2222

23+
mod internal;
24+
2325
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
2426
type Output = DefId;
2527

@@ -231,3 +233,11 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
231233
k
232234
}
233235
}
236+
237+
/// Trait used to translate a stable construct to its rustc counterpart.
238+
///
239+
/// This is basically a mirror of [crate::rustc_smir::Stable].
240+
pub(crate) trait RustcInternal<'tcx> {
241+
type T;
242+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
243+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//! Logic required to produce a monomorphic stable body.
2+
//!
3+
//! We first retrieve and monomorphize the rustc body representation, i.e., we generate a
4+
//! monomorphic body using internal representation.
5+
//! After that, we convert the internal representation into a stable one.
6+
use crate::rustc_smir::{Stable, Tables};
7+
use rustc_middle::mir;
8+
use rustc_middle::mir::visit::MutVisitor;
9+
use rustc_middle::ty::{self, Ty, TyCtxt};
10+
11+
/// Builds a monomorphic body for a given instance.
12+
pub struct BodyBuilder<'tcx> {
13+
tcx: TyCtxt<'tcx>,
14+
instance: ty::Instance<'tcx>,
15+
}
16+
17+
impl<'tcx> BodyBuilder<'tcx> {
18+
pub fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
19+
BodyBuilder { tcx, instance }
20+
}
21+
22+
pub fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
23+
let mut body = self.tcx.instance_mir(self.instance.def).clone();
24+
let generics = self.tcx.generics_of(self.instance.def_id());
25+
if generics.requires_monomorphization(self.tcx) {
26+
self.visit_body(&mut body);
27+
}
28+
body.stable(tables)
29+
}
30+
31+
fn monomorphize<T>(&self, value: T) -> T
32+
where
33+
T: ty::TypeFoldable<TyCtxt<'tcx>>,
34+
{
35+
self.instance.instantiate_mir_and_normalize_erasing_regions(
36+
self.tcx,
37+
ty::ParamEnv::reveal_all(),
38+
ty::EarlyBinder::bind(value),
39+
)
40+
}
41+
}
42+
43+
impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
44+
fn visit_ty_const(&mut self, ct: &mut ty::Const<'tcx>, _location: mir::Location) {
45+
*ct = self.monomorphize(*ct);
46+
}
47+
48+
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: mir::visit::TyContext) {
49+
*ty = self.monomorphize(*ty);
50+
}
51+
52+
fn tcx(&self) -> TyCtxt<'tcx> {
53+
self.tcx
54+
}
55+
}

compiler/rustc_smir/src/rustc_smir/mod.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//!
88
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
99
10-
use crate::rustc_internal::IndexMap;
10+
use crate::rustc_internal::{IndexMap, RustcInternal};
1111
use crate::rustc_smir::hir::def::DefKind;
1212
use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
1313
use rustc_hir as hir;
@@ -26,6 +26,7 @@ use stable_mir::{self, opaque, Context, Filename};
2626
use tracing::debug;
2727

2828
mod alloc;
29+
mod builder;
2930

3031
impl<'tcx> Context for Tables<'tcx> {
3132
fn local_crate(&self) -> stable_mir::Crate {
@@ -171,8 +172,9 @@ impl<'tcx> Context for Tables<'tcx> {
171172
}
172173
}
173174

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

178180
fn instance_ty(&mut self, def: InstanceDef) -> stable_mir::ty::Ty {
@@ -195,9 +197,21 @@ impl<'tcx> Context for Tables<'tcx> {
195197
let def_id = self[def_id];
196198
let generics = self.tcx.generics_of(def_id);
197199
let result = generics.requires_monomorphization(self.tcx);
198-
println!("req {result}: {def_id:?}");
199200
result
200201
}
202+
203+
fn resolve_instance(
204+
&mut self,
205+
def: stable_mir::ty::FnDef,
206+
args: &stable_mir::ty::GenericArgs,
207+
) -> Option<stable_mir::mir::mono::Instance> {
208+
let def_id = def.0.internal(self);
209+
let args_ref = args.internal(self);
210+
match Instance::resolve(self.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
211+
Ok(Some(instance)) => Some(instance.stable(self)),
212+
Ok(None) | Err(_) => None,
213+
}
214+
}
201215
}
202216

203217
#[derive(Clone)]

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+23
Original file line numberDiff line numberDiff line change
@@ -2665,6 +2665,29 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
26652665
// Check for foreign traits being reachable.
26662666
self.tcx.visible_parent_map(()).get(&def_id).is_some()
26672667
};
2668+
if Some(def_id) == self.tcx.lang_items().sized_trait()
2669+
&& let Some(hir::Node::TraitItem(hir::TraitItem {
2670+
ident,
2671+
kind: hir::TraitItemKind::Type(bounds, None),
2672+
..
2673+
})) = tcx.hir().get_if_local(item_def_id)
2674+
// Do not suggest relaxing if there is an explicit `Sized` obligation.
2675+
&& !bounds.iter()
2676+
.filter_map(|bound| bound.trait_ref())
2677+
.any(|tr| tr.trait_def_id() == self.tcx.lang_items().sized_trait())
2678+
{
2679+
let (span, separator) = if let [.., last] = bounds {
2680+
(last.span().shrink_to_hi(), " +")
2681+
} else {
2682+
(ident.span.shrink_to_hi(), ":")
2683+
};
2684+
err.span_suggestion_verbose(
2685+
span,
2686+
"consider relaxing the implicit `Sized` restriction",
2687+
format!("{separator} ?Sized"),
2688+
Applicability::MachineApplicable,
2689+
);
2690+
}
26682691
if let DefKind::Trait = tcx.def_kind(item_def_id)
26692692
&& !visible_item
26702693
{

compiler/stable_mir/src/error.rs

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! - [CompilerError]: This represents errors that can be raised when invoking the compiler.
55
//! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.
66
7+
use std::convert::From;
78
use std::fmt::{Debug, Display, Formatter};
89
use std::{error, fmt};
910

@@ -31,6 +32,12 @@ impl Error {
3132
}
3233
}
3334

35+
impl From<&str> for Error {
36+
fn from(value: &str) -> Self {
37+
Self(value.into())
38+
}
39+
}
40+
3441
impl Display for Error {
3542
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
3643
Display::fmt(&self.0, f)

compiler/stable_mir/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub mod visitor;
3939

4040
pub use error::*;
4141
use mir::mono::Instance;
42+
use ty::{FnDef, GenericArgs};
4243

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

234235
/// Item requires monomorphization.
235236
fn requires_monomorphization(&self, def_id: DefId) -> bool;
237+
238+
/// Resolve an instance from the given function definition and generic arguments.
239+
fn resolve_instance(&mut self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
236240
}
237241

238242
// A thread local variable that stores a pointer to the tables mapping between TyCtxt

compiler/stable_mir/src/mir/body.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ use crate::{ty::Ty, Span};
55
#[derive(Clone, Debug)]
66
pub struct Body {
77
pub blocks: Vec<BasicBlock>,
8-
pub locals: Vec<LocalDecl>,
8+
pub locals: LocalDecls,
99
}
1010

11+
type LocalDecls = Vec<LocalDecl>;
12+
1113
#[derive(Clone, Debug)]
1214
pub struct LocalDecl {
1315
pub ty: Ty,
@@ -344,6 +346,7 @@ pub enum Operand {
344346
#[derive(Clone, Debug)]
345347
pub struct Place {
346348
pub local: Local,
349+
/// projection out of a place (access a field, deref a pointer, etc)
347350
pub projection: String,
348351
}
349352

@@ -462,3 +465,25 @@ pub enum NullOp {
462465
/// Returns the offset of a field.
463466
OffsetOf(Vec<FieldIdx>),
464467
}
468+
469+
impl Operand {
470+
pub fn ty(&self, locals: &LocalDecls) -> Ty {
471+
match self {
472+
Operand::Copy(place) | Operand::Move(place) => place.ty(locals),
473+
Operand::Constant(c) => c.ty(),
474+
}
475+
}
476+
}
477+
478+
impl Constant {
479+
pub fn ty(&self) -> Ty {
480+
self.literal.ty
481+
}
482+
}
483+
484+
impl Place {
485+
pub fn ty(&self, locals: &LocalDecls) -> Ty {
486+
let _start_ty = locals[self.local].ty;
487+
todo!("Implement projection")
488+
}
489+
}

0 commit comments

Comments
 (0)