Skip to content

Commit 5812b69

Browse files
committed
Auto merge of rust-lang#16484 - Austaras:master, r=Veykril
fix: preserve where clause when builtin derive Closes rust-lang#16432.
2 parents 0e5766b + dad0fdb commit 5812b69

File tree

3 files changed

+50
-5
lines changed

3 files changed

+50
-5
lines changed

crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ where
157157
generic: Vec<T::InGenericArg>,
158158
}
159159
160-
impl <T: $crate::clone::Clone, > $crate::clone::Clone for Foo<T, > where T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, {
160+
impl <T: $crate::clone::Clone, > $crate::clone::Clone for Foo<T, > where <T as Trait>::InWc: Marker, T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, {
161161
fn clone(&self ) -> Self {
162162
match self {
163163
Foo {

crates/hir-expand/src/builtin_derive_macro.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ struct BasicAdtInfo {
194194
/// second field is `Some(ty)` if it's a const param of type `ty`, `None` if it's a type param.
195195
/// third fields is where bounds, if any
196196
param_types: Vec<(tt::Subtree, Option<tt::Subtree>, Option<tt::Subtree>)>,
197+
where_clause: Vec<tt::Subtree>,
197198
associated_types: Vec<tt::Subtree>,
198199
}
199200

@@ -202,10 +203,11 @@ fn parse_adt(
202203
adt: &ast::Adt,
203204
call_site: Span,
204205
) -> Result<BasicAdtInfo, ExpandError> {
205-
let (name, generic_param_list, shape) = match adt {
206+
let (name, generic_param_list, where_clause, shape) = match adt {
206207
ast::Adt::Struct(it) => (
207208
it.name(),
208209
it.generic_param_list(),
210+
it.where_clause(),
209211
AdtShape::Struct(VariantShape::from(tm, it.field_list())?),
210212
),
211213
ast::Adt::Enum(it) => {
@@ -217,6 +219,7 @@ fn parse_adt(
217219
(
218220
it.name(),
219221
it.generic_param_list(),
222+
it.where_clause(),
220223
AdtShape::Enum {
221224
default_variant,
222225
variants: it
@@ -233,7 +236,9 @@ fn parse_adt(
233236
},
234237
)
235238
}
236-
ast::Adt::Union(it) => (it.name(), it.generic_param_list(), AdtShape::Union),
239+
ast::Adt::Union(it) => {
240+
(it.name(), it.generic_param_list(), it.where_clause(), AdtShape::Union)
241+
}
237242
};
238243

239244
let mut param_type_set: FxHashSet<Name> = FxHashSet::default();
@@ -274,6 +279,14 @@ fn parse_adt(
274279
})
275280
.collect();
276281

282+
let where_clause = if let Some(w) = where_clause {
283+
w.predicates()
284+
.map(|it| mbe::syntax_node_to_token_tree(it.syntax(), tm, call_site))
285+
.collect()
286+
} else {
287+
vec![]
288+
};
289+
277290
// For a generic parameter `T`, when shorthand associated type `T::Assoc` appears in field
278291
// types (of any variant for enums), we generate trait bound for it. It sounds reasonable to
279292
// also generate trait bound for qualified associated type `<T as Trait>::Assoc`, but rustc
@@ -301,7 +314,7 @@ fn parse_adt(
301314
.map(|it| mbe::syntax_node_to_token_tree(it.syntax(), tm, call_site))
302315
.collect();
303316
let name_token = name_to_token(tm, name)?;
304-
Ok(BasicAdtInfo { name: name_token, shape, param_types, associated_types })
317+
Ok(BasicAdtInfo { name: name_token, shape, param_types, where_clause, associated_types })
305318
}
306319

307320
fn name_to_token(
@@ -366,7 +379,8 @@ fn expand_simple_derive(
366379
}
367380
};
368381
let trait_body = make_trait_body(&info);
369-
let mut where_block = vec![];
382+
let mut where_block: Vec<_> =
383+
info.where_clause.into_iter().map(|w| quote! {invoc_span => #w , }).collect();
370384
let (params, args): (Vec<_>, Vec<_>) = info
371385
.param_types
372386
.into_iter()

crates/hir-ty/src/tests/macros.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,3 +1373,34 @@ pub fn attr_macro() {}
13731373
"#,
13741374
);
13751375
}
1376+
1377+
#[test]
1378+
fn clone_with_type_bound() {
1379+
check_types(
1380+
r#"
1381+
//- minicore: derive, clone, builtin_impls
1382+
#[derive(Clone)]
1383+
struct Float;
1384+
1385+
trait TensorKind: Clone {
1386+
/// The primitive type of the tensor.
1387+
type Primitive: Clone;
1388+
}
1389+
1390+
impl TensorKind for Float {
1391+
type Primitive = f64;
1392+
}
1393+
1394+
#[derive(Clone)]
1395+
struct Tensor<K = Float> where K: TensorKind
1396+
{
1397+
primitive: K::Primitive,
1398+
}
1399+
1400+
fn foo(t: Tensor) {
1401+
let x = t.clone();
1402+
//^ Tensor<Float>
1403+
}
1404+
"#,
1405+
);
1406+
}

0 commit comments

Comments
 (0)