Skip to content

Commit 3d46260

Browse files
committed
Auto merge of #147366 - Zalathar:rollup-f6ipp2q, r=Zalathar
Rollup of 3 pull requests Successful merges: - #146874 (compiler: Hint at multiple crate versions if trait impl is for wrong ADT ) - #147262 (Make #[link="dl"] an FCW rather than an error) - #147364 (update autodiff testcases) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e2c96cc + bae926d commit 3d46260

File tree

14 files changed

+256
-35
lines changed

14 files changed

+256
-35
lines changed

compiler/rustc_attr_parsing/src/attributes/link_attrs.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,22 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
6565
cx: &'c mut AcceptContext<'_, '_, S>,
6666
args: &'c ArgParser<'_>,
6767
) -> impl IntoIterator<Item = Self::Item> + 'c {
68-
let mut result = None;
69-
let Some(items) = args.list() else {
70-
cx.expected_list(cx.attr_span);
71-
return result;
68+
let items = match args {
69+
ArgParser::List(list) => list,
70+
// This is an edgecase added because making this a hard error would break too many crates
71+
// Specifically `#[link = "dl"]` is accepted with a FCW
72+
// For more information, see https://github.com/rust-lang/rust/pull/143193
73+
ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => {
74+
let suggestions = <Self as CombineAttributeParser<S>>::TEMPLATE
75+
.suggestions(cx.attr_style, "link");
76+
let span = cx.attr_span;
77+
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
78+
return None;
79+
}
80+
_ => {
81+
cx.expected_list(cx.attr_span);
82+
return None;
83+
}
7284
};
7385

7486
let sess = cx.sess();
@@ -113,7 +125,7 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
113125
}
114126
};
115127
if !cont {
116-
return result;
128+
return None;
117129
}
118130
}
119131

@@ -202,7 +214,7 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
202214
}
203215
let Some((name, name_span)) = name else {
204216
cx.emit_err(LinkRequiresName { span: cx.attr_span });
205-
return result;
217+
return None;
206218
};
207219

208220
// Do this outside of the loop so that `import_name_type` can be specified before `kind`.
@@ -218,15 +230,14 @@ impl<S: Stage> CombineAttributeParser<S> for LinkParser {
218230
cx.emit_err(RawDylibNoNul { span: name_span });
219231
}
220232

221-
result = Some(LinkEntry {
233+
Some(LinkEntry {
222234
span: cx.attr_span,
223235
kind: kind.unwrap_or(NativeLibKind::Unspecified),
224236
name,
225237
cfg,
226238
verbatim,
227239
import_name_type,
228-
});
229-
result
240+
})
230241
}
231242
}
232243

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ symbols! {
874874
div,
875875
div_assign,
876876
diverging_block_default,
877+
dl,
877878
do_not_recommend,
878879
doc,
879880
doc_alias,

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
467467
span,
468468
leaf_trait_predicate,
469469
);
470-
self.note_version_mismatch(&mut err, leaf_trait_predicate);
470+
self.note_trait_version_mismatch(&mut err, leaf_trait_predicate);
471+
self.note_adt_version_mismatch(&mut err, leaf_trait_predicate);
471472
self.suggest_remove_await(&obligation, &mut err);
472473
self.suggest_derive(&obligation, &mut err, leaf_trait_predicate);
473474

@@ -2424,7 +2425,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
24242425
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
24252426
/// with the same path as `trait_ref`, a help message about
24262427
/// a probable version mismatch is added to `err`
2427-
fn note_version_mismatch(
2428+
fn note_trait_version_mismatch(
24282429
&self,
24292430
err: &mut Diag<'_>,
24302431
trait_pred: ty::PolyTraitPredicate<'tcx>,
@@ -2464,15 +2465,87 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
24642465
impl_spans,
24652466
format!("trait impl{} with same name found", pluralize!(trait_impls.len())),
24662467
);
2467-
let trait_crate = self.tcx.crate_name(trait_with_same_path.krate);
2468-
let crate_msg =
2469-
format!("perhaps two different versions of crate `{trait_crate}` are being used?");
2470-
err.note(crate_msg);
2468+
self.note_two_crate_versions(trait_with_same_path, err);
24712469
suggested = true;
24722470
}
24732471
suggested
24742472
}
24752473

2474+
fn note_two_crate_versions(&self, did: DefId, err: &mut Diag<'_>) {
2475+
let crate_name = self.tcx.crate_name(did.krate);
2476+
let crate_msg =
2477+
format!("perhaps two different versions of crate `{crate_name}` are being used?");
2478+
err.note(crate_msg);
2479+
}
2480+
2481+
fn note_adt_version_mismatch(
2482+
&self,
2483+
err: &mut Diag<'_>,
2484+
trait_pred: ty::PolyTraitPredicate<'tcx>,
2485+
) {
2486+
let ty::Adt(impl_self_def, _) = trait_pred.self_ty().skip_binder().peel_refs().kind()
2487+
else {
2488+
return;
2489+
};
2490+
2491+
let impl_self_did = impl_self_def.did();
2492+
2493+
// We only want to warn about different versions of a dependency.
2494+
// If no dependency is involved, bail.
2495+
if impl_self_did.krate == LOCAL_CRATE {
2496+
return;
2497+
}
2498+
2499+
let impl_self_path = self.comparable_path(impl_self_did);
2500+
let impl_self_crate_name = self.tcx.crate_name(impl_self_did.krate);
2501+
let similar_items: UnordSet<_> = self
2502+
.tcx
2503+
.visible_parent_map(())
2504+
.items()
2505+
.filter_map(|(&item, _)| {
2506+
// If we found ourselves, ignore.
2507+
if impl_self_did == item {
2508+
return None;
2509+
}
2510+
// We only want to warn about different versions of a dependency.
2511+
// Ignore items from our own crate.
2512+
if item.krate == LOCAL_CRATE {
2513+
return None;
2514+
}
2515+
// We want to warn about different versions of a dependency.
2516+
// So make sure the crate names are the same.
2517+
if impl_self_crate_name != self.tcx.crate_name(item.krate) {
2518+
return None;
2519+
}
2520+
// Filter out e.g. constructors that often have the same path
2521+
// str as the relevant ADT.
2522+
if !self.tcx.def_kind(item).is_adt() {
2523+
return None;
2524+
}
2525+
let path = self.comparable_path(item);
2526+
// We don't know if our item or the one we found is the re-exported one.
2527+
// Check both cases.
2528+
let is_similar = path.ends_with(&impl_self_path) || impl_self_path.ends_with(&path);
2529+
is_similar.then_some((item, path))
2530+
})
2531+
.collect();
2532+
2533+
let mut similar_items =
2534+
similar_items.into_items().into_sorted_stable_ord_by_key(|(_, path)| path);
2535+
similar_items.dedup();
2536+
2537+
for (similar_item, _) in similar_items {
2538+
err.span_help(self.tcx.def_span(similar_item), "item with same name found");
2539+
self.note_two_crate_versions(similar_item, err);
2540+
}
2541+
}
2542+
2543+
/// Add a `::` prefix when comparing paths so that paths with just one item
2544+
/// like "Foo" does not equal the end of "OtherFoo".
2545+
fn comparable_path(&self, did: DefId) -> String {
2546+
format!("::{}", self.tcx.def_path_str(did))
2547+
}
2548+
24762549
/// Creates a `PredicateObligation` with `new_self_ty` replacing the existing type in the
24772550
/// `trait_ref`.
24782551
///

tests/codegen-llvm/autodiff/autodiffv2.rs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,14 @@
1818
// but each shadow argument is `width` times larger (thus 16 and 20 elements here).
1919
// `d_square3` instead takes `width` (4) shadow arguments, which are all the same size as the
2020
// original function arguments.
21-
//
22-
// FIXME(autodiff): We currently can't test `d_square1` and `d_square3` in the same file, since they
23-
// generate the same dummy functions which get merged by LLVM, breaking pieces of our pipeline which
24-
// try to rewrite the dummy functions later. We should consider to change to pure declarations both
25-
// in our frontend and in the llvm backend to avoid these issues.
2621

2722
#![feature(autodiff)]
2823

2924
use std::autodiff::autodiff_forward;
3025

3126
// CHECK: ;
3227
#[no_mangle]
33-
//#[autodiff(d_square1, Forward, Dual, Dual)]
28+
#[autodiff_forward(d_square1, Dual, Dual)]
3429
#[autodiff_forward(d_square2, 4, Dualv, Dualv)]
3530
#[autodiff_forward(d_square3, 4, Dual, Dual)]
3631
fn square(x: &[f32], y: &mut [f32]) {
@@ -79,25 +74,25 @@ fn main() {
7974
let mut dy3_4 = std::hint::black_box(vec![0.0; 5]);
8075

8176
// scalar.
82-
//d_square1(&x1, &z1, &mut y1, &mut dy1_1);
83-
//d_square1(&x1, &z2, &mut y2, &mut dy1_2);
84-
//d_square1(&x1, &z3, &mut y3, &mut dy1_3);
85-
//d_square1(&x1, &z4, &mut y4, &mut dy1_4);
77+
d_square1(&x1, &z1, &mut y1, &mut dy1_1);
78+
d_square1(&x1, &z2, &mut y2, &mut dy1_2);
79+
d_square1(&x1, &z3, &mut y3, &mut dy1_3);
80+
d_square1(&x1, &z4, &mut y4, &mut dy1_4);
8681

8782
// assert y1 == y2 == y3 == y4
88-
//for i in 0..5 {
89-
// assert_eq!(y1[i], y2[i]);
90-
// assert_eq!(y1[i], y3[i]);
91-
// assert_eq!(y1[i], y4[i]);
92-
//}
83+
for i in 0..5 {
84+
assert_eq!(y1[i], y2[i]);
85+
assert_eq!(y1[i], y3[i]);
86+
assert_eq!(y1[i], y4[i]);
87+
}
9388

9489
// batch mode A)
9590
d_square2(&x1, &z5, &mut y5, &mut dy2);
9691

9792
// assert y1 == y2 == y3 == y4 == y5
98-
//for i in 0..5 {
99-
// assert_eq!(y1[i], y5[i]);
100-
//}
93+
for i in 0..5 {
94+
assert_eq!(y1[i], y5[i]);
95+
}
10196

10297
// batch mode B)
10398
d_square3(&x1, &z1, &z2, &z3, &z4, &mut y6, &mut dy3_1, &mut dy3_2, &mut dy3_3, &mut dy3_4);

tests/codegen-llvm/autodiff/identical_fnc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ fn square2(x: &f64) -> f64 {
3232
// CHECK-NOT:br
3333
// CHECK-NOT:ret
3434
// CHECK:; call identical_fnc::d_square
35-
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1)
35+
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1)
3636
// CHECK:; call identical_fnc::d_square
37-
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2)
37+
// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2)
3838

3939
fn main() {
4040
let x = std::hint::black_box(3.0);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub struct Foo;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub struct Foo;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct Bar;
2+
3+
impl From<Bar> for foo::Foo {
4+
fn from(_: Bar) -> Self {
5+
foo::Foo
6+
}
7+
}
8+
9+
fn main() {
10+
// The user might wrongly expect this to work since From<Bar> for Foo
11+
// implies Into<Foo> for Bar. What the user missed is that different
12+
// versions of Foo exist in the dependency graph, and the impl is for the
13+
// wrong version.
14+
re_export_foo::into_foo(Bar);
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0277]: the trait bound `re_export_foo::foo::Foo: From<Bar>` is not satisfied
2+
--> main.rs:14:29
3+
|
4+
LL | re_export_foo::into_foo(Bar);
5+
| ----------------------- ^^^ the trait `From<Bar>` is not implemented for `re_export_foo::foo::Foo`
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
help: item with same name found
10+
--> $DIR/foo-v1.rs:1:1
11+
|
12+
LL | pub struct Foo;
13+
| ^^^^^^^^^^^^^^
14+
= note: perhaps two different versions of crate `foo` are being used?
15+
= note: required for `Bar` to implement `Into<re_export_foo::foo::Foo>`
16+
note: required by a bound in `into_foo`
17+
--> $DIR/re-export-foo.rs:3:25
18+
|
19+
LL | pub fn into_foo(_: impl Into<foo::Foo>) {}
20+
| ^^^^^^^^^^^^^^ required by this bound in `into_foo`
21+
22+
error: aborting due to 1 previous error
23+
24+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub use foo;
2+
3+
pub fn into_foo(_: impl Into<foo::Foo>) {}

0 commit comments

Comments
 (0)