Rollup merge of #123704 - estebank:diag-changes, r=compiler-errors

Tweak value suggestions in `borrowck` and `hir_analysis`

Unify the output of `suggest_assign_value` and `ty_kind_suggestion`.

Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
This commit is contained in:
Matthias Krüger 2024-04-11 09:31:50 +02:00 committed by GitHub
commit 93645f481d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 389 additions and 194 deletions

View file

@ -652,6 +652,68 @@ fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) {
err
}
fn ty_kind_suggestion(&self, ty: Ty<'tcx>) -> Option<String> {
// Keep in sync with `rustc_hir_analysis/src/check/mod.rs:ty_kind_suggestion`.
// FIXME: deduplicate the above.
let tcx = self.infcx.tcx;
let implements_default = |ty| {
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
return false;
};
self.infcx
.type_implements_trait(default_trait, [ty], self.param_env)
.must_apply_modulo_regions()
};
Some(match ty.kind() {
ty::Never | ty::Error(_) => return None,
ty::Bool => "false".to_string(),
ty::Char => "\'x\'".to_string(),
ty::Int(_) | ty::Uint(_) => "42".into(),
ty::Float(_) => "3.14159".into(),
ty::Slice(_) => "[]".to_string(),
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
"vec![]".to_string()
}
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => {
"String::new()".to_string()
}
ty::Adt(def, args) if def.is_box() => {
format!("Box::new({})", self.ty_kind_suggestion(args[0].expect_ty())?)
}
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => {
"None".to_string()
}
ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => {
format!("Ok({})", self.ty_kind_suggestion(args[0].expect_ty())?)
}
ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
ty::Ref(_, ty, mutability) => {
if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) {
"\"\"".to_string()
} else {
let Some(ty) = self.ty_kind_suggestion(*ty) else {
return None;
};
format!("&{}{ty}", mutability.prefix_str())
}
}
ty::Array(ty, len) => format!(
"[{}; {}]",
self.ty_kind_suggestion(*ty)?,
len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()),
),
ty::Tuple(tys) => format!(
"({})",
tys.iter()
.map(|ty| self.ty_kind_suggestion(ty))
.collect::<Option<Vec<String>>>()?
.join(", ")
),
_ => "value".to_string(),
})
}
fn suggest_assign_value(
&self,
err: &mut Diag<'_>,
@ -661,34 +723,16 @@ fn suggest_assign_value(
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
debug!("ty: {:?}, kind: {:?}", ty, ty.kind());
let tcx = self.infcx.tcx;
let implements_default = |ty, param_env| {
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
return false;
};
self.infcx
.type_implements_trait(default_trait, [ty], param_env)
.must_apply_modulo_regions()
let Some(assign_value) = self.ty_kind_suggestion(ty) else {
return;
};
let assign_value = match ty.kind() {
ty::Bool => "false",
ty::Float(_) => "0.0",
ty::Int(_) | ty::Uint(_) => "0",
ty::Never | ty::Error(_) => "",
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => "vec![]",
ty::Adt(_, _) if implements_default(ty, self.param_env) => "Default::default()",
_ => "todo!()",
};
if !assign_value.is_empty() {
err.span_suggestion_verbose(
sugg_span.shrink_to_hi(),
"consider assigning a value",
format!(" = {assign_value}"),
Applicability::MaybeIncorrect,
);
}
err.span_suggestion_verbose(
sugg_span.shrink_to_hi(),
"consider assigning a value",
format!(" = {assign_value}"),
Applicability::MaybeIncorrect,
);
}
fn suggest_borrow_fn_like(

View file

@ -22,7 +22,6 @@
AdtDef, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
};
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_span::symbol::sym;
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;

View file

@ -81,6 +81,7 @@
use rustc_errors::{pluralize, struct_span_code_err, Diag};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::Mutability;
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::error_reporting::ObligationCauseExt as _;
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
@ -91,10 +92,11 @@
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_session::parse::feature_err;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{self, def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::ObligationCtxt;
@ -466,14 +468,64 @@ fn fn_sig_suggestion<'tcx>(
)
}
pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
pub fn ty_kind_suggestion<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<String> {
// Keep in sync with `rustc_borrowck/src/diagnostics/conflict_errors.rs:ty_kind_suggestion`.
// FIXME: deduplicate the above.
let implements_default = |ty| {
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
return false;
};
let infcx = tcx.infer_ctxt().build();
infcx
.type_implements_trait(default_trait, [ty], ty::ParamEnv::reveal_all())
.must_apply_modulo_regions()
};
Some(match ty.kind() {
ty::Bool => "true",
ty::Char => "'a'",
ty::Int(_) | ty::Uint(_) => "42",
ty::Float(_) => "3.14159",
ty::Error(_) | ty::Never => return None,
_ => "value",
ty::Never | ty::Error(_) => return None,
ty::Bool => "false".to_string(),
ty::Char => "\'x\'".to_string(),
ty::Int(_) | ty::Uint(_) => "42".into(),
ty::Float(_) => "3.14159".into(),
ty::Slice(_) => "[]".to_string(),
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
"vec![]".to_string()
}
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => {
"String::new()".to_string()
}
ty::Adt(def, args) if def.is_box() => {
format!("Box::new({})", ty_kind_suggestion(args[0].expect_ty(), tcx)?)
}
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => {
"None".to_string()
}
ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => {
format!("Ok({})", ty_kind_suggestion(args[0].expect_ty(), tcx)?)
}
ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
ty::Ref(_, ty, mutability) => {
if let (ty::Str, Mutability::Not) = (ty.kind(), mutability) {
"\"\"".to_string()
} else {
let Some(ty) = ty_kind_suggestion(*ty, tcx) else {
return None;
};
format!("&{}{ty}", mutability.prefix_str())
}
}
ty::Array(ty, len) => format!(
"[{}; {}]",
ty_kind_suggestion(*ty, tcx)?,
len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()),
),
ty::Tuple(tys) => format!(
"({})",
tys.iter()
.map(|ty| ty_kind_suggestion(ty, tcx))
.collect::<Option<Vec<String>>>()?
.join(", ")
),
_ => "value".to_string(),
})
}
@ -511,7 +563,7 @@ fn suggestion_signature<'tcx>(
}
ty::AssocKind::Const => {
let ty = tcx.type_of(assoc.def_id).instantiate_identity();
let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
let val = ty_kind_suggestion(ty, tcx).unwrap_or_else(|| "value".to_string());
format!("const {}: {} = {};", assoc.name, ty, val)
}
}

View file

@ -694,10 +694,10 @@ fn check_expr_break(
);
let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty }));
self.annotate_loop_expected_due_to_inference(err, expr, error);
if let Some(val) = ty_kind_suggestion(ty) {
if let Some(val) = ty_kind_suggestion(ty, tcx) {
err.span_suggestion_verbose(
expr.span.shrink_to_hi(),
"give it a value of the expected type",
"give the `break` a value of the expected type",
format!(" {val}"),
Applicability::HasPlaceholders,
);

View file

@ -8,8 +8,8 @@ LL | asm!("{}", in(reg) x);
|
help: consider assigning a value
|
LL | let x: u64 = 0;
| +++
LL | let x: u64 = 42;
| ++++
error[E0381]: used binding `y` isn't initialized
--> $DIR/type-check-2-2.rs:22:9
@ -21,8 +21,8 @@ LL | asm!("{}", inout(reg) y);
|
help: consider assigning a value
|
LL | let mut y: u64 = 0;
| +++
LL | let mut y: u64 = 42;
| ++++
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-2-2.rs:28:13

View file

@ -8,8 +8,8 @@ LL | asm!("{}", in(reg) x);
|
help: consider assigning a value
|
LL | let x: u64 = 0;
| +++
LL | let x: u64 = 42;
| ++++
error[E0381]: used binding `y` isn't initialized
--> $DIR/type-check-5.rs:18:9
@ -21,8 +21,8 @@ LL | asm!("{}", inout(reg) y);
|
help: consider assigning a value
|
LL | let mut y: u64 = 0;
| +++
LL | let mut y: u64 = 42;
| ++++
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-5.rs:24:13

View file

@ -32,8 +32,8 @@ LL | xs
|
help: consider assigning a value
|
LL | let xs = todo!();
| +++++++++
LL | let xs = &42;
| +++++
error: aborting due to 3 previous errors

View file

@ -21,8 +21,8 @@ LL | xs
|
help: consider assigning a value
|
LL | let xs = todo!();
| +++++++++
LL | let xs = &42;
| +++++
error: aborting due to 2 previous errors

View file

@ -10,8 +10,8 @@ LL | println!("{}", x);
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -10,8 +10,8 @@ LL | println!("{}", x);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -10,8 +10,8 @@ LL | println!("{}", x);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | i
|
help: consider assigning a value
|
LL | let i: isize = 0;
| +++
LL | let i: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | i
|
help: consider assigning a value
|
LL | let i: isize = 0;
| +++
LL | let i: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | origin = Point { x: 10, ..origin };
|
help: consider assigning a value
|
LL | let mut origin: Point = todo!();
| +++++++++
LL | let mut origin: Point = value;
| +++++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | v += 1;
|
help: consider assigning a value
|
LL | let v: isize = 0;
| +++
LL | let v: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | v = v + 1;
|
help: consider assigning a value
|
LL | let mut v: isize = 0;
| +++
LL | let mut v: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | return x;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | let _ = x + 1;
|
help: consider assigning a value
|
LL | let x: i32 = 0;
| +++
LL | let x: i32 = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -9,8 +9,8 @@ LL | baz(bar);
|
help: consider assigning a value
|
LL | let bar = 0;
| +++
LL | let bar = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | x += 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:9:5
@ -21,8 +21,8 @@ LL | x -= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:12:5
@ -34,8 +34,8 @@ LL | x *= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:15:5
@ -47,8 +47,8 @@ LL | x /= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:18:5
@ -60,8 +60,8 @@ LL | x %= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:21:5
@ -73,8 +73,8 @@ LL | x ^= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:24:5
@ -86,8 +86,8 @@ LL | x &= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:27:5
@ -99,8 +99,8 @@ LL | x |= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:30:5
@ -112,8 +112,8 @@ LL | x <<= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-in-assignop.rs:33:5
@ -125,8 +125,8 @@ LL | x >>= 1;
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error: aborting due to 10 previous errors

View file

@ -8,8 +8,8 @@ LL | let _y = &**x;
|
help: consider assigning a value
|
LL | let x: &&Box<i32> = todo!();
| +++++++++
LL | let x: &&Box<i32> = &&Box::new(42);
| ++++++++++++++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-uninit-ref-chain.rs:11:14
@ -21,7 +21,7 @@ LL | let _y = &**x;
|
help: consider assigning a value
|
LL | let x: &&S<i32, i32> = todo!();
LL | let x: &&S<i32, i32> = &&value;
| +++++++++
error[E0381]: used binding `x` isn't initialized
@ -34,8 +34,8 @@ LL | let _y = &**x;
|
help: consider assigning a value
|
LL | let x: &&i32 = todo!();
| +++++++++
LL | let x: &&i32 = &&42;
| ++++++
error[E0381]: partially assigned binding `a` isn't fully initialized
--> $DIR/borrowck-uninit-ref-chain.rs:18:5

View file

@ -8,8 +8,8 @@ LL | foo(x);
|
help: consider assigning a value
|
LL | let x: isize = 0;
| +++
LL | let x: isize = 42;
| ++++
error[E0381]: used binding `a` isn't initialized
--> $DIR/borrowck-uninit.rs:14:32

View file

@ -0,0 +1,11 @@
//@ run-rustfix
#[allow(unused_mut)]
fn test() {
let w: &mut [isize] = &mut [];
w[5] = 0; //~ ERROR [E0381]
let mut w: &mut [isize] = &mut [];
w[5] = 0; //~ ERROR [E0381]
}
fn main() { test(); }

View file

@ -1,3 +1,5 @@
//@ run-rustfix
#[allow(unused_mut)]
fn test() {
let w: &mut [isize];
w[5] = 0; //~ ERROR [E0381]

View file

@ -1,5 +1,5 @@
error[E0381]: used binding `w` isn't initialized
--> $DIR/borrowck-use-in-index-lvalue.rs:3:5
--> $DIR/borrowck-use-in-index-lvalue.rs:5:5
|
LL | let w: &mut [isize];
| - binding declared here but left uninitialized
@ -8,11 +8,11 @@ LL | w[5] = 0;
|
help: consider assigning a value
|
LL | let w: &mut [isize] = todo!();
LL | let w: &mut [isize] = &mut [];
| +++++++++
error[E0381]: used binding `w` isn't initialized
--> $DIR/borrowck-use-in-index-lvalue.rs:6:5
--> $DIR/borrowck-use-in-index-lvalue.rs:8:5
|
LL | let mut w: &mut [isize];
| ----- binding declared here but left uninitialized
@ -21,7 +21,7 @@ LL | w[5] = 0;
|
help: consider assigning a value
|
LL | let mut w: &mut [isize] = todo!();
LL | let mut w: &mut [isize] = &mut [];
| +++++++++
error: aborting due to 2 previous errors

View file

@ -0,0 +1,12 @@
// Variation on `borrowck-use-uninitialized-in-cast` in which we do a
// trait cast from an uninitialized source. Issue #20791.
//@ run-rustfix
#![allow(unused_variables, dead_code)]
trait Foo { fn dummy(&self) { } }
impl Foo for i32 { }
fn main() {
let x: &i32 = &42;
let y = x as *const dyn Foo; //~ ERROR [E0381]
}

View file

@ -1,5 +1,7 @@
// Variation on `borrowck-use-uninitialized-in-cast` in which we do a
// trait cast from an uninitialized source. Issue #20791.
//@ run-rustfix
#![allow(unused_variables, dead_code)]
trait Foo { fn dummy(&self) { } }
impl Foo for i32 { }

View file

@ -1,5 +1,5 @@
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:9:13
--> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:11:13
|
LL | let x: &i32;
| - binding declared here but left uninitialized
@ -8,8 +8,8 @@ LL | let y = x as *const dyn Foo;
|
help: consider assigning a value
|
LL | let x: &i32 = todo!();
| +++++++++
LL | let x: &i32 = &42;
| +++++
error: aborting due to 1 previous error

View file

@ -0,0 +1,10 @@
// Check that we detect unused values that are cast to other things.
// The problem was specified to casting to `*`, as creating unsafe
// pointers was not being fully checked. Issue #20791.
//@ run-rustfix
#![allow(unused_variables)]
fn main() {
let x: &i32 = &42;
let y = x as *const i32; //~ ERROR [E0381]
}

View file

@ -1,6 +1,8 @@
// Check that we detect unused values that are cast to other things.
// The problem was specified to casting to `*`, as creating unsafe
// pointers was not being fully checked. Issue #20791.
//@ run-rustfix
#![allow(unused_variables)]
fn main() {
let x: &i32;

View file

@ -1,5 +1,5 @@
error[E0381]: used binding `x` isn't initialized
--> $DIR/borrowck-use-uninitialized-in-cast.rs:7:13
--> $DIR/borrowck-use-uninitialized-in-cast.rs:9:13
|
LL | let x: &i32;
| - binding declared here but left uninitialized
@ -8,8 +8,8 @@ LL | let y = x as *const i32;
|
help: consider assigning a value
|
LL | let x: &i32 = todo!();
| +++++++++
LL | let x: &i32 = &42;
| +++++
error: aborting due to 1 previous error

View file

@ -9,8 +9,8 @@ LL | Err(last_error)
|
help: consider assigning a value
|
LL | let mut last_error: Box<dyn std::error::Error> = todo!();
| +++++++++
LL | let mut last_error: Box<dyn std::error::Error> = Box::new(value);
| +++++++++++++++++
error: aborting due to 1 previous error

View file

@ -10,8 +10,8 @@ LL | println!("{}", x);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let x: i32 = 0;
| +++
LL | let x: i32 = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/issue-24267-flow-exit.rs:18:20
@ -25,8 +25,8 @@ LL | println!("{}", x);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let x: i32 = 0;
| +++
LL | let x: i32 = 42;
| ++++
error: aborting due to 2 previous errors

View file

@ -9,8 +9,8 @@ LL | ref u if true => {}
|
help: consider assigning a value
|
LL | let e: i32 = 0;
| +++
LL | let e: i32 = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | apple(chaenomeles);
|
help: consider assigning a value
|
LL | let chaenomeles = 0;
| +++
LL | let chaenomeles = 42;
| ++++
error[E0381]: used binding `my_float` isn't initialized
--> $DIR/suggest-assign-rvalue.rs:23:30
@ -22,8 +22,8 @@ LL | println!("my_float: {}", my_float);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let my_float: f32 = 0.0;
| +++++
LL | let my_float: f32 = 3.14159;
| +++++++++
error[E0381]: used binding `demo` isn't initialized
--> $DIR/suggest-assign-rvalue.rs:26:28
@ -50,8 +50,8 @@ LL | println!("demo_no: {:?}", demo_no);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let demo_no: DemoNoDef = todo!();
| +++++++++
LL | let demo_no: DemoNoDef = value;
| +++++++
error[E0381]: used binding `arr` isn't initialized
--> $DIR/suggest-assign-rvalue.rs:34:27
@ -64,7 +64,7 @@ LL | println!("arr: {:?}", arr);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let arr: [i32; 5] = todo!();
LL | let arr: [i32; 5] = [42; 5];
| +++++++++
error[E0381]: used binding `foo` isn't initialized
@ -106,8 +106,8 @@ LL | println!("my_int: {}", *my_int);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let my_int: &i32 = todo!();
| +++++++++
LL | let my_int: &i32 = &42;
| +++++
error[E0381]: used binding `hello` isn't initialized
--> $DIR/suggest-assign-rvalue.rs:49:27
@ -120,8 +120,8 @@ LL | println!("hello: {}", hello);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let hello: &str = todo!();
| +++++++++
LL | let hello: &str = "";
| ++++
error[E0381]: used binding `never` isn't initialized
--> $DIR/suggest-assign-rvalue.rs:53:27

View file

@ -79,8 +79,8 @@ LL | let c1 = || match x { };
|
help: consider assigning a value
|
LL | let x: u8 = 0;
| +++
LL | let x: u8 = 42;
| ++++
error: aborting due to 8 previous errors

View file

@ -0,0 +1,6 @@
//@ run-rustfix
pub struct X<const N: usize = {
let s: &'static str = ""; s.len() //~ ERROR E0381
}>;
fn main() {}

View file

@ -1,4 +1,5 @@
struct X<const N: usize = {
//@ run-rustfix
pub struct X<const N: usize = {
let s: &'static str; s.len() //~ ERROR E0381
}>;

View file

@ -1,5 +1,5 @@
error[E0381]: used binding `s` isn't initialized
--> $DIR/const-generic-default-wont-borrowck.rs:2:26
--> $DIR/const-generic-default-wont-borrowck.rs:3:26
|
LL | let s: &'static str; s.len()
| - ^ `*s` used here but it isn't initialized
@ -8,8 +8,8 @@ LL | let s: &'static str; s.len()
|
help: consider assigning a value
|
LL | let s: &'static str = todo!(); s.len()
| +++++++++
LL | let s: &'static str = ""; s.len()
| ++++
error: aborting due to 1 previous error

View file

@ -8,8 +8,8 @@ LL | &x
|
help: consider assigning a value
|
LL | let x = 0;
| +++
LL | let x = 42;
| ++++
error: could not evaluate constant pattern
--> $DIR/issue-78655.rs:7:9

View file

@ -32,8 +32,8 @@ LL | let _ = [x; 0];
|
help: consider assigning a value
|
LL | let x: u8 = 0;
| +++
LL | let x: u8 = 42;
| ++++
error: aborting due to 3 previous errors

View file

@ -19,7 +19,7 @@ LL | loop { break };
| |
| this loop is expected to be of type `i32`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | loop { break 42 };
| ++

View file

@ -23,6 +23,10 @@ fn main() {
};
};
let _: Option<String> = loop {
break; //~ ERROR mismatched types
};
'while_loop: while true { //~ WARN denote infinite loops with
break;
break (); //~ ERROR `break` with value from a `while` loop

View file

@ -1,5 +1,5 @@
warning: label name `'a` shadows a label name that is already in scope
--> $DIR/loop-break-value.rs:136:17
--> $DIR/loop-break-value.rs:140:17
|
LL | 'a: loop {
| -- first declared here
@ -8,7 +8,7 @@ LL | let _ = 'a: loop {
| ^^ label `'a` already in scope
warning: label name `'a` shadows a label name that is already in scope
--> $DIR/loop-break-value.rs:148:17
--> $DIR/loop-break-value.rs:152:17
|
LL | 'a: loop {
| -- first declared here
@ -17,7 +17,7 @@ LL | let _ = 'a: loop {
| ^^ label `'a` already in scope
error[E0425]: cannot find value `LOOP` in this scope
--> $DIR/loop-break-value.rs:95:15
--> $DIR/loop-break-value.rs:99:15
|
LL | 'LOOP: for _ in 0 .. 9 {
| ----- a label with a similar name exists
@ -28,7 +28,7 @@ LL | break LOOP;
| help: use the similarly named label: `'LOOP`
warning: denote infinite loops with `loop { ... }`
--> $DIR/loop-break-value.rs:26:5
--> $DIR/loop-break-value.rs:30:5
|
LL | 'while_loop: while true {
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop`
@ -36,7 +36,7 @@ LL | 'while_loop: while true {
= note: `#[warn(while_true)]` on by default
error[E0571]: `break` with value from a `while` loop
--> $DIR/loop-break-value.rs:28:9
--> $DIR/loop-break-value.rs:32:9
|
LL | 'while_loop: while true {
| ----------------------- you can't `break` with a value in a `while` loop
@ -54,7 +54,7 @@ LL | break 'while_loop;
| ~~~~~~~~~~~
error[E0571]: `break` with value from a `while` loop
--> $DIR/loop-break-value.rs:30:13
--> $DIR/loop-break-value.rs:34:13
|
LL | 'while_loop: while true {
| ----------------------- you can't `break` with a value in a `while` loop
@ -68,7 +68,7 @@ LL | break 'while_loop;
| ~~~~~~~~~~~~~~~~~
error[E0571]: `break` with value from a `while` loop
--> $DIR/loop-break-value.rs:38:12
--> $DIR/loop-break-value.rs:42:12
|
LL | while let Some(_) = Some(()) {
| ---------------------------- you can't `break` with a value in a `while` loop
@ -81,7 +81,7 @@ LL | if break {
| ~~~~~
error[E0571]: `break` with value from a `while` loop
--> $DIR/loop-break-value.rs:43:9
--> $DIR/loop-break-value.rs:47:9
|
LL | while let Some(_) = Some(()) {
| ---------------------------- you can't `break` with a value in a `while` loop
@ -94,7 +94,7 @@ LL | break;
| ~~~~~
error[E0571]: `break` with value from a `while` loop
--> $DIR/loop-break-value.rs:49:13
--> $DIR/loop-break-value.rs:53:13
|
LL | 'while_let_loop: while let Some(_) = Some(()) {
| --------------------------------------------- you can't `break` with a value in a `while` loop
@ -108,7 +108,7 @@ LL | break 'while_let_loop;
| ~~~~~~~~~~~~~~~~~~~~~
error[E0571]: `break` with value from a `for` loop
--> $DIR/loop-break-value.rs:56:9
--> $DIR/loop-break-value.rs:60:9
|
LL | for _ in &[1,2,3] {
| ----------------- you can't `break` with a value in a `for` loop
@ -121,7 +121,7 @@ LL | break;
| ~~~~~
error[E0571]: `break` with value from a `for` loop
--> $DIR/loop-break-value.rs:57:9
--> $DIR/loop-break-value.rs:61:9
|
LL | for _ in &[1,2,3] {
| ----------------- you can't `break` with a value in a `for` loop
@ -135,7 +135,7 @@ LL | break;
| ~~~~~
error[E0571]: `break` with value from a `for` loop
--> $DIR/loop-break-value.rs:64:13
--> $DIR/loop-break-value.rs:68:13
|
LL | 'for_loop: for _ in &[1,2,3] {
| ---------------------------- you can't `break` with a value in a `for` loop
@ -191,7 +191,24 @@ LL | break 'outer_loop "nope";
| ^^^^^^ expected `i32`, found `&str`
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:73:26
--> $DIR/loop-break-value.rs:27:9
|
LL | let _: Option<String> = loop {
| - ---- this loop is expected to be of type `Option<String>`
| |
| expected because of this assignment
LL | break;
| ^^^^^ expected `Option<String>`, found `()`
|
= note: expected enum `Option<String>`
found unit type `()`
help: give the `break` a value of the expected type
|
LL | break None;
| ++++
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:77:26
|
LL | break;
| ----- expected because of this `break`
@ -199,7 +216,7 @@ LL | break 'c 123;
| ^^^ expected `()`, found integer
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:80:15
--> $DIR/loop-break-value.rs:84:15
|
LL | break (break, break);
| ^-----^^-----^
@ -212,7 +229,7 @@ LL | break (break, break);
found tuple `(!, !)`
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:85:15
--> $DIR/loop-break-value.rs:89:15
|
LL | break;
| ----- expected because of this `break`
@ -220,20 +237,20 @@ LL | break 2;
| ^ expected `()`, found integer
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:90:9
--> $DIR/loop-break-value.rs:94:9
|
LL | break 2;
| ------- expected because of this `break`
LL | break;
| ^^^^^ expected integer, found `()`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | break value;
| +++++
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:108:9
--> $DIR/loop-break-value.rs:112:9
|
LL | break 'a 1;
| ---------- expected because of this `break`
@ -241,13 +258,13 @@ LL | break 'a 1;
LL | break;
| ^^^^^ expected integer, found `()`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | break value;
| +++++
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:120:9
--> $DIR/loop-break-value.rs:124:9
|
LL | break 'a 1;
| ---------- expected because of this `break`
@ -255,13 +272,13 @@ LL | break 'a 1;
LL | break 'a;
| ^^^^^^^^ expected integer, found `()`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | break 'a value;
| +++++
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:131:15
--> $DIR/loop-break-value.rs:135:15
|
LL | break;
| ----- expected because of this `break`
@ -270,7 +287,7 @@ LL | break 2;
| ^ expected `()`, found integer
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:140:17
--> $DIR/loop-break-value.rs:144:17
|
LL | break 2;
| ------- expected because of this `break`
@ -278,13 +295,13 @@ LL | loop {
LL | break 'a;
| ^^^^^^^^ expected integer, found `()`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | break 'a value;
| +++++
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:143:15
--> $DIR/loop-break-value.rs:147:15
|
LL | break;
| ----- expected because of this `break`
@ -293,7 +310,7 @@ LL | break 2;
| ^ expected `()`, found integer
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:152:17
--> $DIR/loop-break-value.rs:156:17
|
LL | break 'a 2;
| ---------- expected because of this `break`
@ -301,13 +318,13 @@ LL | loop {
LL | break 'a;
| ^^^^^^^^ expected integer, found `()`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | break 'a value;
| +++++
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:155:15
--> $DIR/loop-break-value.rs:159:15
|
LL | break;
| ----- expected because of this `break`
@ -316,7 +333,7 @@ LL | break 2;
| ^ expected `()`, found integer
error[E0308]: mismatched types
--> $DIR/loop-break-value.rs:159:15
--> $DIR/loop-break-value.rs:163:15
|
LL | fn main() {
| - expected `()` because of this return type
@ -326,7 +343,7 @@ LL | loop { // point at the return type
LL | break 2;
| ^ expected `()`, found integer
error: aborting due to 25 previous errors; 3 warnings emitted
error: aborting due to 26 previous errors; 3 warnings emitted
Some errors have detailed explanations: E0308, E0425, E0571.
For more information about an error, try `rustc --explain E0308`.

View file

@ -7,7 +7,7 @@ LL | let _: i32 = loop { break };
| | this loop is expected to be of type `i32`
| expected because of this assignment
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | let _: i32 = loop { break 42 };
| ++
@ -21,7 +21,7 @@ LL | let _: i32 = 'inner: loop { break 'inner };
| | this loop is expected to be of type `i32`
| expected because of this assignment
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | let _: i32 = 'inner: loop { break 'inner 42 };
| ++
@ -35,7 +35,7 @@ LL | let _: i32 = 'inner2: loop { loop { break 'inner2 } };
| | this loop is expected to be of type `i32`
| expected because of this assignment
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | let _: i32 = 'inner2: loop { loop { break 'inner2 42 } };
| ++

View file

@ -10,8 +10,8 @@ LL | println!("{:?}", x);
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let x: i32 = 0;
| +++
LL | let x: i32 = 42;
| ++++
error: aborting due to 1 previous error

View file

@ -7,7 +7,7 @@ LL | let x: i32 = loop { break };
| | this loop is expected to be of type `i32`
| expected because of this assignment
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | let x: i32 = loop { break 42 };
| ++

View file

@ -56,8 +56,8 @@ LL | let _used = value;
|
help: consider assigning a value
|
LL | let value: NonCopy = todo!();
| +++++++++
LL | let value: NonCopy = value;
| +++++++
error[E0381]: used binding `value` isn't initialized
--> $DIR/issue-72649-uninit-in-loop.rs:69:21
@ -70,8 +70,8 @@ LL | let _used = value;
|
help: consider assigning a value
|
LL | let mut value: NonCopy = todo!();
| +++++++++
LL | let mut value: NonCopy = value;
| +++++++
error: aborting due to 6 previous errors

View file

@ -8,8 +8,8 @@ LL | a[i] = d();
|
help: consider assigning a value
|
LL | let mut a: [D; 4] = todo!();
| +++++++++
LL | let mut a: [D; 4] = [value; 4];
| ++++++++++++
error: aborting due to 1 previous error

View file

@ -9,8 +9,8 @@ LL | std::ptr::addr_of_mut!(x);
= note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider assigning a value
|
LL | let mut x: S = todo!();
| +++++++++
LL | let mut x: S = value;
| +++++++
error: aborting due to 1 previous error

View file

@ -36,7 +36,7 @@ error[E0308]: mismatched types
LL | [(); loop { break }];
| ^^^^^ expected `usize`, found `()`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | [(); loop { break 42 }];
| ++

View file

@ -126,8 +126,8 @@ LL | _ if { x; false } => 2,
|
help: consider assigning a value
|
LL | let x = 0;
| +++
LL | let x = 42;
| ++++
error[E0381]: used binding `x` isn't initialized
--> $DIR/match-cfg-fake-edges.rs:86:31
@ -142,8 +142,8 @@ LL | _ if let Some(()) = { x; None } => 2,
|
help: consider assigning a value
|
LL | let x = 0;
| +++
LL | let x = 42;
| ++++
error[E0382]: use of moved value: `x`
--> $DIR/match-cfg-fake-edges.rs:99:22

View file

@ -43,8 +43,8 @@ LL | match n {}
|
help: consider assigning a value
|
LL | let n: Never = todo!();
| +++++++++
LL | let n: Never = value;
| +++++++
error: aborting due to 4 previous errors

View file

@ -8,7 +8,7 @@ LL | loop {
LL | if false { break; }
| ^^^^^ expected `i32`, found `()`
|
help: give it a value of the expected type
help: give the `break` a value of the expected type
|
LL | if false { break 42; }
| ++

View file

@ -0,0 +1,31 @@
// Verifies that MIR building for a call expression respects
// privacy when checking if a call return type is uninhabited.
//@ run-rustfix
#![allow(unreachable_code, unused_variables)]
pub mod widget {
enum Unimplemented {}
pub struct Widget(Unimplemented);
impl Widget {
pub fn new() -> Widget {
todo!();
}
}
pub fn f() {
let x: &mut u32;
Widget::new();
// Ok. Widget type returned from new is known to be uninhabited
// and the following code is considered unreachable.
*x = 1;
}
}
fn main() {
let y: &mut u32 = &mut 42;
widget::Widget::new();
// Error. Widget type is not known to be uninhabited here,
// so the following code is considered reachable.
*y = 2; //~ ERROR E0381
}

View file

@ -1,5 +1,7 @@
// Verifies that MIR building for a call expression respects
// privacy when checking if a call return type is uninhabited.
//@ run-rustfix
#![allow(unreachable_code, unused_variables)]
pub mod widget {
enum Unimplemented {}

View file

@ -1,5 +1,5 @@
error[E0381]: used binding `y` isn't initialized
--> $DIR/privately-uninhabited-mir-call.rs:28:5
--> $DIR/privately-uninhabited-mir-call.rs:30:5
|
LL | let y: &mut u32;
| - binding declared here but left uninitialized
@ -9,7 +9,7 @@ LL | *y = 2;
|
help: consider assigning a value
|
LL | let y: &mut u32 = todo!();
LL | let y: &mut u32 = &mut 42;
| +++++++++
error: aborting due to 1 previous error