Rollup merge of #119638 - lukas-code:suggest-constructor-cycle-error, r=cjgillot
fix cyle error when suggesting to use associated function instead of constructor Fixes https://github.com/rust-lang/rust/issues/119625. The first commit fixes the infinite recursion and makes the cycle error actually show up. We do this by making the `Display` for `ty::Instance` impl respect `with_no_queries` so that it can be used in query descriptions. The second commit fixes the cycle error `resolver_for_lowering` -> `normalize` -> `resolve_instance` (for evaluating const) -> `lang_items` (for `drop_in_place`) -> `resolver_for_lowering` (for collecting lang items). We do this by simply skipping the suggestion when encountering an unnormalized type.
This commit is contained in:
commit
61c776ae0a
@ -293,12 +293,16 @@ impl<'tcx> InstanceDef<'tcx> {
|
|||||||
fn fmt_instance(
|
fn fmt_instance(
|
||||||
f: &mut fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
instance: &Instance<'_>,
|
instance: &Instance<'_>,
|
||||||
type_length: rustc_session::Limit,
|
type_length: Option<rustc_session::Limit>,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
ty::tls::with(|tcx| {
|
ty::tls::with(|tcx| {
|
||||||
let args = tcx.lift(instance.args).expect("could not lift for printing");
|
let args = tcx.lift(instance.args).expect("could not lift for printing");
|
||||||
|
|
||||||
let mut cx = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length);
|
let mut cx = if let Some(type_length) = type_length {
|
||||||
|
FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
|
||||||
|
} else {
|
||||||
|
FmtPrinter::new(tcx, Namespace::ValueNS)
|
||||||
|
};
|
||||||
cx.print_def_path(instance.def_id(), args)?;
|
cx.print_def_path(instance.def_id(), args)?;
|
||||||
let s = cx.into_buffer();
|
let s = cx.into_buffer();
|
||||||
f.write_str(&s)
|
f.write_str(&s)
|
||||||
@ -324,13 +328,13 @@ pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize);
|
|||||||
|
|
||||||
impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
|
impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt_instance(f, self.0, rustc_session::Limit(self.1))
|
fmt_instance(f, self.0, Some(rustc_session::Limit(self.1)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Display for Instance<'tcx> {
|
impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
ty::tls::with(|tcx| fmt_instance(f, self, tcx.type_length_limit()))
|
fmt_instance(f, self, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1755,11 +1755,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
|||||||
.filter_map(|item| {
|
.filter_map(|item| {
|
||||||
// Only assoc fns that return `Self`
|
// Only assoc fns that return `Self`
|
||||||
let fn_sig = self.r.tcx.fn_sig(item.def_id).skip_binder();
|
let fn_sig = self.r.tcx.fn_sig(item.def_id).skip_binder();
|
||||||
let ret_ty = fn_sig.output();
|
// Don't normalize the return type, because that can cause cycle errors.
|
||||||
let ret_ty = self
|
let ret_ty = fn_sig.output().skip_binder();
|
||||||
.r
|
|
||||||
.tcx
|
|
||||||
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), ret_ty);
|
|
||||||
let ty::Adt(def, _args) = ret_ty.kind() else {
|
let ty::Adt(def, _args) = ret_ty.kind() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
mod m {
|
||||||
|
pub struct Uuid(());
|
||||||
|
|
||||||
|
impl Uuid {
|
||||||
|
pub fn encode_buffer() -> [u8; LENGTH] {
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const LENGTH: usize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use m::Uuid;
|
10
tests/ui/resolve/suggest-constructor-cycle-error.rs
Normal file
10
tests/ui/resolve/suggest-constructor-cycle-error.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// aux-build:suggest-constructor-cycle-error.rs
|
||||||
|
|
||||||
|
// Regression test for https://github.com/rust-lang/rust/issues/119625
|
||||||
|
|
||||||
|
extern crate suggest_constructor_cycle_error as a;
|
||||||
|
|
||||||
|
const CONST_NAME: a::Uuid = a::Uuid(());
|
||||||
|
//~^ ERROR: cannot initialize a tuple struct which contains private fields [E0423]
|
||||||
|
|
||||||
|
fn main() {}
|
15
tests/ui/resolve/suggest-constructor-cycle-error.stderr
Normal file
15
tests/ui/resolve/suggest-constructor-cycle-error.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0423]: cannot initialize a tuple struct which contains private fields
|
||||||
|
--> $DIR/suggest-constructor-cycle-error.rs:7:29
|
||||||
|
|
|
||||||
|
LL | const CONST_NAME: a::Uuid = a::Uuid(());
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
note: constructor is not visible here due to private fields
|
||||||
|
--> $DIR/auxiliary/suggest-constructor-cycle-error.rs:2:21
|
||||||
|
|
|
||||||
|
LL | pub struct Uuid(());
|
||||||
|
| ^^ private field
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0423`.
|
Loading…
x
Reference in New Issue
Block a user