Skip to content

Commit 5f37001

Browse files
committed
Auto merge of rust-lang#95215 - Dylan-DPC:rollup-l9f9t7l, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - rust-lang#95188 ([`macro-metavar-expr`] Fix generated tokens hygiene) - rust-lang#95196 (rename LocalState::Uninitialized to Unallocated) - rust-lang#95197 (Suggest constraining param for unary ops when missing trait impl) - rust-lang#95200 (Cancel a not emitted error after parsing const generic args) - rust-lang#95207 (update Termination trait docs) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 64137f0 + 2aca599 commit 5f37001

File tree

10 files changed

+107
-26
lines changed

10 files changed

+107
-26
lines changed

compiler/rustc_const_eval/src/interpret/eval_context.rs

+10-12
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,10 @@ pub struct LocalState<'tcx, Tag: Provenance = AllocId> {
177177
pub enum LocalValue<Tag: Provenance = AllocId> {
178178
/// This local is not currently alive, and cannot be used at all.
179179
Dead,
180-
/// This local is alive but not yet initialized. It can be written to
181-
/// but not read from or its address taken. Locals get initialized on
182-
/// first write because for unsized locals, we do not know their size
183-
/// before that.
184-
Uninitialized,
180+
/// This local is alive but not yet allocated. It cannot be read from or have its address taken,
181+
/// and will be allocated on the first write. This is to support unsized locals, where we cannot
182+
/// know their size in advance.
183+
Unallocated,
185184
/// A normal, live local.
186185
/// Mostly for convenience, we re-use the `Operand` type here.
187186
/// This is an optimization over just always having a pointer here;
@@ -198,7 +197,7 @@ impl<'tcx, Tag: Provenance + 'static> LocalState<'tcx, Tag> {
198197
pub fn access(&self) -> InterpResult<'tcx, Operand<Tag>> {
199198
match self.value {
200199
LocalValue::Dead => throw_ub!(DeadLocal),
201-
LocalValue::Uninitialized => {
200+
LocalValue::Unallocated => {
202201
bug!("The type checker should prevent reading from a never-written local")
203202
}
204203
LocalValue::Live(val) => Ok(val),
@@ -216,8 +215,7 @@ impl<'tcx, Tag: Provenance + 'static> LocalState<'tcx, Tag> {
216215
match self.value {
217216
LocalValue::Dead => throw_ub!(DeadLocal),
218217
LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)),
219-
ref mut
220-
local @ (LocalValue::Live(Operand::Immediate(_)) | LocalValue::Uninitialized) => {
218+
ref mut local @ (LocalValue::Live(Operand::Immediate(_)) | LocalValue::Unallocated) => {
221219
Ok(Ok(local))
222220
}
223221
}
@@ -752,8 +750,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
752750
})?;
753751
}
754752

755-
// Locals are initially uninitialized.
756-
let dummy = LocalState { value: LocalValue::Uninitialized, layout: Cell::new(None) };
753+
// Locals are initially unallocated.
754+
let dummy = LocalState { value: LocalValue::Unallocated, layout: Cell::new(None) };
757755
let mut locals = IndexVec::from_elem(dummy, &body.local_decls);
758756

759757
// Now mark those locals as dead that we do not want to initialize
@@ -921,7 +919,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
921919
assert!(local != mir::RETURN_PLACE, "Cannot make return place live");
922920
trace!("{:?} is now live", local);
923921

924-
let local_val = LocalValue::Uninitialized;
922+
let local_val = LocalValue::Unallocated;
925923
// StorageLive expects the local to be dead, and marks it live.
926924
let old = mem::replace(&mut self.frame_mut().locals[local].value, local_val);
927925
if !matches!(old, LocalValue::Dead) {
@@ -1025,7 +1023,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
10251023

10261024
match self.ecx.stack()[frame].locals[local].value {
10271025
LocalValue::Dead => write!(fmt, " is dead")?,
1028-
LocalValue::Uninitialized => write!(fmt, " is uninitialized")?,
1026+
LocalValue::Unallocated => write!(fmt, " is unallocated")?,
10291027
LocalValue::Live(Operand::Indirect(mplace)) => {
10301028
write!(
10311029
fmt,

compiler/rustc_expand/src/mbe/transcribe.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ pub(super) fn transcribe<'a>(
257257

258258
// Replace meta-variable expressions with the result of their expansion.
259259
mbe::TokenTree::MetaVarExpr(sp, expr) => {
260-
transcribe_metavar_expr(cx, expr, interp, &repeats, &mut result, &sp)?;
260+
transcribe_metavar_expr(cx, expr, interp, &mut marker, &repeats, &mut result, &sp)?;
261261
}
262262

263263
// If we are entering a new delimiter, we push its contents to the `stack` to be
@@ -513,17 +513,23 @@ fn transcribe_metavar_expr<'a>(
513513
cx: &ExtCtxt<'a>,
514514
expr: MetaVarExpr,
515515
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
516+
marker: &mut Marker,
516517
repeats: &[(usize, usize)],
517518
result: &mut Vec<TreeAndSpacing>,
518519
sp: &DelimSpan,
519520
) -> PResult<'a, ()> {
521+
let mut visited_span = || {
522+
let mut span = sp.entire();
523+
marker.visit_span(&mut span);
524+
span
525+
};
520526
match expr {
521527
MetaVarExpr::Count(original_ident, depth_opt) => {
522528
let matched = matched_from_ident(cx, original_ident, interp)?;
523529
let count = count_repetitions(cx, depth_opt, matched, &repeats, sp)?;
524530
let tt = TokenTree::token(
525531
TokenKind::lit(token::Integer, sym::integer(count), None),
526-
sp.entire(),
532+
visited_span(),
527533
);
528534
result.push(tt.into());
529535
}
@@ -536,7 +542,7 @@ fn transcribe_metavar_expr<'a>(
536542
result.push(
537543
TokenTree::token(
538544
TokenKind::lit(token::Integer, sym::integer(*index), None),
539-
sp.entire(),
545+
visited_span(),
540546
)
541547
.into(),
542548
);
@@ -548,7 +554,7 @@ fn transcribe_metavar_expr<'a>(
548554
result.push(
549555
TokenTree::token(
550556
TokenKind::lit(token::Integer, sym::integer(*length), None),
551-
sp.entire(),
557+
visited_span(),
552558
)
553559
.into(),
554560
);

compiler/rustc_mir_transform/src/const_prop.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
244244
) -> InterpResult<'tcx, InterpOperand<Self::PointerTag>> {
245245
let l = &frame.locals[local];
246246

247-
if l.value == LocalValue::Uninitialized {
248-
throw_machine_stop_str!("tried to access an uninitialized local")
247+
if l.value == LocalValue::Unallocated {
248+
throw_machine_stop_str!("tried to access an unallocated local")
249249
}
250250

251251
l.access()
@@ -442,7 +442,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
442442
/// but not reading from them anymore.
443443
fn remove_const(ecx: &mut InterpCx<'mir, 'tcx, ConstPropMachine<'mir, 'tcx>>, local: Local) {
444444
ecx.frame_mut().locals[local] =
445-
LocalState { value: LocalValue::Uninitialized, layout: Cell::new(None) };
445+
LocalState { value: LocalValue::Unallocated, layout: Cell::new(None) };
446446
}
447447

448448
fn lint_root(&self, source_info: SourceInfo) -> Option<HirId> {
@@ -1147,7 +1147,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
11471147
let frame = self.ecx.frame_mut();
11481148
frame.locals[local].value =
11491149
if let StatementKind::StorageLive(_) = statement.kind {
1150-
LocalValue::Uninitialized
1150+
LocalValue::Unallocated
11511151
} else {
11521152
LocalValue::Dead
11531153
};

compiler/rustc_parse/src/parser/path.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -630,10 +630,14 @@ impl<'a> Parser<'a> {
630630
Ok(ty) => GenericArg::Type(ty),
631631
Err(err) => {
632632
if is_const_fn {
633-
if let Ok(expr) = (*snapshot).parse_expr_res(Restrictions::CONST_EXPR, None)
634-
{
635-
self.restore_snapshot(snapshot);
636-
return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span)));
633+
match (*snapshot).parse_expr_res(Restrictions::CONST_EXPR, None) {
634+
Ok(expr) => {
635+
self.restore_snapshot(snapshot);
636+
return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span)));
637+
}
638+
Err(err) => {
639+
err.cancel();
640+
}
637641
}
638642
}
639643
// Try to recover from possible `const` arg without braces.

compiler/rustc_typeck/src/check/op.rs

+21
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
672672
ex.span,
673673
format!("cannot apply unary operator `{}`", op.as_str()),
674674
);
675+
let missing_trait = match op {
676+
hir::UnOp::Deref => unreachable!("check unary op `-` or `!` only"),
677+
hir::UnOp::Not => "std::ops::Not",
678+
hir::UnOp::Neg => "std::ops::Neg",
679+
};
680+
let mut visitor = TypeParamVisitor(vec![]);
681+
visitor.visit_ty(operand_ty);
682+
if let [ty] = &visitor.0[..] {
683+
if let ty::Param(p) = *operand_ty.kind() {
684+
suggest_constraining_param(
685+
self.tcx,
686+
self.body_id,
687+
&mut err,
688+
*ty,
689+
operand_ty,
690+
missing_trait,
691+
p,
692+
true,
693+
);
694+
}
695+
}
675696

676697
let sp = self.tcx.sess.source_map().start_point(ex.span);
677698
if let Some(sp) =

library/std/src/process.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2030,6 +2030,11 @@ pub fn id() -> u32 {
20302030
///
20312031
/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
20322032
/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
2033+
///
2034+
/// Because different runtimes have different specifications on the return value
2035+
/// of the `main` function, this trait is likely to be available only on
2036+
/// standard library's runtime for convenience. Other runtimes are not required
2037+
/// to provide similar functionality.
20332038
#[cfg_attr(not(test), lang = "termination")]
20342039
#[unstable(feature = "termination_trait_lib", issue = "43301")]
20352040
#[rustc_on_unimplemented(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// #95163
2+
fn return_ty() -> impl Into<<() as Reexported;
3+
//~^ ERROR expected one of `(`, `::`, `<`, or `>`, found `;`
4+
5+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected one of `(`, `::`, `<`, or `>`, found `;`
2+
--> $DIR/ice-const-generic-function-return-ty.rs:2:46
3+
|
4+
LL | fn return_ty() -> impl Into<<() as Reexported;
5+
| ^ expected one of `(`, `::`, `<`, or `>`
6+
7+
error: aborting due to previous error
8+

src/test/ui/type/type-check/missing_trait_impl.rs

+6
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,9 @@ fn foo<T>(x: T, y: T) {
88
fn bar<T>(x: T) {
99
x += x; //~ ERROR binary assignment operation `+=` cannot be applied to type `T`
1010
}
11+
12+
fn baz<T>(x: T) {
13+
let y = -x; //~ ERROR cannot apply unary operator `-` to type `T`
14+
let y = !x; //~ ERROR cannot apply unary operator `!` to type `T`
15+
let y = *x; //~ ERROR type `T` cannot be dereferenced
16+
}

src/test/ui/type/type-check/missing_trait_impl.stderr

+30-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,35 @@ help: consider restricting type parameter `T`
2424
LL | fn bar<T: std::ops::AddAssign>(x: T) {
2525
| +++++++++++++++++++++
2626

27-
error: aborting due to 2 previous errors
27+
error[E0600]: cannot apply unary operator `-` to type `T`
28+
--> $DIR/missing_trait_impl.rs:13:13
29+
|
30+
LL | let y = -x;
31+
| ^^ cannot apply unary operator `-`
32+
|
33+
help: consider restricting type parameter `T`
34+
|
35+
LL | fn baz<T: std::ops::Neg<Output = T>>(x: T) {
36+
| +++++++++++++++++++++++++++
37+
38+
error[E0600]: cannot apply unary operator `!` to type `T`
39+
--> $DIR/missing_trait_impl.rs:14:13
40+
|
41+
LL | let y = !x;
42+
| ^^ cannot apply unary operator `!`
43+
|
44+
help: consider restricting type parameter `T`
45+
|
46+
LL | fn baz<T: std::ops::Not<Output = T>>(x: T) {
47+
| +++++++++++++++++++++++++++
48+
49+
error[E0614]: type `T` cannot be dereferenced
50+
--> $DIR/missing_trait_impl.rs:15:13
51+
|
52+
LL | let y = *x;
53+
| ^^
54+
55+
error: aborting due to 5 previous errors
2856

29-
Some errors have detailed explanations: E0368, E0369.
57+
Some errors have detailed explanations: E0368, E0369, E0600, E0614.
3058
For more information about an error, try `rustc --explain E0368`.

0 commit comments

Comments
 (0)