mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-30 04:56:25 +03:00
Suggest function-local constructors without enclosing function path
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
use rustc_hir_analysis::suggest_impl_trait;
|
||||
use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_suggestion};
|
||||
use rustc_middle::ty::{
|
||||
self, Article, Binder, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Unnormalized, Upcast,
|
||||
suggest_constraining_type_params,
|
||||
@@ -2679,8 +2679,9 @@ pub(crate) fn suggest_compatible_variants(
|
||||
|
||||
let sole_field_ty = sole_field.ty(self.tcx, args).skip_norm_wip();
|
||||
if self.may_coerce(expr_ty, sole_field_ty) {
|
||||
let variant_path =
|
||||
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
|
||||
let variant_path = with_types_for_suggestion!(with_no_trimmed_paths!(
|
||||
self.tcx.def_path_str(variant.def_id)
|
||||
));
|
||||
// FIXME #56861: DRYer prelude filtering
|
||||
if let Some(path) = variant_path.strip_prefix("std::prelude::")
|
||||
&& let Some((_, path)) = path.split_once("::")
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//@ run-rustfix
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/144319.
|
||||
// Function-local constructors cannot be named through the enclosing function
|
||||
// path. The suggestion must omit path segments that cannot be written in source,
|
||||
// while preserving real path segments like local modules and enums.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn direct_tuple_struct() {
|
||||
struct Foo(bool);
|
||||
struct Bar(Foo);
|
||||
|
||||
_ = Bar(Foo(false));
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `Foo`
|
||||
}
|
||||
|
||||
fn enum_variant() {
|
||||
enum LocalResult<T> {
|
||||
Ok(T),
|
||||
}
|
||||
struct Bar(LocalResult<bool>);
|
||||
|
||||
_ = Bar(LocalResult::Ok(false));
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `LocalResult::Ok`
|
||||
}
|
||||
|
||||
fn local_module() {
|
||||
mod inner {
|
||||
pub struct Foo(pub bool);
|
||||
}
|
||||
struct Bar(inner::Foo);
|
||||
|
||||
_ = Bar(inner::Foo(false));
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `inner::Foo`
|
||||
}
|
||||
|
||||
fn closure_body() {
|
||||
let _ = || {
|
||||
struct Foo(bool);
|
||||
struct Bar(Foo);
|
||||
|
||||
_ = Bar(Foo(false));
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `Foo`
|
||||
};
|
||||
}
|
||||
|
||||
fn inline_const_block() {
|
||||
const {
|
||||
struct Foo(bool);
|
||||
struct Bar(Foo);
|
||||
|
||||
_ = Bar(Foo(false));
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `Foo`
|
||||
};
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
@@ -0,0 +1,63 @@
|
||||
//@ run-rustfix
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/144319.
|
||||
// Function-local constructors cannot be named through the enclosing function
|
||||
// path. The suggestion must omit path segments that cannot be written in source,
|
||||
// while preserving real path segments like local modules and enums.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn direct_tuple_struct() {
|
||||
struct Foo(bool);
|
||||
struct Bar(Foo);
|
||||
|
||||
_ = Bar(false);
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `Foo`
|
||||
}
|
||||
|
||||
fn enum_variant() {
|
||||
enum LocalResult<T> {
|
||||
Ok(T),
|
||||
}
|
||||
struct Bar(LocalResult<bool>);
|
||||
|
||||
_ = Bar(false);
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `LocalResult::Ok`
|
||||
}
|
||||
|
||||
fn local_module() {
|
||||
mod inner {
|
||||
pub struct Foo(pub bool);
|
||||
}
|
||||
struct Bar(inner::Foo);
|
||||
|
||||
_ = Bar(false);
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `inner::Foo`
|
||||
}
|
||||
|
||||
fn closure_body() {
|
||||
let _ = || {
|
||||
struct Foo(bool);
|
||||
struct Bar(Foo);
|
||||
|
||||
_ = Bar(false);
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `Foo`
|
||||
};
|
||||
}
|
||||
|
||||
fn inline_const_block() {
|
||||
const {
|
||||
struct Foo(bool);
|
||||
struct Bar(Foo);
|
||||
|
||||
_ = Bar(false);
|
||||
//~^ ERROR mismatched types
|
||||
//~| HELP try wrapping the expression in `Foo`
|
||||
};
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
@@ -0,0 +1,95 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/wrap-function-local-constructors.rs:14:13
|
||||
|
|
||||
LL | _ = Bar(false);
|
||||
| --- ^^^^^ expected `Foo`, found `bool`
|
||||
| |
|
||||
| arguments to this struct are incorrect
|
||||
|
|
||||
note: tuple struct defined here
|
||||
--> $DIR/wrap-function-local-constructors.rs:12:12
|
||||
|
|
||||
LL | struct Bar(Foo);
|
||||
| ^^^
|
||||
help: try wrapping the expression in `Foo`
|
||||
|
|
||||
LL | _ = Bar(Foo(false));
|
||||
| ++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/wrap-function-local-constructors.rs:25:13
|
||||
|
|
||||
LL | _ = Bar(false);
|
||||
| --- ^^^^^ expected `LocalResult<bool>`, found `bool`
|
||||
| |
|
||||
| arguments to this struct are incorrect
|
||||
|
|
||||
= note: expected enum `LocalResult<bool>`
|
||||
found type `bool`
|
||||
note: tuple struct defined here
|
||||
--> $DIR/wrap-function-local-constructors.rs:23:12
|
||||
|
|
||||
LL | struct Bar(LocalResult<bool>);
|
||||
| ^^^
|
||||
help: try wrapping the expression in `LocalResult::Ok`
|
||||
|
|
||||
LL | _ = Bar(LocalResult::Ok(false));
|
||||
| ++++++++++++++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/wrap-function-local-constructors.rs:36:13
|
||||
|
|
||||
LL | _ = Bar(false);
|
||||
| --- ^^^^^ expected `Foo`, found `bool`
|
||||
| |
|
||||
| arguments to this struct are incorrect
|
||||
|
|
||||
note: tuple struct defined here
|
||||
--> $DIR/wrap-function-local-constructors.rs:34:12
|
||||
|
|
||||
LL | struct Bar(inner::Foo);
|
||||
| ^^^
|
||||
help: try wrapping the expression in `inner::Foo`
|
||||
|
|
||||
LL | _ = Bar(inner::Foo(false));
|
||||
| +++++++++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/wrap-function-local-constructors.rs:46:17
|
||||
|
|
||||
LL | _ = Bar(false);
|
||||
| --- ^^^^^ expected `Foo`, found `bool`
|
||||
| |
|
||||
| arguments to this struct are incorrect
|
||||
|
|
||||
note: tuple struct defined here
|
||||
--> $DIR/wrap-function-local-constructors.rs:44:16
|
||||
|
|
||||
LL | struct Bar(Foo);
|
||||
| ^^^
|
||||
help: try wrapping the expression in `Foo`
|
||||
|
|
||||
LL | _ = Bar(Foo(false));
|
||||
| ++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/wrap-function-local-constructors.rs:57:17
|
||||
|
|
||||
LL | _ = Bar(false);
|
||||
| --- ^^^^^ expected `Foo`, found `bool`
|
||||
| |
|
||||
| arguments to this struct are incorrect
|
||||
|
|
||||
note: tuple struct defined here
|
||||
--> $DIR/wrap-function-local-constructors.rs:55:16
|
||||
|
|
||||
LL | struct Bar(Foo);
|
||||
| ^^^
|
||||
help: try wrapping the expression in `Foo`
|
||||
|
|
||||
LL | _ = Bar(Foo(false));
|
||||
| ++++ +
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
Reference in New Issue
Block a user