Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_middle::mir::{
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
Promoted,
};
use rustc_middle::ty::{self, OpaqueTypeKey, RegionKind, RegionVid, Ty};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, RegionKind, RegionVid};
use rustc_span::symbol::sym;
use std::env;
use std::fmt::Debug;
Expand Down Expand Up @@ -44,7 +44,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>>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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_buffer: &mut Vec<Diagnostic>,
) {
let tcx = infcx.tcx;
Expand Down
32 changes: 15 additions & 17 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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];
Expand All @@ -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
Expand Down Expand Up @@ -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()
}
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,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};
Expand Down Expand Up @@ -213,21 +213,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()
},
Expand Down Expand Up @@ -893,7 +893,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
Expand Down
36 changes: 3 additions & 33 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/opaque_types/table.rs
Original file line number Diff line number Diff line change
@@ -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)]
pub struct OpaqueTypeStorage<'tcx> {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_infer/src/infer/undo_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()>,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/query.rs
Original file line number Diff line number Diff line change
@@ -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::sync::Lrc;
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::ErrorReported;
Expand Down Expand Up @@ -211,7 +211,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]>,
}
Expand Down
32 changes: 32 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,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
Expand Down
14 changes: 6 additions & 8 deletions compiler/rustc_trait_selection/src/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
}

Expand Down Expand Up @@ -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();
Expand All @@ -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);

Expand Down
Loading