Skip to content

Commit 6f120f9

Browse files
committed
Use more detailed spans in dyn compat errors within bodies
1 parent 7068c8b commit 6f120f9

File tree

60 files changed

+218
-773
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+218
-773
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
3131
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics};
3232
use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind};
3333
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
34-
use rustc_infer::traits::ObligationCause;
34+
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
3535
use rustc_middle::hir::nested_filter;
3636
use rustc_middle::query::Providers;
3737
use rustc_middle::ty::util::{Discr, IntTypeExt};
@@ -40,7 +40,7 @@ use rustc_middle::{bug, span_bug};
4040
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
4141
use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
4242
use rustc_trait_selection::infer::InferCtxtExt;
43-
use rustc_trait_selection::traits::ObligationCtxt;
43+
use rustc_trait_selection::traits::{ObligationCtxt, hir_ty_lowering_dyn_compatibility_violations};
4444
use tracing::{debug, instrument};
4545

4646
use crate::errors;
@@ -626,6 +626,10 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
626626

627627
(input_tys, output_ty)
628628
}
629+
630+
fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation> {
631+
hir_ty_lowering_dyn_compatibility_violations(self.tcx, trait_def_id)
632+
}
629633
}
630634

631635
/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{
1111
};
1212
use rustc_span::{ErrorGuaranteed, Span};
1313
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
14-
use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
14+
use rustc_trait_selection::traits;
1515
use smallvec::{SmallVec, smallvec};
1616
use tracing::{debug, instrument};
1717

@@ -99,8 +99,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
9999
// to avoid ICEs.
100100
for (clause, span) in user_written_bounds {
101101
if let Some(trait_pred) = clause.as_trait_clause() {
102-
let violations =
103-
hir_ty_lowering_dyn_compatibility_violations(tcx, trait_pred.def_id());
102+
let violations = self.dyn_compatibility_violations(trait_pred.def_id());
104103
if !violations.is_empty() {
105104
let reported = report_dyn_incompatibility(
106105
tcx,

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
3333
use rustc_hir::def_id::{DefId, LocalDefId};
3434
use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
3535
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
36-
use rustc_infer::traits::ObligationCause;
36+
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
3737
use rustc_middle::middle::stability::AllowUnstable;
3838
use rustc_middle::mir::interpret::LitToConstInput;
3939
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
@@ -203,6 +203,10 @@ pub trait HirTyLowerer<'tcx> {
203203
{
204204
self
205205
}
206+
207+
/// Performs minimalistic dyn compat checks outside of bodies, but full within bodies.
208+
/// Outside of bodies we could end up in cycles, so we delay most checks to later phases.
209+
fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation>;
206210
}
207211

208212
/// The "qualified self" of an associated item path.

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
1414
use rustc_hir::{self as hir, HirId, ItemLocalMap};
1515
use rustc_hir_analysis::hir_ty_lowering::{HirTyLowerer, RegionInferReason};
1616
use rustc_infer::infer;
17-
use rustc_infer::traits::Obligation;
17+
use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
1818
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
1919
use rustc_session::Session;
2020
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym};
@@ -389,6 +389,10 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
389389
};
390390
(input_tys, output_ty)
391391
}
392+
393+
fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation> {
394+
self.tcx.dyn_compatibility_violations(trait_def_id).to_vec()
395+
}
392396
}
393397

394398
/// The `ty` representation of a user-provided type. Depending on the use-site

tests/ui/async-await/dyn/mut-is-pointer-like.stderr

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | #![feature(async_fn_in_dyn_trait)]
88
= note: `#[warn(incomplete_features)]` on by default
99

1010
error[E0038]: the trait `AsyncTrait` is not dyn compatible
11-
--> $DIR/mut-is-pointer-like.rs:35:16
11+
--> $DIR/mut-is-pointer-like.rs:35:29
1212
|
1313
LL | let x: Pin<&mut dyn AsyncTrait<Output = ()>> = f;
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
14+
| ^^^^^^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
1515
|
1616
note: for a trait to be dyn compatible it needs to allow building a vtable
1717
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -24,48 +24,6 @@ LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
2424
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
2525
= help: consider moving `async_dispatch` to another trait
2626

27-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
28-
--> $DIR/mut-is-pointer-like.rs:35:56
29-
|
30-
LL | let x: Pin<&mut dyn AsyncTrait<Output = ()>> = f;
31-
| ^ `AsyncTrait` is not dyn compatible
32-
|
33-
note: for a trait to be dyn compatible it needs to allow building a vtable
34-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
35-
--> $DIR/mut-is-pointer-like.rs:16:14
36-
|
37-
LL | trait AsyncTrait {
38-
| ---------- this trait is not dyn compatible...
39-
...
40-
LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
41-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
42-
= help: consider moving `async_dispatch` to another trait
43-
= note: required for the cast from `Pin<&mut {async block@$DIR/mut-is-pointer-like.rs:32:32: 32:37}>` to `Pin<&mut dyn AsyncTrait<Output = ()>>`
44-
45-
error[E0277]: the trait bound `dyn AsyncTrait<Output = ()>: AsyncTrait` is not satisfied
46-
--> $DIR/mut-is-pointer-like.rs:36:11
47-
|
48-
LL | x.async_dispatch().await;
49-
| ^^^^^^^^^^^^^^ the trait `AsyncTrait` is not implemented for `dyn AsyncTrait<Output = ()>`
50-
51-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
52-
--> $DIR/mut-is-pointer-like.rs:36:9
53-
|
54-
LL | x.async_dispatch().await;
55-
| ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
56-
|
57-
note: for a trait to be dyn compatible it needs to allow building a vtable
58-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
59-
--> $DIR/mut-is-pointer-like.rs:16:14
60-
|
61-
LL | trait AsyncTrait {
62-
| ---------- this trait is not dyn compatible...
63-
...
64-
LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
65-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
66-
= help: consider moving `async_dispatch` to another trait
67-
68-
error: aborting due to 4 previous errors; 1 warning emitted
27+
error: aborting due to 1 previous error; 1 warning emitted
6928

70-
Some errors have detailed explanations: E0038, E0277.
71-
For more information about an error, try `rustc --explain E0038`.
29+
For more information about this error, try `rustc --explain E0038`.

tests/ui/async-await/dyn/works.stderr

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | #![feature(async_fn_in_dyn_trait)]
88
= note: `#[warn(incomplete_features)]` on by default
99

1010
error[E0038]: the trait `AsyncTrait` is not dyn compatible
11-
--> $DIR/works.rs:27:34
11+
--> $DIR/works.rs:27:21
1212
|
1313
LL | let x: &dyn AsyncTrait = &"hello, world!";
14-
| ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
14+
| ^^^^^^^^^^ `AsyncTrait` is not dyn compatible
1515
|
1616
note: for a trait to be dyn compatible it needs to allow building a vtable
1717
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -23,59 +23,7 @@ LL | async fn async_dispatch(&self);
2323
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
2424
= help: consider moving `async_dispatch` to another trait
2525
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
26-
= note: required for the cast from `&&'static str` to `&dyn AsyncTrait`
2726

28-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
29-
--> $DIR/works.rs:27:16
30-
|
31-
LL | let x: &dyn AsyncTrait = &"hello, world!";
32-
| ^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
33-
|
34-
note: for a trait to be dyn compatible it needs to allow building a vtable
35-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
36-
--> $DIR/works.rs:14:14
37-
|
38-
LL | trait AsyncTrait {
39-
| ---------- this trait is not dyn compatible...
40-
LL | async fn async_dispatch(&self);
41-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
42-
= help: consider moving `async_dispatch` to another trait
43-
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
44-
45-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
46-
--> $DIR/works.rs:28:11
47-
|
48-
LL | x.async_dispatch().await;
49-
| ^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
50-
|
51-
note: for a trait to be dyn compatible it needs to allow building a vtable
52-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
53-
--> $DIR/works.rs:14:14
54-
|
55-
LL | trait AsyncTrait {
56-
| ---------- this trait is not dyn compatible...
57-
LL | async fn async_dispatch(&self);
58-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
59-
= help: consider moving `async_dispatch` to another trait
60-
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
61-
62-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
63-
--> $DIR/works.rs:28:9
64-
|
65-
LL | x.async_dispatch().await;
66-
| ^^^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
67-
|
68-
note: for a trait to be dyn compatible it needs to allow building a vtable
69-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
70-
--> $DIR/works.rs:14:14
71-
|
72-
LL | trait AsyncTrait {
73-
| ---------- this trait is not dyn compatible...
74-
LL | async fn async_dispatch(&self);
75-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
76-
= help: consider moving `async_dispatch` to another trait
77-
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
78-
79-
error: aborting due to 4 previous errors; 1 warning emitted
27+
error: aborting due to 1 previous error; 1 warning emitted
8028

8129
For more information about this error, try `rustc --explain E0038`.

tests/ui/async-await/dyn/wrong-size.stderr

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | #![feature(async_fn_in_dyn_trait)]
88
= note: `#[warn(incomplete_features)]` on by default
99

1010
error[E0038]: the trait `AsyncTrait` is not dyn compatible
11-
--> $DIR/wrong-size.rs:21:30
11+
--> $DIR/wrong-size.rs:21:17
1212
|
1313
LL | let x: &dyn AsyncTrait = &"hello, world!";
14-
| ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
14+
| ^^^^^^^^^^ `AsyncTrait` is not dyn compatible
1515
|
1616
note: for a trait to be dyn compatible it needs to allow building a vtable
1717
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -23,25 +23,7 @@ LL | async fn async_dispatch(&self);
2323
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
2424
= help: consider moving `async_dispatch` to another trait
2525
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
26-
= note: required for the cast from `&&'static str` to `&dyn AsyncTrait`
2726

28-
error[E0038]: the trait `AsyncTrait` is not dyn compatible
29-
--> $DIR/wrong-size.rs:21:12
30-
|
31-
LL | let x: &dyn AsyncTrait = &"hello, world!";
32-
| ^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
33-
|
34-
note: for a trait to be dyn compatible it needs to allow building a vtable
35-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
36-
--> $DIR/wrong-size.rs:9:14
37-
|
38-
LL | trait AsyncTrait {
39-
| ---------- this trait is not dyn compatible...
40-
LL | async fn async_dispatch(&self);
41-
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
42-
= help: consider moving `async_dispatch` to another trait
43-
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
44-
45-
error: aborting due to 2 previous errors; 1 warning emitted
27+
error: aborting due to 1 previous error; 1 warning emitted
4628

4729
For more information about this error, try `rustc --explain E0038`.

tests/ui/async-await/in-trait/dyn-compatibility.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0038]: the trait `Foo` is not dyn compatible
2-
--> $DIR/dyn-compatibility.rs:9:12
2+
--> $DIR/dyn-compatibility.rs:9:17
33
|
44
LL | let x: &dyn Foo = todo!();
5-
| ^^^^^^^^ `Foo` is not dyn compatible
5+
| ^^^ `Foo` is not dyn compatible
66
|
77
note: for a trait to be dyn compatible it needs to allow building a vtable
88
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>

tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ fn main() {
44
let _: &Copy + 'static; //~ ERROR expected a path
55
//~^ ERROR is not dyn compatible
66
let _: &'static Copy + 'static; //~ ERROR expected a path
7+
//~^ ERROR is not dyn compatible
78
}

tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,26 @@ LL | let _: &'static (Copy + 'static);
2121
| + +
2222

2323
error[E0038]: the trait `Copy` is not dyn compatible
24-
--> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
24+
--> $DIR/trait-object-reference-without-parens-suggestion.rs:4:13
2525
|
2626
LL | let _: &Copy + 'static;
27-
| ^^^^^ `Copy` is not dyn compatible
27+
| ^^^^ `Copy` is not dyn compatible
28+
|
29+
= note: the trait is not dyn compatible because it requires `Self: Sized`
30+
= note: for a trait to be dyn compatible it needs to allow building a vtable
31+
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
32+
33+
error[E0038]: the trait `Copy` is not dyn compatible
34+
--> $DIR/trait-object-reference-without-parens-suggestion.rs:6:21
35+
|
36+
LL | let _: &'static Copy + 'static;
37+
| ^^^^ `Copy` is not dyn compatible
2838
|
2939
= note: the trait is not dyn compatible because it requires `Self: Sized`
3040
= note: for a trait to be dyn compatible it needs to allow building a vtable
3141
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
3242

33-
error: aborting due to 3 previous errors
43+
error: aborting due to 4 previous errors
3444

3545
Some errors have detailed explanations: E0038, E0178.
3646
For more information about an error, try `rustc --explain E0038`.

tests/ui/dyn-compatibility/almost-supertrait-associated-type.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::marker::PhantomData;
66
fn transmute<T, U>(t: T) -> U {
77
(&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
88
//~^ ERROR the trait `Foo` is not dyn compatible
9-
//~| ERROR the trait `Foo` is not dyn compatible
109
}
1110

1211
struct ActuallySuper;
Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
error[E0038]: the trait `Foo` is not dyn compatible
2-
--> $DIR/almost-supertrait-associated-type.rs:21:20
2+
--> $DIR/almost-supertrait-associated-type.rs:20:20
33
|
44
LL | impl<T, U> Dyn for dyn Foo<T, U> + '_ {
55
| ^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
66
|
77
note: for a trait to be dyn compatible it needs to allow building a vtable
88
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
9-
--> $DIR/almost-supertrait-associated-type.rs:33:34
9+
--> $DIR/almost-supertrait-associated-type.rs:32:34
1010
|
1111
LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
1212
| --- this trait is not dyn compatible...
@@ -16,14 +16,14 @@ LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc;
1616
= help: consider moving `transmute` to another trait
1717

1818
error[E0038]: the trait `Foo` is not dyn compatible
19-
--> $DIR/almost-supertrait-associated-type.rs:7:27
19+
--> $DIR/almost-supertrait-associated-type.rs:7:32
2020
|
2121
LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
22-
| ^^^^^^^^^^^^^^ `Foo` is not dyn compatible
22+
| ^^^^^^^^^ `Foo` is not dyn compatible
2323
|
2424
note: for a trait to be dyn compatible it needs to allow building a vtable
2525
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
26-
--> $DIR/almost-supertrait-associated-type.rs:33:34
26+
--> $DIR/almost-supertrait-associated-type.rs:32:34
2727
|
2828
LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
2929
| --- this trait is not dyn compatible...
@@ -32,24 +32,6 @@ LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc;
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `transmute` references the `Self` type in its return type
3333
= help: consider moving `transmute` to another trait
3434

35-
error[E0038]: the trait `Foo` is not dyn compatible
36-
--> $DIR/almost-supertrait-associated-type.rs:7:6
37-
|
38-
LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
39-
| ^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
40-
|
41-
note: for a trait to be dyn compatible it needs to allow building a vtable
42-
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
43-
--> $DIR/almost-supertrait-associated-type.rs:33:34
44-
|
45-
LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
46-
| --- this trait is not dyn compatible...
47-
...
48-
LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc;
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `transmute` references the `Self` type in its return type
50-
= help: consider moving `transmute` to another trait
51-
= note: required for the cast from `&PhantomData<T>` to `&dyn Foo<T, U>`
52-
53-
error: aborting due to 3 previous errors
35+
error: aborting due to 2 previous errors
5436

5537
For more information about this error, try `rustc --explain E0038`.

tests/ui/dyn-compatibility/generics.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
2222
//~^ ERROR E0038
2323
t as &dyn Bar
2424
//~^ ERROR E0038
25-
//~| ERROR E0038
2625
}
2726

2827
fn make_quux<T:Quux>(t: &T) -> &dyn Quux {

0 commit comments

Comments
 (0)