Skip to content

Commit 520b0b2

Browse files
committed
Auto merge of rust-lang#120619 - compiler-errors:param, r=lcnr
Assert that params with the same *index* have the same *name* Found this bug when trying to build libcore with the new solver, since it will canonicalize two params with the same index into *different* placeholders if those params differ by name.
2 parents 1a648b3 + 24d806c commit 520b0b2

File tree

10 files changed

+90
-41
lines changed

10 files changed

+90
-41
lines changed

compiler/rustc_hir_analysis/src/check/intrinsic.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_errors::{codes::*, struct_span_code_err, DiagnosticMessage};
1212
use rustc_hir as hir;
1313
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
1414
use rustc_middle::ty::{self, Ty, TyCtxt};
15-
use rustc_span::symbol::{kw, sym, Symbol};
15+
use rustc_span::symbol::{kw, sym};
1616
use rustc_target::spec::abi::Abi;
1717

1818
fn equate_intrinsic_type<'tcx>(
@@ -133,7 +133,17 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
133133
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
134134
/// and in `library/core/src/intrinsics.rs`.
135135
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
136-
let param = |n| Ty::new_param(tcx, n, Symbol::intern(&format!("P{n}")));
136+
let generics = tcx.generics_of(it.owner_id);
137+
let param = |n| {
138+
if let Some(&ty::GenericParamDef {
139+
name, kind: ty::GenericParamDefKind::Type { .. }, ..
140+
}) = generics.opt_param_at(n as usize, tcx)
141+
{
142+
Ty::new_param(tcx, n, name)
143+
} else {
144+
Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
145+
}
146+
};
137147
let intrinsic_id = it.owner_id.to_def_id();
138148
let intrinsic_name = tcx.item_name(intrinsic_id);
139149
let name_str = intrinsic_name.as_str();
@@ -478,9 +488,16 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
478488

479489
/// Type-check `extern "platform-intrinsic" { ... }` functions.
480490
pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
491+
let generics = tcx.generics_of(it.owner_id);
481492
let param = |n| {
482-
let name = Symbol::intern(&format!("P{n}"));
483-
Ty::new_param(tcx, n, name)
493+
if let Some(&ty::GenericParamDef {
494+
name, kind: ty::GenericParamDefKind::Type { .. }, ..
495+
}) = generics.opt_param_at(n as usize, tcx)
496+
{
497+
Ty::new_param(tcx, n, name)
498+
} else {
499+
Ty::new_error_with_message(tcx, tcx.def_span(it.owner_id), "expected param")
500+
}
484501
};
485502

486503
let name = it.ident.name;

compiler/rustc_middle/src/ty/relate.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,10 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
435435
Ok(a)
436436
}
437437

438-
(ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => Ok(a),
438+
(ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => {
439+
debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
440+
Ok(a)
441+
}
439442

440443
(ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
441444

@@ -593,7 +596,10 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
593596
(ty::ConstKind::Error(_), _) => return Ok(a),
594597
(_, ty::ConstKind::Error(_)) => return Ok(b),
595598

596-
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) => a_p.index == b_p.index,
599+
(ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
600+
debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
601+
true
602+
}
597603
(ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
598604
(ty::ConstKind::Value(a_val), ty::ConstKind::Value(b_val)) => a_val == b_val,
599605

compiler/rustc_mir_transform/src/shim.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -447,16 +447,13 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'t
447447
fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
448448
debug!("build_clone_shim(def_id={:?})", def_id);
449449

450-
let param_env = tcx.param_env_reveal_all_normalized(def_id);
451-
452450
let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
453-
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
454451

455452
let dest = Place::return_place();
456453
let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
457454

458455
match self_ty.kind() {
459-
_ if is_copy => builder.copy_shim(),
456+
ty::FnDef(..) | ty::FnPtr(_) => builder.copy_shim(),
460457
ty::Closure(_, args) => builder.tuple_like_shim(dest, src, args.as_closure().upvar_tys()),
461458
ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),
462459
ty::Coroutine(coroutine_def_id, args) => {

compiler/rustc_ty_utils/src/instance.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,8 @@ fn resolve_associated_item<'tcx>(
209209
let name = tcx.item_name(trait_item_id);
210210
if name == sym::clone {
211211
let self_ty = trait_ref.self_ty();
212-
213-
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env);
214212
match self_ty.kind() {
215-
_ if is_copy => (),
213+
ty::FnDef(..) | ty::FnPtr(_) => (),
216214
ty::Coroutine(..)
217215
| ty::CoroutineWitness(..)
218216
| ty::Closure(..)

src/librustdoc/clean/inline.rs

+38-18
Original file line numberDiff line numberDiff line change
@@ -65,37 +65,49 @@ pub(crate) fn try_inline(
6565
let kind = match res {
6666
Res::Def(DefKind::Trait, did) => {
6767
record_extern_fqn(cx, did, ItemType::Trait);
68-
build_impls(cx, did, attrs_without_docs, &mut ret);
69-
clean::TraitItem(Box::new(build_external_trait(cx, did)))
68+
cx.with_param_env(did, |cx| {
69+
build_impls(cx, did, attrs_without_docs, &mut ret);
70+
clean::TraitItem(Box::new(build_external_trait(cx, did)))
71+
})
7072
}
7173
Res::Def(DefKind::Fn, did) => {
7274
record_extern_fqn(cx, did, ItemType::Function);
73-
clean::FunctionItem(build_external_function(cx, did))
75+
cx.with_param_env(did, |cx| clean::FunctionItem(build_external_function(cx, did)))
7476
}
7577
Res::Def(DefKind::Struct, did) => {
7678
record_extern_fqn(cx, did, ItemType::Struct);
77-
build_impls(cx, did, attrs_without_docs, &mut ret);
78-
clean::StructItem(build_struct(cx, did))
79+
cx.with_param_env(did, |cx| {
80+
build_impls(cx, did, attrs_without_docs, &mut ret);
81+
clean::StructItem(build_struct(cx, did))
82+
})
7983
}
8084
Res::Def(DefKind::Union, did) => {
8185
record_extern_fqn(cx, did, ItemType::Union);
82-
build_impls(cx, did, attrs_without_docs, &mut ret);
83-
clean::UnionItem(build_union(cx, did))
86+
cx.with_param_env(did, |cx| {
87+
build_impls(cx, did, attrs_without_docs, &mut ret);
88+
clean::UnionItem(build_union(cx, did))
89+
})
8490
}
8591
Res::Def(DefKind::TyAlias, did) => {
8692
record_extern_fqn(cx, did, ItemType::TypeAlias);
87-
build_impls(cx, did, attrs_without_docs, &mut ret);
88-
clean::TypeAliasItem(build_type_alias(cx, did, &mut ret))
93+
cx.with_param_env(did, |cx| {
94+
build_impls(cx, did, attrs_without_docs, &mut ret);
95+
clean::TypeAliasItem(build_type_alias(cx, did, &mut ret))
96+
})
8997
}
9098
Res::Def(DefKind::Enum, did) => {
9199
record_extern_fqn(cx, did, ItemType::Enum);
92-
build_impls(cx, did, attrs_without_docs, &mut ret);
93-
clean::EnumItem(build_enum(cx, did))
100+
cx.with_param_env(did, |cx| {
101+
build_impls(cx, did, attrs_without_docs, &mut ret);
102+
clean::EnumItem(build_enum(cx, did))
103+
})
94104
}
95105
Res::Def(DefKind::ForeignTy, did) => {
96106
record_extern_fqn(cx, did, ItemType::ForeignType);
97-
build_impls(cx, did, attrs_without_docs, &mut ret);
98-
clean::ForeignTypeItem
107+
cx.with_param_env(did, |cx| {
108+
build_impls(cx, did, attrs_without_docs, &mut ret);
109+
clean::ForeignTypeItem
110+
})
99111
}
100112
// Never inline enum variants but leave them shown as re-exports.
101113
Res::Def(DefKind::Variant, _) => return None,
@@ -108,11 +120,13 @@ pub(crate) fn try_inline(
108120
}
109121
Res::Def(DefKind::Static(_), did) => {
110122
record_extern_fqn(cx, did, ItemType::Static);
111-
clean::StaticItem(build_static(cx, did, cx.tcx.is_mutable_static(did)))
123+
cx.with_param_env(did, |cx| {
124+
clean::StaticItem(build_static(cx, did, cx.tcx.is_mutable_static(did)))
125+
})
112126
}
113127
Res::Def(DefKind::Const, did) => {
114128
record_extern_fqn(cx, did, ItemType::Constant);
115-
clean::ConstantItem(build_const(cx, did))
129+
cx.with_param_env(did, |cx| clean::ConstantItem(build_const(cx, did)))
116130
}
117131
Res::Def(DefKind::Macro(kind), did) => {
118132
let mac = build_macro(cx, did, name, import_def_id, kind);
@@ -334,7 +348,9 @@ pub(crate) fn build_impls(
334348

335349
// for each implementation of an item represented by `did`, build the clean::Item for that impl
336350
for &did in tcx.inherent_impls(did).into_iter().flatten() {
337-
build_impl(cx, did, attrs, ret);
351+
cx.with_param_env(did, |cx| {
352+
build_impl(cx, did, attrs, ret);
353+
});
338354
}
339355

340356
// This pretty much exists expressly for `dyn Error` traits that exist in the `alloc` crate.
@@ -347,7 +363,9 @@ pub(crate) fn build_impls(
347363
let type_ =
348364
if tcx.is_trait(did) { SimplifiedType::Trait(did) } else { SimplifiedType::Adt(did) };
349365
for &did in tcx.incoherent_impls(type_).into_iter().flatten() {
350-
build_impl(cx, did, attrs, ret);
366+
cx.with_param_env(did, |cx| {
367+
build_impl(cx, did, attrs, ret);
368+
});
351369
}
352370
}
353371
}
@@ -549,7 +567,9 @@ pub(crate) fn build_impl(
549567
}
550568

551569
if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
552-
record_extern_trait(cx, did);
570+
cx.with_param_env(did, |cx| {
571+
record_extern_trait(cx, did);
572+
});
553573
}
554574

555575
let (merged_attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs);

src/librustdoc/clean/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,9 @@ fn clean_ty_alias_inner_type<'tcx>(
947947
};
948948

949949
if !adt_def.did().is_local() {
950-
inline::build_impls(cx, adt_def.did(), None, ret);
950+
cx.with_param_env(adt_def.did(), |cx| {
951+
inline::build_impls(cx, adt_def.did(), None, ret);
952+
});
951953
}
952954

953955
Some(if adt_def.is_enum() {

src/librustdoc/clean/utils.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,16 @@ pub(crate) fn build_deref_target_impls(
295295
if let Some(prim) = target.primitive_type() {
296296
let _prof_timer = tcx.sess.prof.generic_activity("build_primitive_inherent_impls");
297297
for did in prim.impls(tcx).filter(|did| !did.is_local()) {
298-
inline::build_impl(cx, did, None, ret);
298+
cx.with_param_env(did, |cx| {
299+
inline::build_impl(cx, did, None, ret);
300+
});
299301
}
300302
} else if let Type::Path { path } = target {
301303
let did = path.def_id();
302304
if !did.is_local() {
303-
inline::build_impls(cx, did, None, ret);
305+
cx.with_param_env(did, |cx| {
306+
inline::build_impls(cx, did, None, ret);
307+
});
304308
}
305309
}
306310
}

src/librustdoc/passes/collect_trait_impls.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
4949
let _prof_timer = tcx.sess.prof.generic_activity("build_extern_trait_impls");
5050
for &cnum in tcx.crates(()) {
5151
for &impl_def_id in tcx.trait_impls_in_crate(cnum) {
52-
inline::build_impl(cx, impl_def_id, None, &mut new_items_external);
52+
cx.with_param_env(impl_def_id, |cx| {
53+
inline::build_impl(cx, impl_def_id, None, &mut new_items_external);
54+
});
5355
}
5456
}
5557
}
@@ -74,7 +76,9 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
7476
);
7577
parent = tcx.opt_parent(did);
7678
}
77-
inline::build_impl(cx, impl_def_id, Some((&attr_buf, None)), &mut new_items_local);
79+
cx.with_param_env(impl_def_id, |cx| {
80+
inline::build_impl(cx, impl_def_id, Some((&attr_buf, None)), &mut new_items_local);
81+
});
7882
attr_buf.clear();
7983
}
8084
}
@@ -83,7 +87,9 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
8387
for def_id in PrimitiveType::all_impls(tcx) {
8488
// Try to inline primitive impls from other crates.
8589
if !def_id.is_local() {
86-
inline::build_impl(cx, def_id, None, &mut new_items_external);
90+
cx.with_param_env(def_id, |cx| {
91+
inline::build_impl(cx, def_id, None, &mut new_items_external);
92+
});
8793
}
8894
}
8995
for (prim, did) in PrimitiveType::primitive_locations(tcx) {

src/tools/clippy/clippy_lints/src/default.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
131131
// only when assigning `... = Default::default()`
132132
&& is_expr_default(expr, cx)
133133
&& let binding_type = cx.typeck_results().node_type(binding_id)
134-
&& let Some(adt) = binding_type.ty_adt_def()
134+
&& let ty::Adt(adt, args) = *binding_type.kind()
135135
&& adt.is_struct()
136136
&& let variant = adt.non_enum_variant()
137137
&& (adt.did().is_local() || !variant.is_field_list_non_exhaustive())
@@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
144144
.fields
145145
.iter()
146146
.all(|field| {
147-
is_copy(cx, cx.tcx.type_of(field.did).instantiate_identity())
147+
is_copy(cx, cx.tcx.type_of(field.did).instantiate(cx.tcx, args))
148148
})
149149
&& (!has_drop(cx, binding_type) || all_fields_are_copy)
150150
{

src/tools/clippy/clippy_lints/src/useless_conversion.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ fn into_iter_bound<'tcx>(
8686
param_index: u32,
8787
node_args: GenericArgsRef<'tcx>,
8888
) -> Option<Span> {
89-
let param_env = cx.tcx.param_env(fn_did);
9089
let mut into_iter_span = None;
9190

9291
for (pred, span) in cx.tcx.explicit_predicates_of(fn_did).predicates {
@@ -111,7 +110,7 @@ fn into_iter_bound<'tcx>(
111110
}));
112111

113112
let predicate = EarlyBinder::bind(tr).instantiate(cx.tcx, args);
114-
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), param_env, predicate);
113+
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
115114
if !cx
116115
.tcx
117116
.infer_ctxt()

0 commit comments

Comments
 (0)