Differentiate different defining uses of taits when they reference distinct generic parameters
This commit is contained in:
parent
e386373514
commit
9e547b4464
3 changed files with 38 additions and 10 deletions
|
@ -11,7 +11,7 @@ use rustc_infer::infer::free_regions::FreeRegionRelations;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{self, InferCtxt, InferOk};
|
use rustc_infer::infer::{self, InferCtxt, InferOk};
|
||||||
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
|
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst};
|
||||||
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
|
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -1007,7 +1007,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
if in_definition_scope {
|
if in_definition_scope {
|
||||||
return self.fold_opaque_ty(ty, def_id.to_def_id(), substs, origin);
|
let opaque_type_key =
|
||||||
|
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
|
||||||
|
return self.fold_opaque_ty(ty, opaque_type_key, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -1029,23 +1031,18 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||||
fn fold_opaque_ty(
|
fn fold_opaque_ty(
|
||||||
&mut self,
|
&mut self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
def_id: DefId,
|
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
|
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
|
||||||
|
|
||||||
debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs);
|
debug!("instantiate_opaque_types: Opaque(def_id={:?}, substs={:?})", def_id, substs);
|
||||||
|
|
||||||
// Use the same type variable if the exact same opaque type appears more
|
// Use the same type variable if the exact same opaque type appears more
|
||||||
// than once in the return type (e.g., if it's passed to a type alias).
|
// than once in the return type (e.g., if it's passed to a type alias).
|
||||||
if let Some(opaque_defn) = self
|
if let Some(opaque_defn) = self.opaque_types.get(&opaque_type_key) {
|
||||||
.opaque_types
|
|
||||||
.iter()
|
|
||||||
.find(|(opaque_type_key, _)| opaque_type_key.def_id == def_id)
|
|
||||||
.map(|(_, opaque_defn)| opaque_defn)
|
|
||||||
{
|
|
||||||
debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty);
|
debug!("instantiate_opaque_types: returning concrete ty {:?}", opaque_defn.concrete_ty);
|
||||||
return opaque_defn.concrete_ty;
|
return opaque_defn.concrete_ty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// https://github.com/rust-lang/rust/issues/73481
|
||||||
|
// This test used to cause unsoundness, since one of the two possible
|
||||||
|
// resolutions was chosen at random instead of erroring due to conflicts.
|
||||||
|
|
||||||
|
#![feature(min_type_alias_impl_trait)]
|
||||||
|
|
||||||
|
type X<A, B> = impl Into<&'static A>;
|
||||||
|
//~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied
|
||||||
|
|
||||||
|
fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
|
||||||
|
(a, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{}", <X<_, _> as Into<&String>>::into(f(&[1isize, 2, 3], String::new()).1));
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied
|
||||||
|
--> $DIR/multiple-def-uses-in-one-fn.rs:7:16
|
||||||
|
|
|
||||||
|
LL | type X<A, B> = impl Into<&'static A>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B`
|
||||||
|
|
|
||||||
|
= note: required because of the requirements on the impl of `Into<&'static B>` for `&A`
|
||||||
|
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue