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

Rollup of 6 pull requests #67463

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c1241bf
add debuginfo in generator_interior
csmoe Oct 16, 2019
ff4f6a1
record previous unresolve span for generator error reporting
csmoe Oct 21, 2019
4c7f5af
Separate region inference logic from error handling better
mark-i-m Dec 16, 2019
12d65c2
Split up ptr/mod.rs in libcore, one with implementation detail for co…
TheSamsa Dec 8, 2019
ffbde9f
is_binding_pat: don't use _ arm
Centril Dec 19, 2019
4414f0d
is_binding_pat: treat or-pat like tuple-pat
Centril Dec 19, 2019
43fc934
Tweak errors for missing associated types and type parameters
estebank Dec 12, 2019
a89f03d
Fix case in `associated-type-projection-from-multiple-supertraits.rs`
estebank Dec 12, 2019
e9ef8c6
review comments: move error reporting to their own methods
estebank Dec 13, 2019
fef3c8f
Handle more specific case E0222
estebank Dec 13, 2019
a4ec575
Use structured suggestion for bad `Fn` traits
estebank Dec 13, 2019
e21be12
Avoid output dependency on std spans
estebank Dec 13, 2019
a4883ba
Account for multiple trait bounds with missing associated types
estebank Dec 18, 2019
87bf6bd
Cleanup: move code to their own methods and deduplicate actions
estebank Dec 18, 2019
97219d8
Don't suppress move errors for union fields
matthewjasper Dec 15, 2019
d72ceb4
Fix suggestion span for typo in associated type name
estebank Dec 19, 2019
90ef197
Better comment
mark-i-m Dec 20, 2019
0e61dcc
Rollup merge of #67163 - TheSamsa:split-up-ptr-mod, r=Mark-Simulacrum
Centril Dec 20, 2019
28a724e
Rollup merge of #67268 - estebank:assoc-types, r=oli-obk
Centril Dec 20, 2019
d9f1f48
Rollup merge of #67314 - matthewjasper:union-move-errors, r=nikomatsakis
Centril Dec 20, 2019
27e39b1
Rollup merge of #67392 - csmoe:async-typeinfo, r=estebank
Centril Dec 20, 2019
ec436c0
Rollup merge of #67404 - mark-i-m:split-1, r=matthewjasper
Centril Dec 20, 2019
a146309
Rollup merge of #67428 - Centril:ibp-explicit-match, r=matthewjasper
Centril Dec 20, 2019
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
755 changes: 755 additions & 0 deletions src/libcore/ptr/const_ptr.rs

Large diffs are not rendered by default.

1,696 changes: 5 additions & 1,691 deletions src/libcore/ptr/mod.rs

Large diffs are not rendered by default.

925 changes: 925 additions & 0 deletions src/libcore/ptr/mut_ptr.rs

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,16 @@ impl fmt::Display for YieldSource {
}
}

impl From<GeneratorKind> for YieldSource {
fn from(kind: GeneratorKind) -> Self {
match kind {
// Guess based on the kind of the current generator.
GeneratorKind::Gen => Self::Yield,
GeneratorKind::Async(_) => Self::Await,
}
}
}

// N.B., if you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,7 @@ fn resolve_local<'tcx>(
/// | VariantName(..., P&, ...)
/// | [ ..., P&, ... ]
/// | ( ..., P&, ... )
/// | ... "|" P& "|" ...
/// | box P&
fn is_binding_pat(pat: &hir::Pat) -> bool {
// Note that the code below looks for *explicit* refs only, that is, it won't
Expand Down Expand Up @@ -1212,6 +1213,7 @@ fn resolve_local<'tcx>(
pats3.iter().any(|p| is_binding_pat(&p))
}

PatKind::Or(ref subpats) |
PatKind::TupleStruct(_, ref subpats, _) |
PatKind::Tuple(ref subpats, _) => {
subpats.iter().any(|p| is_binding_pat(&p))
Expand All @@ -1221,7 +1223,13 @@ fn resolve_local<'tcx>(
is_binding_pat(&subpat)
}

_ => false,
PatKind::Ref(_, _) |
PatKind::Binding(hir::BindingAnnotation::Unannotated, ..) |
PatKind::Binding(hir::BindingAnnotation::Mutable, ..) |
PatKind::Wild |
PatKind::Path(_) |
PatKind::Lit(_) |
PatKind::Range(_, _, _) => false,
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/librustc_error_codes/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ E0211: include_str!("./error_codes/E0211.md"),
E0214: include_str!("./error_codes/E0214.md"),
E0220: include_str!("./error_codes/E0220.md"),
E0221: include_str!("./error_codes/E0221.md"),
E0222: include_str!("./error_codes/E0222.md"),
E0223: include_str!("./error_codes/E0223.md"),
E0225: include_str!("./error_codes/E0225.md"),
E0229: include_str!("./error_codes/E0229.md"),
Expand Down Expand Up @@ -456,8 +457,6 @@ E0745: include_str!("./error_codes/E0745.md"),
// E0217, // ambiguous associated type, defined in multiple supertraits
// E0218, // no associated type defined
// E0219, // associated type defined in higher-ranked supertrait
// E0222, // Error code E0045 (variadic function must have C or cdecl calling
// convention) duplicate
E0224, // at least one non-builtin train is required for an object type
E0226, // only a single explicit lifetime bound is permitted
E0227, // ambiguous lifetime bound, explicit lifetime bound required
Expand Down
51 changes: 51 additions & 0 deletions src/librustc_error_codes/error_codes/E0222.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
An attempt was made to constrain an associated type.
For example:

```compile_fail,E0222
pub trait Vehicle {
type Color;
}

pub trait Box {
type Color;
}

pub trait BoxCar : Box + Vehicle {}

fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {} // Invalid constraint
```

In this example, `BoxCar` has two super-traits: `Vehicle` and `Box`. Both of
these traits define an associated type `Color`. `BoxCar` inherits two types
with that name from both super-traits. Because of this, we need to use the
fully qualified path syntax to refer to the appropriate `Color` associated
type, either `<BoxCar as Vehicle>::Color` or `<BoxCar as Box>::Color`, but this
syntax is not allowed to be used in a function signature.

In order to encode this kind of constraint, a `where` clause and a new type
parameter are needed:

```
pub trait Vehicle {
type Color;
}

pub trait Box {
type Color;
}

pub trait BoxCar : Box + Vehicle {}

// Introduce a new `CAR` type parameter
fn foo<CAR, COLOR>(
c: CAR,
) where
// Bind the type parameter `CAR` to the trait `BoxCar`
CAR: BoxCar,
// Further restrict `<BoxCar as Vehicle>::Color` to be the same as the
// type parameter `COLOR`
CAR: Vehicle<Color = COLOR>,
// We can also simultaneously restrict the other trait's associated type
CAR: Box<Color = COLOR>
{}
```
37 changes: 33 additions & 4 deletions src/librustc_mir/borrow_check/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//! Error reporting machinery for lifetime errors.

use rustc::hir::def_id::DefId;
use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc::infer::InferCtxt;
use rustc::infer::NLLRegionVariableOrigin;
use rustc::mir::{ConstraintCategory, Local, Location, Body};
use rustc::infer::{
error_reporting::nice_region_error::NiceRegionError,
InferCtxt, NLLRegionVariableOrigin,
};
use rustc::mir::{
ConstraintCategory, Local, Location, Body,
};
use rustc::ty::{self, RegionVid};
use rustc_index::vec::IndexVec;
use rustc_errors::DiagnosticBuilder;
Expand Down Expand Up @@ -93,6 +96,32 @@ pub struct ErrorConstraintInfo {
}

impl<'tcx> RegionInferenceContext<'tcx> {
/// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound,
/// then we use the name that we have on record for it. If `r` is
/// existentially bound, then we check its inferred value and try
/// to find a good name from that. Returns `None` if we can't find
/// one (e.g., this is just some random part of the CFG).
pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name)
}

/// Returns the [RegionVid] corresponding to the region returned by
/// `to_error_region`.
pub fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
if self.universal_regions.is_universal_region(r) {
Some(r)
} else {
let r_scc = self.constraint_sccs.scc(r);
let upper_bound = self.universal_upper_bound(r);
if self.scc_values.contains(r_scc, upper_bound) {
self.to_error_region_vid(upper_bound)
} else {
None
}
}
}

/// Tries to find the best constraint to blame for the fact that
/// `R: from_region`, where `R` is some region that meets
/// `target_test`. This works by following the constraint graph,
Expand Down
147 changes: 63 additions & 84 deletions src/librustc_mir/borrow_check/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,32 +928,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
}

/// Converts a region inference variable into a `ty::Region` that
/// we can use for error reporting. If `r` is universally bound,
/// then we use the name that we have on record for it. If `r` is
/// existentially bound, then we check its inferred value and try
/// to find a good name from that. Returns `None` if we can't find
/// one (e.g., this is just some random part of the CFG).
pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name)
}

/// Returns the [RegionVid] corresponding to the region returned by
/// `to_error_region`.
pub fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
if self.universal_regions.is_universal_region(r) {
Some(r)
} else {
let r_scc = self.constraint_sccs.scc(r);
let upper_bound = self.universal_upper_bound(r);
if self.scc_values.contains(r_scc, upper_bound) {
self.to_error_region_vid(upper_bound)
} else {
None
}
}
}

/// Invoked when we have some type-test (e.g., `T: 'X`) that we cannot
/// prove to be satisfied. If this is a closure, we will attempt to
/// "promote" this type-test into our `ClosureRegionRequirements` and
Expand Down Expand Up @@ -1164,7 +1138,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// include the CFG anyhow.
/// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
/// a result `'y`.
fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
pub (in crate::borrow_check) fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
debug!("universal_upper_bound(r={:?}={})", r, self.region_value_str(r));

// Find the smallest universal region that contains all other
Expand Down Expand Up @@ -1458,19 +1432,34 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!("check_polonius_subset_errors: subset_error longer_fr={:?},\
shorter_fr={:?}", longer_fr, shorter_fr);

self.report_or_propagate_universal_region_error(
let propagated = self.try_propagate_universal_region_error(
*longer_fr,
*shorter_fr,
infcx,
body,
local_names,
upvars,
mir_def_id,
&mut propagated_outlives_requirements,
&mut outlives_suggestion,
errors_buffer,
region_naming,
);
if !propagated {
// If we are not in a context where we can't propagate errors, or we
// could not shrink `fr` to something smaller, then just report an
// error.
//
// Note: in this case, we use the unapproximated regions to report the
// error. This gives better error messages in some cases.
let db = self.report_error(
body,
local_names,
upvars,
infcx,
mir_def_id,
*longer_fr,
NLLRegionVariableOrigin::FreeRegion,
*shorter_fr,
&mut outlives_suggestion,
region_naming,
);

db.buffer(errors_buffer);
}
}

// Handle the placeholder errors as usual, until the chalk-rustc-polonius triumvirate has
Expand Down Expand Up @@ -1594,48 +1583,59 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return None;
}

self.report_or_propagate_universal_region_error(
let propagated = self.try_propagate_universal_region_error(
longer_fr,
shorter_fr,
infcx,
body,
local_names,
upvars,
mir_def_id,
propagated_outlives_requirements,
outlives_suggestion,
errors_buffer,
region_naming,
)
);

if propagated {
None
} else {
// If we are not in a context where we can't propagate errors, or we
// could not shrink `fr` to something smaller, then just report an
// error.
//
// Note: in this case, we use the unapproximated regions to report the
// error. This gives better error messages in some cases.
let db = self.report_error(
body,
local_names,
upvars,
infcx,
mir_def_id,
longer_fr,
NLLRegionVariableOrigin::FreeRegion,
shorter_fr,
outlives_suggestion,
region_naming,
);

db.buffer(errors_buffer);

Some(ErrorReported)
}
}

fn report_or_propagate_universal_region_error(
/// Attempt to propagate a region error (e.g. `'a: 'b`) that is not met to a closure's
/// creator. If we cannot, then the caller should report an error to the user.
///
/// Returns `true` if the error was propagated, and `false` otherwise.
fn try_propagate_universal_region_error(
&self,
longer_fr: RegionVid,
shorter_fr: RegionVid,
infcx: &InferCtxt<'_, 'tcx>,
body: &Body<'tcx>,
local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
mir_def_id: DefId,
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
errors_buffer: &mut Vec<Diagnostic>,
region_naming: &mut RegionErrorNamingCtx,
) -> Option<ErrorReported> {
debug!(
"report_or_propagate_universal_region_error: fr={:?} does not outlive shorter_fr={:?}",
longer_fr, shorter_fr,
);

) -> bool {
if let Some(propagated_outlives_requirements) = propagated_outlives_requirements {
// Shrink `longer_fr` until we find a non-local region (if we do).
// We'll call it `fr-` -- it's ever so slightly smaller than
// `longer_fr`.

if let Some(fr_minus) =
self.universal_region_relations.non_local_lower_bound(longer_fr) {
debug!("report_or_propagate_universal_region_error: fr_minus={:?}", fr_minus);
debug!("try_propagate_universal_region_error: fr_minus={:?}", fr_minus);

let blame_span_category =
self.find_outlives_blame_span(body, longer_fr,
Expand All @@ -1648,7 +1648,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.universal_region_relations
.non_local_upper_bounds(&shorter_fr);
debug!(
"report_or_propagate_universal_region_error: shorter_fr_plus={:?}",
"try_propagate_universal_region_error: shorter_fr_plus={:?}",
shorter_fr_plus
);
for &&fr in &shorter_fr_plus {
Expand All @@ -1660,32 +1660,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
category: blame_span_category.0,
});
}
return None;
return true;
}
}

// If we are not in a context where we can't propagate errors, or we
// could not shrink `fr` to something smaller, then just report an
// error.
//
// Note: in this case, we use the unapproximated regions to report the
// error. This gives better error messages in some cases.
let db = self.report_error(
body,
local_names,
upvars,
infcx,
mir_def_id,
longer_fr,
NLLRegionVariableOrigin::FreeRegion,
shorter_fr,
outlives_suggestion,
region_naming,
);

db.buffer(errors_buffer);

Some(ErrorReported)
false
}

fn check_bound_universal_region(
Expand Down
Loading