diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index e8a421afacabd..8a7ad70f8ebb1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2141,7 +2141,16 @@ fn compare_const_generic_param_types<'tcx>( iter::zip(const_params_of(impl_item.def_id), const_params_of(trait_item.def_id)); for (param_impl, param_trait) in param_iter { - let param_impl_ty_span = tcx.ty_span(param_impl.def_id.expect_local()); + // If `impl_item` comes from RPITIT: + // + // then expecting a `LocalDefId` for `param_impl` is fraught: the synthetic + // associated type reuses the trait's generic parameters, which may be nonlocal. + // Use the impl item's span instead. + let param_impl_ty_span = if impl_item.is_impl_trait_in_trait() { + tcx.def_span(impl_item.def_id) + } else { + tcx.ty_span(param_impl.def_id.expect_local()) + }; let cause = ObligationCause::new( param_impl_ty_span, diff --git a/tests/ui/const-generics/auxiliary/non_local.rs b/tests/ui/const-generics/auxiliary/non_local.rs index 38a030d610be6..de0dc2ae85aee 100644 --- a/tests/ui/const-generics/auxiliary/non_local.rs +++ b/tests/ui/const-generics/auxiliary/non_local.rs @@ -1,3 +1,8 @@ pub trait NonLocal { fn method(); } + +use std::future::Future; +pub trait R { + fn read(&mut self) -> impl Future; +} diff --git a/tests/ui/const-generics/non-local-method-same-ok.rs b/tests/ui/const-generics/non-local-method-same-ok.rs new file mode 100644 index 0000000000000..8d67188fa8bca --- /dev/null +++ b/tests/ui/const-generics/non-local-method-same-ok.rs @@ -0,0 +1,15 @@ +// Adapted from; https://github.com/rust-lang/rust/issues/164180#issuecomment-6168887401 +//@ check-pass +//@ compile-flags: --crate-type lib +//@ aux-build:non_local.rs +//@ edition: 2024 + +extern crate non_local; + +struct Local; + +impl non_local::R for Local { + async fn read(&mut self) -> [u8; L] { + [0; L] + } +} diff --git a/tests/ui/const-generics/non-local-method.rs b/tests/ui/const-generics/non-local-method.rs index 290d7fc903eff..b041e0ee7be60 100644 --- a/tests/ui/const-generics/non-local-method.rs +++ b/tests/ui/const-generics/non-local-method.rs @@ -1,5 +1,6 @@ //@ compile-flags: --crate-type lib //@ aux-build:non_local.rs +//@ edition: 2024 extern crate non_local; @@ -13,3 +14,10 @@ impl NonLocal for Local { print!("hello\n"); } } + +impl non_local::R for Local { + async fn read(&mut self) -> [u16; L] { + //~^ ERROR: expected `impl Future` to be a future that resolves to `[u8; L]`, but it resolves to `[u16; L]` + [0; L] + } +} diff --git a/tests/ui/const-generics/non-local-method.stderr b/tests/ui/const-generics/non-local-method.stderr index 0619570689da3..850f248732e2c 100644 --- a/tests/ui/const-generics/non-local-method.stderr +++ b/tests/ui/const-generics/non-local-method.stderr @@ -1,9 +1,25 @@ error[E0053]: associated function `method` has an incompatible type for const generic parameter - --> $DIR/non-local-method.rs:11:24 + --> $DIR/non-local-method.rs:12:24 | LL | fn method() { | ^^^ expected `i32`, found `u16` -error: aborting due to 1 previous error +error[E0271]: expected `impl Future` to be a future that resolves to `[u8; L]`, but it resolves to `[u16; L]` + --> $DIR/non-local-method.rs:19:49 + | +LL | async fn read(&mut self) -> [u16; L] { + | ^^^^^^^^ expected `[u8; L]`, found `[u16; L]` + | + = note: expected array `[u8; L]` + found array `[u16; L]` +note: required by a bound in `R::read::{anon_assoc#0}` + --> $DIR/auxiliary/non_local.rs:7:55 + | +LL | pub trait R { +LL | fn read(&mut self) -> impl Future; + | ^^^^^^^^^^^^^^^^ required by this bound in `R::read::{anon_assoc#0}` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0053`. +Some errors have detailed explanations: E0053, E0271. +For more information about an error, try `rustc --explain E0053`.