Skip to content

Commit

Permalink
Auto merge of #69076 - cjgillot:split_trait, r=matthewjasper
Browse files Browse the repository at this point in the history
Split librustc::{traits,infer} to their respective crates

Followup on #67953.

I tried to follow the existing module structures.

cc @eddyb
r? @Zoxc
  • Loading branch information
bors committed Mar 13, 2020
2 parents 54b7d21 + 13fed54 commit 474cd8d
Show file tree
Hide file tree
Showing 114 changed files with 5,588 additions and 4,695 deletions.
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

0 comments on commit 474cd8d

Please sign in to comment.