Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ee5ef3a

Browse files
committedNov 17, 2023
Auto merge of rust-lang#118003 - matthiaskrgr:rollup-80t3uky, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - rust-lang#115476 (document ABI compatibility) - rust-lang#117688 (Misc changes to StableMIR required to Kani use case.) - rust-lang#117998 (On resolve error of `[rest..]`, suggest `[rest @ ..]`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 00bfd6b + 488c2aa commit ee5ef3a

21 files changed

+784
-80
lines changed
 

‎compiler/rustc_resolve/src/late.rs

+8
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ struct DiagnosticMetadata<'ast> {
603603
/// Only used for better errors on `let <pat>: <expr, not type>;`.
604604
current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
605605

606+
current_pat: Option<&'ast Pat>,
607+
606608
/// Used to detect possible `if let` written without `let` and to provide structured suggestion.
607609
in_if_condition: Option<&'ast Expr>,
608610

@@ -703,6 +705,12 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
703705
fn visit_expr(&mut self, expr: &'ast Expr) {
704706
self.resolve_expr(expr, None);
705707
}
708+
fn visit_pat(&mut self, p: &'ast Pat) {
709+
let prev = self.diagnostic_metadata.current_pat;
710+
self.diagnostic_metadata.current_pat = Some(p);
711+
visit::walk_pat(self, p);
712+
self.diagnostic_metadata.current_pat = prev;
713+
}
706714
fn visit_local(&mut self, local: &'ast Local) {
707715
let local_spans = match local.pat.kind {
708716
// We check for this to avoid tuple struct fields.

‎compiler/rustc_resolve/src/late/diagnostics.rs

+27
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
431431
code,
432432
);
433433

434+
self.suggest_at_operator_in_slice_pat_with_range(&mut err, path);
434435
self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
435436

436437
if let Some((span, label)) = base_error.span_label {
@@ -1063,6 +1064,32 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
10631064
true
10641065
}
10651066

1067+
fn suggest_at_operator_in_slice_pat_with_range(
1068+
&mut self,
1069+
err: &mut Diagnostic,
1070+
path: &[Segment],
1071+
) {
1072+
if let Some(pat) = self.diagnostic_metadata.current_pat
1073+
&& let ast::PatKind::Range(Some(start), None, range) = &pat.kind
1074+
&& let ExprKind::Path(None, range_path) = &start.kind
1075+
&& let [segment] = &range_path.segments[..]
1076+
&& let [s] = path
1077+
&& segment.ident == s.ident
1078+
{
1079+
// We've encountered `[first, rest..]` where the user might have meant
1080+
// `[first, rest @ ..]` (#88404).
1081+
err.span_suggestion_verbose(
1082+
segment.ident.span.between(range.span),
1083+
format!(
1084+
"if you meant to collect the rest of the slice in `{}`, use the at operator",
1085+
segment.ident,
1086+
),
1087+
" @ ",
1088+
Applicability::MaybeIncorrect,
1089+
);
1090+
}
1091+
}
1092+
10661093
fn suggest_swapping_misplaced_self_ty_and_trait(
10671094
&mut self,
10681095
err: &mut Diagnostic,

‎compiler/rustc_smir/src/rustc_internal/internal.rs

+132-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,23 @@
66
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
77
use crate::rustc_smir::Tables;
88
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;
9+
use rustc_span::Symbol;
10+
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
11+
use stable_mir::ty::{
12+
Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, GenericArgKind,
13+
GenericArgs, Region, TraitRef, Ty,
14+
};
15+
use stable_mir::{AllocId, CrateItem, DefId};
1116

1217
use super::RustcInternal;
1318

19+
impl<'tcx> RustcInternal<'tcx> for CrateItem {
20+
type T = rustc_span::def_id::DefId;
21+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
22+
self.0.internal(tables)
23+
}
24+
}
25+
1426
impl<'tcx> RustcInternal<'tcx> for DefId {
1527
type T = rustc_span::def_id::DefId;
1628
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
@@ -38,8 +50,9 @@ impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
3850

3951
impl<'tcx> RustcInternal<'tcx> for Region {
4052
type T = rustc_ty::Region<'tcx>;
41-
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
42-
todo!()
53+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
54+
// Cannot recover region. Use erased instead.
55+
tables.tcx.lifetimes.re_erased
4356
}
4457
}
4558

@@ -65,3 +78,118 @@ impl<'tcx> RustcInternal<'tcx> for Const {
6578
tables.constants[self.id]
6679
}
6780
}
81+
82+
impl<'tcx> RustcInternal<'tcx> for MonoItem {
83+
type T = rustc_middle::mir::mono::MonoItem<'tcx>;
84+
85+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
86+
use rustc_middle::mir::mono as rustc_mono;
87+
match self {
88+
MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables)),
89+
MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables)),
90+
MonoItem::GlobalAsm(_) => {
91+
unimplemented!()
92+
}
93+
}
94+
}
95+
}
96+
97+
impl<'tcx> RustcInternal<'tcx> for Instance {
98+
type T = rustc_ty::Instance<'tcx>;
99+
100+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
101+
tables.instances[self.def]
102+
}
103+
}
104+
105+
impl<'tcx> RustcInternal<'tcx> for StaticDef {
106+
type T = rustc_span::def_id::DefId;
107+
108+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
109+
self.0.internal(tables)
110+
}
111+
}
112+
113+
#[allow(rustc::usage_of_qualified_ty)]
114+
impl<'tcx, T> RustcInternal<'tcx> for Binder<T>
115+
where
116+
T: RustcInternal<'tcx>,
117+
T::T: rustc_ty::TypeVisitable<rustc_ty::TyCtxt<'tcx>>,
118+
{
119+
type T = rustc_ty::Binder<'tcx, T::T>;
120+
121+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
122+
rustc_ty::Binder::bind_with_vars(
123+
self.value.internal(tables),
124+
tables.tcx.mk_bound_variable_kinds_from_iter(
125+
self.bound_vars.iter().map(|bound| bound.internal(tables)),
126+
),
127+
)
128+
}
129+
}
130+
131+
impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
132+
type T = rustc_ty::BoundVariableKind;
133+
134+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
135+
match self {
136+
BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind {
137+
BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon,
138+
BoundTyKind::Param(def, symbol) => {
139+
rustc_ty::BoundTyKind::Param(def.0.internal(tables), Symbol::intern(&symbol))
140+
}
141+
}),
142+
BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind {
143+
BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::BrAnon,
144+
BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::BrNamed(
145+
def.0.internal(tables),
146+
Symbol::intern(&symbol),
147+
),
148+
BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::BrEnv,
149+
}),
150+
BoundVariableKind::Const => rustc_ty::BoundVariableKind::Const,
151+
}
152+
}
153+
}
154+
155+
impl<'tcx> RustcInternal<'tcx> for TraitRef {
156+
type T = rustc_ty::TraitRef<'tcx>;
157+
158+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
159+
rustc_ty::TraitRef::new(
160+
tables.tcx,
161+
self.def_id.0.internal(tables),
162+
self.args().internal(tables),
163+
)
164+
}
165+
}
166+
167+
impl<'tcx> RustcInternal<'tcx> for AllocId {
168+
type T = rustc_middle::mir::interpret::AllocId;
169+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
170+
tables.alloc_ids[*self]
171+
}
172+
}
173+
174+
impl<'tcx> RustcInternal<'tcx> for ClosureKind {
175+
type T = rustc_ty::ClosureKind;
176+
177+
fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
178+
match self {
179+
ClosureKind::Fn => rustc_ty::ClosureKind::Fn,
180+
ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut,
181+
ClosureKind::FnOnce => rustc_ty::ClosureKind::FnOnce,
182+
}
183+
}
184+
}
185+
186+
impl<'tcx, T> RustcInternal<'tcx> for &T
187+
where
188+
T: RustcInternal<'tcx>,
189+
{
190+
type T = T::T;
191+
192+
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
193+
(*self).internal(tables)
194+
}
195+
}

‎compiler/rustc_smir/src/rustc_internal/mod.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_span::def_id::{CrateNum, DefId};
1313
use rustc_span::Span;
1414
use scoped_tls::scoped_thread_local;
1515
use stable_mir::ty::IndexedVal;
16+
use stable_mir::Error;
1617
use std::cell::Cell;
1718
use std::cell::RefCell;
1819
use std::fmt::Debug;
@@ -21,11 +22,11 @@ use std::ops::Index;
2122

2223
mod internal;
2324

24-
pub fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
25+
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
2526
with_tables(|tables| item.stable(tables))
2627
}
2728

28-
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: &S) -> S::T {
29+
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: S) -> S::T {
2930
with_tables(|tables| item.internal(tables))
3031
}
3132

@@ -144,12 +145,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
144145
// datastructures and stable MIR datastructures
145146
scoped_thread_local! (static TLV: Cell<*const ()>);
146147

147-
pub(crate) fn init<'tcx>(tables: &TablesWrapper<'tcx>, f: impl FnOnce()) {
148+
pub(crate) fn init<'tcx, F, T>(tables: &TablesWrapper<'tcx>, f: F) -> T
149+
where
150+
F: FnOnce() -> T,
151+
{
148152
assert!(!TLV.is_set());
149153
let ptr = tables as *const _ as *const ();
150-
TLV.set(&Cell::new(ptr), || {
151-
f();
152-
});
154+
TLV.set(&Cell::new(ptr), || f())
153155
}
154156

155157
/// Loads the current context and calls a function with it.
@@ -165,7 +167,10 @@ pub(crate) fn with_tables<'tcx, R>(f: impl FnOnce(&mut Tables<'tcx>) -> R) -> R
165167
})
166168
}
167169

168-
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
170+
pub fn run<F, T>(tcx: TyCtxt<'_>, f: F) -> Result<T, Error>
171+
where
172+
F: FnOnce() -> T,
173+
{
169174
let tables = TablesWrapper(RefCell::new(Tables {
170175
tcx,
171176
def_ids: IndexMap::default(),
@@ -175,7 +180,7 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
175180
instances: IndexMap::default(),
176181
constants: IndexMap::default(),
177182
}));
178-
stable_mir::run(&tables, || init(&tables, f));
183+
stable_mir::run(&tables, || init(&tables, f))
179184
}
180185

181186
#[macro_export]
@@ -241,7 +246,8 @@ macro_rules! run {
241246
queries.global_ctxt().unwrap().enter(|tcx| {
242247
rustc_internal::run(tcx, || {
243248
self.result = Some((self.callback)(tcx));
244-
});
249+
})
250+
.unwrap();
245251
if self.result.as_ref().is_some_and(|val| val.is_continue()) {
246252
Compilation::Continue
247253
} else {

‎compiler/rustc_smir/src/rustc_smir/builder.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@ impl<'tcx> BodyBuilder<'tcx> {
1919
BodyBuilder { tcx, instance }
2020
}
2121

22+
/// Build a stable monomorphic body for a given instance based on the MIR body.
23+
///
24+
/// Note that we skip instantiation for static and constants. Trying to do so can cause ICE.
25+
///
26+
/// We do monomorphize non-generic functions to eval unevaluated constants.
2227
pub fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body {
2328
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) {
29+
if self.tcx.def_kind(self.instance.def_id()).is_fn_like() || !self.instance.args.is_empty()
30+
{
2631
self.visit_body(&mut body);
2732
}
2833
body.stable(tables)
@@ -49,6 +54,20 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
4954
*ty = self.monomorphize(*ty);
5055
}
5156

57+
fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) {
58+
let const_ = self.monomorphize(constant.const_);
59+
let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), None) {
60+
Ok(v) => v,
61+
Err(mir::interpret::ErrorHandled::Reported(..)) => return,
62+
Err(mir::interpret::ErrorHandled::TooGeneric(..)) => {
63+
unreachable!("Failed to evaluate instance constant: {:?}", const_)
64+
}
65+
};
66+
let ty = constant.ty();
67+
constant.const_ = mir::Const::Val(val, ty);
68+
self.super_constant(constant, location);
69+
}
70+
5271
fn tcx(&self) -> TyCtxt<'tcx> {
5372
self.tcx
5473
}
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.