Have the spans of TAIT type conflict errors point to the actual site instead of the owning function

This commit is contained in:
Oli Scherer 2022-02-09 16:44:17 +00:00
parent 4b249b062b
commit d5b6510bfb
37 changed files with 180 additions and 187 deletions

View File

@ -8,7 +8,7 @@ use rustc_middle::mir::{
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
Promoted,
};
use rustc_middle::ty::{self, OpaqueTypeKey, Region, RegionVid, Ty};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid};
use rustc_span::symbol::sym;
use std::env;
use std::fmt::Debug;
@ -43,7 +43,7 @@ pub type PoloniusOutput = Output<RustcFacts>;
/// closure requirements to propagate, and any generated errors.
crate struct NllOutput<'tcx> {
pub regioncx: RegionInferenceContext<'tcx>,
pub opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>>,
pub opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
pub polonius_input: Option<Box<AllFacts>>,
pub polonius_output: Option<Rc<PoloniusOutput>>,
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
@ -305,7 +305,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
infcx.set_tainted_by_errors();
}
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values, body.span);
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);
NllOutput {
regioncx,
@ -372,7 +372,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
opaque_type_values: &VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>>,
opaque_type_values: &VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
errors: &mut crate::error::BorrowckErrors<'tcx>,
) {
let tcx = infcx.tcx;

View File

@ -3,7 +3,7 @@ use rustc_data_structures::vec_map::VecMap;
use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::InferCtxt;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, TyCtxt, TypeFoldable};
use rustc_span::Span;
use rustc_trait_selection::opaque_types::InferCtxtExt;
@ -53,15 +53,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn infer_opaque_types(
&self,
infcx: &InferCtxt<'_, 'tcx>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (Ty<'tcx>, Span, OpaqueTyOrigin)>,
span: Span,
) -> VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>> {
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> {
opaque_ty_decls
.into_iter()
.map(|(opaque_type_key, (concrete_type, decl_span, origin))| {
.map(|(opaque_type_key, (concrete_type, origin))| {
let substs = opaque_type_key.substs;
// FIXME: why are the spans in decl_span often DUMMY_SP?
let span = decl_span.substitute_dummy(span);
debug!(?concrete_type, ?substs);
let mut subst_regions = vec![self.universal_regions.fr_static];
@ -85,7 +82,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
span,
concrete_type.span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
@ -113,17 +110,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key,
universal_concrete_type,
span,
);
(
let ty = if check_opaque_type_parameter_valid(
infcx.tcx,
opaque_type_key,
if check_opaque_type_parameter_valid(infcx.tcx, opaque_type_key, origin, span) {
remapped_type
} else {
infcx.tcx.ty_error()
},
)
origin,
concrete_type.span,
) {
remapped_type
} else {
infcx.tcx.ty_error()
};
(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span })
})
.collect()
}

View File

@ -31,8 +31,8 @@ use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts};
use rustc_middle::ty::{
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid,
ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueHiddenType,
OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
};
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::{Span, DUMMY_SP};
@ -225,21 +225,21 @@ pub(crate) fn type_check<'mir, 'tcx>(
),
)
.unwrap();
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type.ty);
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
trace!(
"finalized opaque type {:?} to {:#?}",
opaque_type_key,
hidden_type.kind()
hidden_type.ty.kind()
);
if hidden_type.has_infer_types_or_consts() {
infcx.tcx.sess.delay_span_bug(
decl.hidden_type.span,
&format!("could not resolve {:#?}", hidden_type.kind()),
&format!("could not resolve {:#?}", hidden_type.ty.kind()),
);
hidden_type = infcx.tcx.ty_error();
hidden_type.ty = infcx.tcx.ty_error();
}
(opaque_type_key, (hidden_type, decl.hidden_type.span, decl.origin))
(opaque_type_key, (hidden_type, decl.origin))
})
.collect()
},
@ -905,7 +905,7 @@ struct BorrowCheckContext<'a, 'tcx> {
crate struct MirTypeckResults<'tcx> {
crate constraints: MirTypeckRegionConstraints<'tcx>,
crate universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, (Ty<'tcx>, Span, OpaqueTyOrigin)>,
crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
}
/// A collection of region constraints that must be satisfied for the

View File

@ -8,7 +8,9 @@ use rustc_hir as hir;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor};
use rustc_middle::ty::{
self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor,
};
use rustc_span::Span;
use std::ops::ControlFlow;
@ -35,38 +37,6 @@ pub struct OpaqueTypeDecl<'tcx> {
pub origin: hir::OpaqueTyOrigin,
}
#[derive(Copy, Clone, Debug, TypeFoldable)]
pub struct OpaqueHiddenType<'tcx> {
/// The span of this particular definition of the opaque type. So
/// for example:
///
/// ```ignore (incomplete snippet)
/// type Foo = impl Baz;
/// fn bar() -> Foo {
/// // ^^^ This is the span we are looking for!
/// }
/// ```
///
/// In cases where the fn returns `(impl Trait, impl Trait)` or
/// other such combinations, the result is currently
/// over-approximated, but better than nothing.
pub span: Span,
/// The type variable that represents the value of the opaque type
/// that we require. In other words, after we compile this function,
/// we will be created a constraint like:
///
/// Foo<'a, T> = ?C
///
/// where `?C` is the value of this type variable. =) It may
/// naturally refer to the type and lifetime parameters in scope
/// in this function, though ultimately it should only reference
/// those that are arguments to `Foo` in the constraint above. (In
/// other words, `?C` should not include `'b`, even though it's a
/// lifetime parameter on `foo`.)
pub ty: Ty<'tcx>,
}
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn handle_opaque_type(
&self,

View File

@ -1,11 +1,11 @@
use rustc_data_structures::undo_log::UndoLogs;
use rustc_hir::OpaqueTyOrigin;
use rustc_middle::ty::{self, OpaqueTypeKey, Ty};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
use rustc_span::DUMMY_SP;
use crate::infer::{InferCtxtUndoLogs, UndoLog};
use super::{OpaqueHiddenType, OpaqueTypeDecl, OpaqueTypeMap};
use super::{OpaqueTypeDecl, OpaqueTypeMap};
#[derive(Default, Debug, Clone)]
pub struct OpaqueTypeStorage<'tcx> {

View File

@ -4,15 +4,13 @@ use rustc_data_structures::snapshot_vec as sv;
use rustc_data_structures::undo_log::{Rollback, UndoLogs};
use rustc_data_structures::unify as ut;
use rustc_middle::infer::unify_key::RegionVidKey;
use rustc_middle::ty::{self, OpaqueTypeKey};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey};
use crate::{
infer::{region_constraints, type_variable, InferCtxtInner},
traits,
};
use super::opaque_types::OpaqueHiddenType;
pub struct Snapshot<'tcx> {
pub(crate) undo_len: usize,
_marker: PhantomData<&'tcx ()>,

View File

@ -1,7 +1,7 @@
//! Values computed by queries that use MIR.
use crate::mir::{Body, Promoted};
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
use rustc_data_structures::stable_map::FxHashMap;
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::ErrorGuaranteed;
@ -242,7 +242,7 @@ pub struct BorrowCheckResult<'tcx> {
/// All the opaque types that are restricted to concrete types
/// by this function. Unlike the value in `TypeckResults`, this has
/// unerased regions.
pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>>,
pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
pub used_mut_upvars: SmallVec<[Field; 8]>,
pub tainted_by_errors: Option<ErrorGuaranteed>,

View File

@ -1081,6 +1081,38 @@ pub struct OpaqueTypeKey<'tcx> {
pub substs: SubstsRef<'tcx>,
}
#[derive(Copy, Clone, Debug, TypeFoldable, HashStable, TyEncodable, TyDecodable)]
pub struct OpaqueHiddenType<'tcx> {
/// The span of this particular definition of the opaque type. So
/// for example:
///
/// ```ignore (incomplete snippet)
/// type Foo = impl Baz;
/// fn bar() -> Foo {
/// // ^^^ This is the span we are looking for!
/// }
/// ```
///
/// In cases where the fn returns `(impl Trait, impl Trait)` or
/// other such combinations, the result is currently
/// over-approximated, but better than nothing.
pub span: Span,
/// The type variable that represents the value of the opaque type
/// that we require. In other words, after we compile this function,
/// we will be created a constraint like:
///
/// Foo<'a, T> = ?C
///
/// where `?C` is the value of this type variable. =) It may
/// naturally refer to the type and lifetime parameters in scope
/// in this function, though ultimately it should only reference
/// those that are arguments to `Foo` in the constraint above. (In
/// other words, `?C` should not include `'b`, even though it's a
/// lifetime parameter on `foo`.)
pub ty: Ty<'tcx>,
}
rustc_index::newtype_index! {
/// "Universes" are used during type- and trait-checking in the
/// presence of `for<..>` binders to control what sets of names are

View File

@ -5,15 +5,14 @@ use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
use rustc_infer::infer::InferCtxt;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt};
use rustc_span::Span;
pub trait InferCtxtExt<'tcx> {
fn infer_opaque_definition_from_instantiation(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
instantiated_ty: Ty<'tcx>,
span: Span,
instantiated_ty: OpaqueHiddenType<'tcx>,
) -> Ty<'tcx>;
}
@ -45,8 +44,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
fn infer_opaque_definition_from_instantiation(
&self,
opaque_type_key: OpaqueTypeKey<'tcx>,
instantiated_ty: Ty<'tcx>,
span: Span,
instantiated_ty: OpaqueHiddenType<'tcx>,
) -> Ty<'tcx> {
if self.is_tainted_by_errors() {
return self.tcx.ty_error();
@ -69,12 +67,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// Convert the type from the function into a type valid outside
// the function, by replacing invalid regions with 'static,
// after producing an error for each of them.
let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new(
let definition_ty = instantiated_ty.ty.fold_with(&mut ReverseMapper::new(
self.tcx,
def_id,
map,
instantiated_ty,
span,
instantiated_ty.ty,
instantiated_ty.span,
));
debug!(?definition_ty);

View File

@ -358,6 +358,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
.concrete_opaque_types
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
.copied()
.map(|concrete| concrete.ty)
.unwrap_or_else(|| {
let table = tcx.typeck(owner);
if let Some(_) = table.tainted_by_errors {
@ -556,7 +557,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
/// with the first type that we find, and then later types are
/// checked against it (we also carry the span of that first
/// type).
found: Option<(Span, Ty<'tcx>)>,
found: Option<ty::OpaqueHiddenType<'tcx>>,
}
impl ConstraintLocator<'_> {
@ -580,7 +581,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
// ```
let tables = self.tcx.typeck(def_id);
if let Some(_) = tables.tainted_by_errors {
self.found = Some((DUMMY_SP, self.tcx.ty_error()));
self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error() });
return;
}
if tables.concrete_opaque_types.get(&self.def_id).is_none() {
@ -590,7 +591,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
// Use borrowck to get the type with unerased regions.
let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types;
debug!(?concrete_opaque_types);
for (opaque_type_key, concrete_type) in concrete_opaque_types {
for &(opaque_type_key, concrete_type) in concrete_opaque_types {
if opaque_type_key.def_id != self.def_id {
// Ignore constraints for other opaque types.
continue;
@ -598,26 +599,22 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
debug!(?concrete_type, ?opaque_type_key.substs, "found constraint");
// FIXME(oli-obk): trace the actual span from inference to improve errors.
let span = self.tcx.def_span(def_id);
if let Some((prev_span, prev_ty)) = self.found {
if *concrete_type != prev_ty && !(*concrete_type, prev_ty).references_error() {
debug!(?span);
if let Some(prev) = self.found {
if concrete_type.ty != prev.ty && !(concrete_type, prev).references_error() {
// Found different concrete types for the opaque type.
let mut err = self.tcx.sess.struct_span_err(
span,
concrete_type.span,
"concrete type differs from previous defining opaque type use",
);
err.span_label(
span,
format!("expected `{}`, got `{}`", prev_ty, concrete_type),
concrete_type.span,
format!("expected `{}`, got `{}`", prev.ty, concrete_type.ty),
);
err.span_note(prev_span, "previous use here");
err.span_note(prev.span, "previous use here");
err.emit();
}
} else {
self.found = Some((span, *concrete_type));
self.found = Some(concrete_type);
}
}
}
@ -692,7 +689,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
}
match locator.found {
Some((_, ty)) => ty,
Some(hidden) => hidden.ty,
None => {
let span = tcx.def_span(def_id);
let name = tcx.item_name(tcx.parent(def_id.to_def_id()).unwrap());

View File

@ -3,8 +3,8 @@
type X<'a, 'b> = impl std::fmt::Debug;
fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
//~^ ERROR concrete type differs from previous defining opaque type use
(a, a)
//~^ ERROR concrete type differs from previous defining opaque type use
}
fn main() {}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/issue-86465.rs:5:1
--> $DIR/issue-86465.rs:6:5
|
LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a u32`, got `&'b u32`
LL | (a, a)
| ^^^^^^ expected `&'a u32`, got `&'b u32`
|
note: previous use here
--> $DIR/issue-86465.rs:5:1
--> $DIR/issue-86465.rs:6:5
|
LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (a, a)
| ^^^^^^
error: aborting due to previous error

View File

@ -10,6 +10,6 @@ fn foo() -> Foo {
}
fn bar() -> Foo {
//~^ ERROR concrete type differs from previous
42i32
//~^ ERROR concrete type differs from previous
}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/different_defining_uses.rs:12:1
--> $DIR/different_defining_uses.rs:13:5
|
LL | fn bar() -> Foo {
| ^^^^^^^^^^^^^^^ expected `&'static str`, got `i32`
LL | 42i32
| ^^^^^ expected `&'static str`, got `i32`
|
note: previous use here
--> $DIR/different_defining_uses.rs:8:1
--> $DIR/different_defining_uses.rs:9:5
|
LL | fn foo() -> Foo {
| ^^^^^^^^^^^^^^^
LL | ""
| ^^
error: aborting due to previous error

View File

@ -8,8 +8,8 @@ fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
}
fn bar<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
//~^ ERROR: concrete type differs from previous defining opaque type use
b
//~^ ERROR: concrete type differs from previous defining opaque type use
}
fn main() {}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/different_lifetimes_defining_uses.rs:10:1
--> $DIR/different_lifetimes_defining_uses.rs:11:5
|
LL | fn bar<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a u32`, got `&'b u32`
LL | b
| ^ expected `&'a u32`, got `&'b u32`
|
note: previous use here
--> $DIR/different_lifetimes_defining_uses.rs:6:1
--> $DIR/different_lifetimes_defining_uses.rs:7:5
|
LL | fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | a
| ^
error: aborting due to previous error

View File

@ -9,6 +9,6 @@ fn my_iter<T>(t: T) -> MyIter<T> {
}
fn my_iter2<T>(t: T) -> MyIter<T> {
//~^ ERROR concrete type differs from previous
Some(t).into_iter()
//~^ ERROR concrete type differs from previous
}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_different_defining_uses.rs:11:1
--> $DIR/generic_different_defining_uses.rs:12:5
|
LL | fn my_iter2<T>(t: T) -> MyIter<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once<T>`, got `std::option::IntoIter<T>`
LL | Some(t).into_iter()
| ^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once<T>`, got `std::option::IntoIter<T>`
|
note: previous use here
--> $DIR/generic_different_defining_uses.rs:7:1
--> $DIR/generic_different_defining_uses.rs:8:5
|
LL | fn my_iter<T>(t: T) -> MyIter<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | std::iter::once(t)
| ^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -13,6 +13,6 @@ fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
}
fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
//~^ ERROR concrete type differs from previous defining opaque type use
u
//~^ ERROR concrete type differs from previous defining opaque type use
}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use3.rs:15:1
--> $DIR/generic_duplicate_param_use3.rs:16:5
|
LL | fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `T`, got `U`
LL | u
| ^ expected `T`, got `U`
|
note: previous use here
--> $DIR/generic_duplicate_param_use3.rs:11:1
--> $DIR/generic_duplicate_param_use3.rs:12:5
|
LL | fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | t
| ^
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use3.rs:8:18

View File

@ -14,6 +14,6 @@ fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
}
fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
//~^ concrete type differs from previous
(u, t)
//~^ concrete type differs from previous
}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use5.rs:16:1
--> $DIR/generic_duplicate_param_use5.rs:17:5
|
LL | fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, U)`, got `(U, T)`
LL | (u, t)
| ^^^^^^ expected `(T, U)`, got `(U, T)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use5.rs:12:1
--> $DIR/generic_duplicate_param_use5.rs:13:5
|
LL | fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (t, u)
| ^^^^^^
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:8:18

View File

@ -13,6 +13,6 @@ fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
}
fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
//~^ ERROR concrete type differs from previous
(u, t)
//~^ ERROR concrete type differs from previous
}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use6.rs:15:1
--> $DIR/generic_duplicate_param_use6.rs:16:5
|
LL | fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, T)`, got `(U, T)`
LL | (u, t)
| ^^^^^^ expected `(T, T)`, got `(U, T)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use6.rs:11:1
--> $DIR/generic_duplicate_param_use6.rs:12:5
|
LL | fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (t, t)
| ^^^^^^
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use6.rs:8:18

View File

@ -12,6 +12,6 @@ fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
}
fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
//~^ concrete type differs from previous
(u, 4u32)
//~^ concrete type differs from previous
}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use8.rs:14:1
--> $DIR/generic_duplicate_param_use8.rs:15:5
|
LL | fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, u32)`, got `(U, u32)`
LL | (u, 4u32)
| ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use8.rs:10:1
--> $DIR/generic_duplicate_param_use8.rs:11:5
|
LL | fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (t, 4u32)
| ^^^^^^^^^
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use8.rs:7:18

View File

@ -19,5 +19,5 @@ fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
}
fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, u, 42) //~^ ERROR concrete type differs from previous
(t, u, 42) //~ ERROR concrete type differs from previous
}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/generic_duplicate_param_use9.rs:21:1
--> $DIR/generic_duplicate_param_use9.rs:22:5
|
LL | fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(A, B, <A as Foo>::Bar)`, got `(A, B, i32)`
LL | (t, u, 42)
| ^^^^^^^^^^ expected `(A, B, <A as Foo>::Bar)`, got `(A, B, i32)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use9.rs:17:1
--> $DIR/generic_duplicate_param_use9.rs:18:5
|
LL | fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^
error[E0277]: the trait bound `A: Foo` is not satisfied
--> $DIR/generic_duplicate_param_use9.rs:7:18

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/issue-52843-closure-constrain.rs:10:16
--> $DIR/issue-52843-closure-constrain.rs:10:31
|
LL | let null = || -> Opaque { 0 };
| ^^^^^^^^^^^^^^^^^^ expected `String`, got `i32`
| ^ expected `String`, got `i32`
|
note: previous use here
--> $DIR/issue-52843-closure-constrain.rs:9:5
--> $DIR/issue-52843-closure-constrain.rs:9:30
|
LL | fn _unused() -> Opaque { String::new() }
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -7,7 +7,7 @@
type Y<A, B> = impl std::fmt::Debug;
fn g<A, B>() -> (Y<A, B>, Y<B, A>) {
(42_i64, 60) //~^ ERROR concrete type differs from previous defining opaque type use
(42_i64, 60) //~ ERROR concrete type differs from previous defining opaque type use
}
fn main() {}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/multiple-def-uses-in-one-fn-infer.rs:9:1
--> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:5
|
LL | fn g<A, B>() -> (Y<A, B>, Y<B, A>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i64`, got `i32`
LL | (42_i64, 60)
| ^^^^^^^^^^^^ expected `i64`, got `i32`
|
note: previous use here
--> $DIR/multiple-def-uses-in-one-fn-infer.rs:9:1
--> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:5
|
LL | fn g<A, B>() -> (Y<A, B>, Y<B, A>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (42_i64, 60)
| ^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -3,7 +3,7 @@
type Foo<'a, 'b> = impl std::fmt::Debug;
fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
(i, i) //~^ ERROR concrete type differs from previous
(i, i) //~ ERROR concrete type differs from previous
}
fn main() {}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:5:1
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
LL | fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a i32`, got `&'b i32`
LL | (i, i)
| ^^^^^^ expected `&'a i32`, got `&'b i32`
|
note: previous use here
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:5:1
--> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
|
LL | fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (i, i)
| ^^^^^^
error: aborting due to previous error

View File

@ -7,8 +7,8 @@
type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
//~^ ERROR concrete type differs from previous defining opaque type
(a.clone(), a)
//~^ ERROR concrete type differs from previous defining opaque type
}
fn main() {

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
--> $DIR/multiple-def-uses-in-one-fn2.rs:10:5
|
LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `B`
LL | (a.clone(), a)
| ^^^^^^^^^^^^^^ expected `A`, got `B`
|
note: previous use here
--> $DIR/multiple-def-uses-in-one-fn2.rs:9:1
--> $DIR/multiple-def-uses-in-one-fn2.rs:10:5
|
LL | fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (a.clone(), a)
| ^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -22,8 +22,8 @@ impl Bar for u32 {
}
fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
//~^ ERROR concrete type differs from previous
(t, <U as Bar>::FOO)
//~^ ERROR concrete type differs from previous
}
fn is_sync<T: Sync>() {}

View File

@ -1,14 +1,14 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/not_a_defining_use.rs:24:1
--> $DIR/not_a_defining_use.rs:25:5
|
LL | fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
|
note: previous use here
--> $DIR/not_a_defining_use.rs:10:1
--> $DIR/not_a_defining_use.rs:11:5
|
LL | fn three<T: Debug, U>(t: T) -> Two<T, U> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | (t, 5i8)
| ^^^^^^^^
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/not_a_defining_use.rs:7:18