Skip to content

Commit 9e547b4

Browse files
committed
Differentiate different defining uses of taits when they reference distinct generic parameters
1 parent e386373 commit 9e547b4

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

compiler/rustc_trait_selection/src/opaque_types.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_infer::infer::free_regions::FreeRegionRelations;
1111
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1212
use rustc_infer::infer::{self, InferCtxt, InferOk};
1313
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
14-
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
14+
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst};
1515
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
1616
use rustc_span::Span;
1717

@@ -1007,7 +1007,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
10071007
),
10081008
};
10091009
if in_definition_scope {
1010-
return self.fold_opaque_ty(ty, def_id.to_def_id(), substs, origin);
1010+
let opaque_type_key =
1011+
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
1012+
return self.fold_opaque_ty(ty, opaque_type_key, origin);
10111013
}
10121014

10131015
debug!(
@@ -1029,23 +1031,18 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
10291031
fn fold_opaque_ty(
10301032
&mut self,
10311033
ty: Ty<'tcx>,
1032-
def_id: DefId,
1033-
substs: SubstsRef<'tcx>,
1034+
opaque_type_key: OpaqueTypeKey<'tcx>,
10341035
origin: hir::OpaqueTyOrigin,
10351036
) -> Ty<'tcx> {
10361037
let infcx = self.infcx;
10371038
let tcx = infcx.tcx;
1039+
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
10381040

10391041
debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs);
10401042

10411043
// Use the same type variable if the exact same opaque type appears more
10421044
// than once in the return type (e.g., if it's passed to a type alias).
1043-
if let Some(opaque_defn) = self
1044-
.opaque_types
1045-
.iter()
1046-
.find(|(opaque_type_key, _)| opaque_type_key.def_id == def_id)
1047-
.map(|(_, opaque_defn)| opaque_defn)
1048-
{
1045+
if let Some(opaque_defn) = self.opaque_types.get(&opaque_type_key) {
10491046
debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty);
10501047
return opaque_defn.concrete_ty;
10511048
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// https://github.com/rust-lang/rust/issues/73481
2+
// This test used to cause unsoundness, since one of the two possible
3+
// resolutions was chosen at random instead of erroring due to conflicts.
4+
5+
#![feature(min_type_alias_impl_trait)]
6+
7+
type X<A, B> = impl Into<&'static A>;
8+
//~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied
9+
10+
fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
11+
(a, a)
12+
}
13+
14+
fn main() {
15+
println!("{}", <X<_, _> as Into<&String>>::into(f(&[1isize, 2, 3], String::new()).1));
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied
2+
--> $DIR/multiple-def-uses-in-one-fn.rs:7:16
3+
|
4+
LL | type X<A, B> = impl Into<&'static A>;
5+
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B`
6+
|
7+
= note: required because of the requirements on the impl of `Into<&'static B>` for `&A`
8+
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
9+
|
10+
LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)