Forbid overwriting types in typeck
This commit is contained in:
parent
45920d2f52
commit
661b8f5694
4 changed files with 33 additions and 20 deletions
|
|
@ -146,13 +146,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
|
||||
let mut typeck = self.typeck_results.borrow_mut();
|
||||
let mut node_ty = typeck.node_types_mut();
|
||||
if let Some(ty) = node_ty.get(id)
|
||||
&& ty.references_error()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node_ty.insert(id, ty);
|
||||
if let Some(prev) = node_ty.insert(id, ty) {
|
||||
if prev.references_error() {
|
||||
node_ty.insert(id, prev);
|
||||
} else if !ty.references_error() {
|
||||
// Could change this to a bug, but there's lots of diagnostic code re-lowering
|
||||
// or re-typechecking nodes that were already typecked.
|
||||
// Lots of that diagnostics code relies on subtle effects of re-lowering, so we'll
|
||||
// let it keep doing that and just ensure that compilation won't succeed.
|
||||
self.dcx().span_delayed_bug(
|
||||
self.tcx.hir().span(id),
|
||||
format!("`{prev}` overridden by `{ty}` for {id:?} in {:?}", self.body_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = ty.error_reported() {
|
||||
self.set_tainted_by_errors(e);
|
||||
|
|
|
|||
|
|
@ -1750,10 +1750,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) {
|
||||
pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) -> Ty<'tcx> {
|
||||
// Determine and write the type which we'll check the pattern against.
|
||||
let decl_ty = self.local_ty(decl.span, decl.hir_id);
|
||||
self.write_ty(decl.hir_id, decl_ty);
|
||||
|
||||
// Type check the initializer.
|
||||
if let Some(ref init) = decl.init {
|
||||
|
|
@ -1785,11 +1784,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
self.diverges.set(previous_diverges);
|
||||
}
|
||||
decl_ty
|
||||
}
|
||||
|
||||
/// Type check a `let` statement.
|
||||
fn check_decl_local(&self, local: &'tcx hir::LetStmt<'tcx>) {
|
||||
self.check_decl(local.into());
|
||||
let ty = self.check_decl(local.into());
|
||||
self.write_ty(local.hir_id, ty);
|
||||
if local.pat.is_never_pattern() {
|
||||
self.diverges.set(Diverges::Always {
|
||||
span: local.pat.span,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
error[E0282]: type annotations needed
|
||||
--> $DIR/slice-pattern-refutable.rs:14:9
|
||||
--> $DIR/slice-pattern-refutable.rs:14:28
|
||||
|
|
||||
LL | let [a, b, c] = Zeroes.into() else {
|
||||
| ^^^^^^^^^
|
||||
| --------- ^^^^
|
||||
| |
|
||||
| type must be known at this point
|
||||
|
|
||||
help: consider giving this pattern a type
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | let [a, b, c]: /* Type */ = Zeroes.into() else {
|
||||
| ++++++++++++
|
||||
LL | let [a, b, c] = <Zeroes as Into<T>>::into(Zeroes) else {
|
||||
| ++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/slice-pattern-refutable.rs:21:31
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
error[E0282]: type annotations needed for `&_`
|
||||
--> $DIR/slice-patterns-ambiguity.rs:25:9
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/slice-patterns-ambiguity.rs:25:26
|
||||
|
|
||||
LL | let &[a, b] = Zeroes.into() else {
|
||||
| ^^^^^^^
|
||||
| ------ ^^^^
|
||||
| |
|
||||
| type must be known at this point
|
||||
|
|
||||
help: consider giving this pattern a type, where the placeholders `_` are specified
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | let &[a, b]: &_ = Zeroes.into() else {
|
||||
| ++++
|
||||
LL | let &[a, b] = <Zeroes as Into<&_>>::into(Zeroes) else {
|
||||
| +++++++++++++++++++++++++++ ~
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/slice-patterns-ambiguity.rs:32:29
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue