Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
// <https://rustc-dev-guide.rust-lang.org/return-position-impl-trait-in-trait.html>
// 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,
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/const-generics/auxiliary/non_local.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
pub trait NonLocal {
fn method<const N: i32>();
}

use std::future::Future;
pub trait R {
fn read<const L: usize>(&mut self) -> impl Future<Output = [u8; L]>;
}
15 changes: 15 additions & 0 deletions tests/ui/const-generics/non-local-method-same-ok.rs
Original file line number Diff line number Diff line change
@@ -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<const L: usize>(&mut self) -> [u8; L] {
[0; L]
}
}
8 changes: 8 additions & 0 deletions tests/ui/const-generics/non-local-method.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//@ compile-flags: --crate-type lib
//@ aux-build:non_local.rs
//@ edition: 2024

extern crate non_local;

Expand All @@ -13,3 +14,10 @@ impl NonLocal for Local {
print!("hello\n");
}
}

impl non_local::R for Local {
async fn read<const L: usize>(&mut self) -> [u16; L] {
//~^ ERROR: expected `impl Future<Output = [u16; L]>` to be a future that resolves to `[u8; L]`, but it resolves to `[u16; L]`
[0; L]
}
}
22 changes: 19 additions & 3 deletions tests/ui/const-generics/non-local-method.stderr
Original file line number Diff line number Diff line change
@@ -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<const N: u16>() {
| ^^^ expected `i32`, found `u16`

error: aborting due to 1 previous error
error[E0271]: expected `impl Future<Output = [u16; L]>` 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<const L: usize>(&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<const L: usize>(&mut self) -> impl Future<Output = [u8; L]>;
| ^^^^^^^^^^^^^^^^ 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`.
Loading