Skip to content

Commit 661b8f5

Browse files
committed
Forbid overwriting types in typeck
1 parent 45920d2 commit 661b8f5

File tree

4 files changed

+33
-20
lines changed

4 files changed

+33
-20
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
146146
debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
147147
let mut typeck = self.typeck_results.borrow_mut();
148148
let mut node_ty = typeck.node_types_mut();
149-
if let Some(ty) = node_ty.get(id)
150-
&& ty.references_error()
151-
{
152-
return;
153-
}
154149

155-
node_ty.insert(id, ty);
150+
if let Some(prev) = node_ty.insert(id, ty) {
151+
if prev.references_error() {
152+
node_ty.insert(id, prev);
153+
} else if !ty.references_error() {
154+
// Could change this to a bug, but there's lots of diagnostic code re-lowering
155+
// or re-typechecking nodes that were already typecked.
156+
// Lots of that diagnostics code relies on subtle effects of re-lowering, so we'll
157+
// let it keep doing that and just ensure that compilation won't succeed.
158+
self.dcx().span_delayed_bug(
159+
self.tcx.hir().span(id),
160+
format!("`{prev}` overridden by `{ty}` for {id:?} in {:?}", self.body_id),
161+
);
162+
}
163+
}
156164

157165
if let Err(e) = ty.error_reported() {
158166
self.set_tainted_by_errors(e);

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1750,10 +1750,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17501750
}
17511751
}
17521752

1753-
pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) {
1753+
pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) -> Ty<'tcx> {
17541754
// Determine and write the type which we'll check the pattern against.
17551755
let decl_ty = self.local_ty(decl.span, decl.hir_id);
1756-
self.write_ty(decl.hir_id, decl_ty);
17571756

17581757
// Type check the initializer.
17591758
if let Some(ref init) = decl.init {
@@ -1785,11 +1784,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17851784
}
17861785
self.diverges.set(previous_diverges);
17871786
}
1787+
decl_ty
17881788
}
17891789

17901790
/// Type check a `let` statement.
17911791
fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) {
1792-
self.check_decl(local.into());
1792+
let ty = self.check_decl(local.into());
1793+
self.write_ty(local.hir_id, ty);
17931794
if local.pat.is_never_pattern() {
17941795
self.diverges.set(Diverges::Always {
17951796
span: local.pat.span,

tests/ui/pattern/slice-pattern-refutable.stderr

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
error[E0282]: type annotations needed
2-
--> $DIR/slice-pattern-refutable.rs:14:9
2+
--> $DIR/slice-pattern-refutable.rs:14:28
33
|
44
LL | let [a, b, c] = Zeroes.into() else {
5-
| ^^^^^^^^^
5+
| --------- ^^^^
6+
| |
7+
| type must be known at this point
68
|
7-
help: consider giving this pattern a type
9+
help: try using a fully qualified path to specify the expected types
810
|
9-
LL | let [a, b, c]: /* Type */ = Zeroes.into() else {
10-
| ++++++++++++
11+
LL | let [a, b, c] = <Zeroes as Into<T>>::into(Zeroes) else {
12+
| ++++++++++++++++++++++++++ ~
1113

1214
error[E0282]: type annotations needed
1315
--> $DIR/slice-pattern-refutable.rs:21:31

tests/ui/pattern/slice-patterns-ambiguity.stderr

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
error[E0282]: type annotations needed for `&_`
2-
--> $DIR/slice-patterns-ambiguity.rs:25:9
1+
error[E0282]: type annotations needed
2+
--> $DIR/slice-patterns-ambiguity.rs:25:26
33
|
44
LL | let &[a, b] = Zeroes.into() else {
5-
| ^^^^^^^
5+
| ------ ^^^^
6+
| |
7+
| type must be known at this point
68
|
7-
help: consider giving this pattern a type, where the placeholders `_` are specified
9+
help: try using a fully qualified path to specify the expected types
810
|
9-
LL | let &[a, b]: &_ = Zeroes.into() else {
10-
| ++++
11+
LL | let &[a, b] = <Zeroes as Into<&_>>::into(Zeroes) else {
12+
| +++++++++++++++++++++++++++ ~
1113

1214
error[E0282]: type annotations needed
1315
--> $DIR/slice-patterns-ambiguity.rs:32:29

0 commit comments

Comments
 (0)