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

Split librustc::{traits,infer} to their respective crates #69076

Merged
merged 8 commits into from
Mar 14, 2020
Merged
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
34 changes: 29 additions & 5 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3774,19 +3774,15 @@ dependencies = [
name = "rustc_infer"
version = "0.0.0"
dependencies = [
"fmt_macros",
"graphviz",
"log",
"rustc",
"rustc_ast",
"rustc_attr",
"rustc_data_structures",
"rustc_error_codes",
"rustc_errors",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_session",
"rustc_span",
"rustc_target",
"smallvec 1.0.0",
Expand Down Expand Up @@ -3826,6 +3822,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"rustc_traits",
"rustc_ty",
"rustc_typeck",
Expand Down Expand Up @@ -3860,6 +3857,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"unicode-security",
]

Expand Down Expand Up @@ -3929,6 +3927,7 @@ dependencies = [
"rustc_macros",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"serialize",
"smallvec 1.0.0",
]
Expand All @@ -3952,6 +3951,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"serialize",
"smallvec 1.0.0",
]
Expand Down Expand Up @@ -3992,6 +3992,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
]

[[package]]
Expand Down Expand Up @@ -4039,7 +4040,6 @@ dependencies = [
"rustc_expand",
"rustc_feature",
"rustc_hir",
"rustc_infer",
"rustc_metadata",
"rustc_session",
"rustc_span",
Expand Down Expand Up @@ -4119,6 +4119,27 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b725dadae9fabc488df69a287f5a99c5eaf5d10853842a8a3dfac52476f544ee"

[[package]]
name = "rustc_trait_selection"
version = "0.0.0"
dependencies = [
"fmt_macros",
"log",
"rustc",
"rustc_ast",
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
"rustc_hir",
"rustc_index",
"rustc_infer",
"rustc_macros",
"rustc_session",
"rustc_span",
"rustc_target",
"smallvec 1.0.0",
]

[[package]]
name = "rustc_traits"
version = "0.0.0"
Expand All @@ -4132,6 +4153,7 @@ dependencies = [
"rustc_macros",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"smallvec 1.0.0",
]

Expand All @@ -4146,6 +4168,7 @@ dependencies = [
"rustc_infer",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
]

[[package]]
Expand All @@ -4164,6 +4187,7 @@ dependencies = [
"rustc_infer",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"smallvec 1.0.0",
]

Expand Down
41 changes: 41 additions & 0 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,44 @@ impl<T: Clone> WithDepNode<T> {
self.cached_value.clone()
}
}

#[derive(Clone, Debug)]
pub enum IntercrateAmbiguityCause {
DownstreamCrate { trait_desc: String, self_desc: Option<String> },
UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
ReservationImpl { message: String },
}

impl IntercrateAmbiguityCause {
/// Emits notes when the overlap is caused by complex intercrate ambiguities.
/// See #23980 for details.
pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) {
err.note(&self.intercrate_ambiguity_hint());
}

pub fn intercrate_ambiguity_hint(&self) -> String {
match self {
&IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => {
let self_desc = if let &Some(ref ty) = self_desc {
format!(" for type `{}`", ty)
} else {
String::new()
};
format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc)
}
&IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => {
let self_desc = if let &Some(ref ty) = self_desc {
format!(" for type `{}`", ty)
} else {
String::new()
};
format!(
"upstream crates may add a new impl of trait `{}`{} \
in future versions",
trait_desc, self_desc
)
}
&IntercrateAmbiguityCause::ReservationImpl { ref message } => message.clone(),
}
}
}
4 changes: 0 additions & 4 deletions src/librustc_infer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,14 @@ path = "lib.rs"
doctest = false

[dependencies]
fmt_macros = { path = "../libfmt_macros" }
graphviz = { path = "../libgraphviz" }
log = { version = "0.4", features = ["release_max_level_info", "std"] }
rustc_attr = { path = "../librustc_attr" }
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
rustc_error_codes = { path = "../librustc_error_codes" }
rustc_hir = { path = "../librustc_hir" }
rustc_index = { path = "../librustc_index" }
rustc_macros = { path = "../librustc_macros" }
rustc_session = { path = "../librustc_session" }
rustc_span = { path = "../librustc_span" }
rustc_target = { path = "../librustc_target" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
Expand Down
46 changes: 1 addition & 45 deletions src/librustc_infer/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::infer::canonical::{
};
use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::{InferCtxt, InferCtxtBuilder, InferOk, InferResult, NLLRegionVariableOrigin};
use crate::infer::{InferCtxt, InferOk, InferResult, NLLRegionVariableOrigin};
use crate::traits::query::{Fallible, NoSolution};
use crate::traits::{DomainGoal, TraitEngine};
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
Expand All @@ -26,52 +26,8 @@ use rustc::ty::{self, BoundVar, Ty, TyCtxt};
use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx;
use rustc_index::vec::IndexVec;
use rustc_span::DUMMY_SP;
use std::fmt::Debug;

impl<'tcx> InferCtxtBuilder<'tcx> {
/// The "main method" for a canonicalized trait query. Given the
/// canonical key `canonical_key`, this method will create a new
/// inference context, instantiate the key, and run your operation
/// `op`. The operation should yield up a result (of type `R`) as
/// well as a set of trait obligations that must be fully
/// satisfied. These obligations will be processed and the
/// canonical result created.
///
/// Returns `NoSolution` in the event of any error.
///
/// (It might be mildly nicer to implement this on `TyCtxt`, and
/// not `InferCtxtBuilder`, but that is a bit tricky right now.
/// In part because we would need a `for<'tcx>` sort of
/// bound for the closure and in part because it is convenient to
/// have `'tcx` be free on this function so that we can talk about
/// `K: TypeFoldable<'tcx>`.)
pub fn enter_canonical_trait_query<K, R>(
&mut self,
canonical_key: &Canonical<'tcx, K>,
operation: impl FnOnce(&InferCtxt<'_, 'tcx>, &mut dyn TraitEngine<'tcx>, K) -> Fallible<R>,
) -> Fallible<CanonicalizedQueryResponse<'tcx, R>>
where
K: TypeFoldable<'tcx>,
R: Debug + TypeFoldable<'tcx>,
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable,
{
self.enter_with_canonical(
DUMMY_SP,
canonical_key,
|ref infcx, key, canonical_inference_vars| {
let mut fulfill_cx = TraitEngine::new(infcx.tcx);
let value = operation(infcx, &mut *fulfill_cx, key)?;
infcx.make_canonicalized_query_response(
canonical_inference_vars,
value,
&mut *fulfill_cx,
)
},
)
}
}

impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
/// This method is meant to be invoked as the final step of a canonical query
/// implementation. It is given:
Expand Down
85 changes: 82 additions & 3 deletions src/librustc_infer/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ use super::lexical_region_resolve::RegionResolutionError;
use super::region_constraints::GenericKind;
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};

use crate::infer::opaque_types;
use crate::infer::{self, SuppressRegionErrors};
use crate::traits::error_reporting::report_object_safety_error;
use crate::traits::{
Expand Down Expand Up @@ -288,6 +287,86 @@ fn explain_span(tcx: TyCtxt<'tcx>, heading: &str, span: Span) -> (String, Option
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1), Some(span))
}

pub fn unexpected_hidden_region_diagnostic(
tcx: TyCtxt<'tcx>,
region_scope_tree: Option<&region::ScopeTree>,
span: Span,
hidden_ty: Ty<'tcx>,
hidden_region: ty::Region<'tcx>,
) -> DiagnosticBuilder<'tcx> {
let mut err = struct_span_err!(
tcx.sess,
span,
E0700,
"hidden type for `impl Trait` captures lifetime that does not appear in bounds",
);

// Explain the region we are capturing.
if let ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic | ty::ReEmpty(_) = hidden_region {
// Assuming regionck succeeded (*), we ought to always be
// capturing *some* region from the fn header, and hence it
// ought to be free. So under normal circumstances, we will go
// down this path which gives a decent human readable
// explanation.
//
// (*) if not, the `tainted_by_errors` flag would be set to
// true in any case, so we wouldn't be here at all.
note_and_explain_free_region(
tcx,
&mut err,
&format!("hidden type `{}` captures ", hidden_ty),
hidden_region,
"",
);
} else {
// Ugh. This is a painful case: the hidden region is not one
// that we can easily summarize or explain. This can happen
// in a case like
// `src/test/ui/multiple-lifetimes/ordinary-bounds-unsuited.rs`:
//
// ```
// fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> {
// if condition() { a } else { b }
// }
// ```
//
// Here the captured lifetime is the intersection of `'a` and
// `'b`, which we can't quite express.

if let Some(region_scope_tree) = region_scope_tree {
// If the `region_scope_tree` is available, this is being
// invoked from the "region inferencer error". We can at
// least report a really cryptic error for now.
note_and_explain_region(
tcx,
region_scope_tree,
&mut err,
&format!("hidden type `{}` captures ", hidden_ty),
hidden_region,
"",
);
} else {
// If the `region_scope_tree` is *unavailable*, this is
// being invoked by the code that comes *after* region
// inferencing. This is a bug, as the region inferencer
// ought to have noticed the failed constraint and invoked
// error reporting, which in turn should have prevented us
// from getting trying to infer the hidden type
// completely.
tcx.sess.delay_span_bug(
span,
&format!(
"hidden type captures unexpected lifetime `{:?}` \
but no region inference failure",
hidden_region,
),
);
}
}

err
}

impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn report_region_errors(
&self,
Expand Down Expand Up @@ -410,7 +489,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
span,
} => {
let hidden_ty = self.resolve_vars_if_possible(&hidden_ty);
opaque_types::unexpected_hidden_region_diagnostic(
unexpected_hidden_region_diagnostic(
self.tcx,
Some(region_scope_tree),
span,
Expand Down Expand Up @@ -2077,7 +2156,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
/// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks
/// extra information about each type, but we only care about the category.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
crate enum TyCategory {
pub enum TyCategory {
Closure,
Opaque,
Generator,
Expand Down
Loading