rollup merge of #23580: nikomatsakis/pattern-and-overflow
This commit is contained in:
commit
bed77408df
11 changed files with 88 additions and 104 deletions
|
@ -25,6 +25,7 @@ use core::mem;
|
||||||
use core::ops::{self, Deref, Add, Index};
|
use core::ops::{self, Deref, Add, Index};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::slice;
|
use core::slice;
|
||||||
|
use core::str::Pattern;
|
||||||
use unicode::str as unicode_str;
|
use unicode::str as unicode_str;
|
||||||
use unicode::str::Utf16Item;
|
use unicode::str::Utf16Item;
|
||||||
|
|
||||||
|
@ -765,6 +766,25 @@ impl<'a> Extend<&'a str> for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A convenience impl that delegates to the impl for `&str`
|
||||||
|
impl<'a, 'b> Pattern<'a> for &'b String {
|
||||||
|
type Searcher = <&'b str as Pattern<'a>>::Searcher;
|
||||||
|
|
||||||
|
fn into_searcher(self, haystack: &'a str) -> <&'b str as Pattern<'a>>::Searcher {
|
||||||
|
self[..].into_searcher(haystack)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_contained_in(self, haystack: &'a str) -> bool {
|
||||||
|
self[..].is_contained_in(haystack)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_prefix_of(self, haystack: &'a str) -> bool {
|
||||||
|
self[..].is_prefix_of(haystack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl PartialEq for String {
|
impl PartialEq for String {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -474,22 +474,16 @@ impl<'a, 'b> Pattern<'a> for &'b [char] {
|
||||||
s, CharEqPattern(s));
|
s, CharEqPattern(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A convenience impl that delegates to the impl for `&str`
|
||||||
|
impl<'a, 'b> Pattern<'a> for &'b &'b str {
|
||||||
|
type Searcher = <&'b str as Pattern<'a>>::Searcher;
|
||||||
|
associated_items!(<&'b str as Pattern<'a>>::Searcher,
|
||||||
|
s, (*s));
|
||||||
|
}
|
||||||
|
|
||||||
/// Searches for chars that match the given predicate
|
/// Searches for chars that match the given predicate
|
||||||
impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool {
|
impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool {
|
||||||
type Searcher = <CharEqPattern<Self> as Pattern<'a>>::Searcher;
|
type Searcher = <CharEqPattern<Self> as Pattern<'a>>::Searcher;
|
||||||
associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
|
associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
|
||||||
s, CharEqPattern(s));
|
s, CharEqPattern(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deref-forward impl
|
|
||||||
|
|
||||||
use ops::Deref;
|
|
||||||
|
|
||||||
/// Delegates to the next deref coercion of `Self` that implements `Pattern`
|
|
||||||
impl<'a, 'b, P: 'b + ?Sized, T: Deref<Target = P> + ?Sized> Pattern<'a> for &'b T
|
|
||||||
where &'b P: Pattern<'a>
|
|
||||||
{
|
|
||||||
type Searcher = <&'b P as Pattern<'a>>::Searcher;
|
|
||||||
associated_items!(<&'b P as Pattern<'a>>::Searcher,
|
|
||||||
s, (&**s));
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,9 +13,7 @@ fn test_pattern_deref_forward() {
|
||||||
let data = "aabcdaa";
|
let data = "aabcdaa";
|
||||||
assert!(data.contains("bcd"));
|
assert!(data.contains("bcd"));
|
||||||
assert!(data.contains(&"bcd"));
|
assert!(data.contains(&"bcd"));
|
||||||
assert!(data.contains(&&"bcd"));
|
|
||||||
assert!(data.contains(&"bcd".to_string()));
|
assert!(data.contains(&"bcd".to_string()));
|
||||||
assert!(data.contains(&&"bcd".to_string()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -12,6 +12,7 @@ use super::{
|
||||||
FulfillmentError,
|
FulfillmentError,
|
||||||
FulfillmentErrorCode,
|
FulfillmentErrorCode,
|
||||||
MismatchedProjectionTypes,
|
MismatchedProjectionTypes,
|
||||||
|
Obligation,
|
||||||
ObligationCauseCode,
|
ObligationCauseCode,
|
||||||
OutputTypeParameterMismatch,
|
OutputTypeParameterMismatch,
|
||||||
PredicateObligation,
|
PredicateObligation,
|
||||||
|
@ -21,6 +22,7 @@ use super::{
|
||||||
use fmt_macros::{Parser, Piece, Position};
|
use fmt_macros::{Parser, Piece, Position};
|
||||||
use middle::infer::InferCtxt;
|
use middle::infer::InferCtxt;
|
||||||
use middle::ty::{self, AsPredicate, ReferencesError, ToPolyTraitRef, TraitRef};
|
use middle::ty::{self, AsPredicate, ReferencesError, ToPolyTraitRef, TraitRef};
|
||||||
|
use middle::ty_fold::TypeFoldable;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use syntax::codemap::{DUMMY_SP, Span};
|
use syntax::codemap::{DUMMY_SP, Span};
|
||||||
use syntax::attr::{AttributeMethods, AttrMetaMethods};
|
use syntax::attr::{AttributeMethods, AttrMetaMethods};
|
||||||
|
@ -137,13 +139,17 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
report
|
report
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
/// Reports that an overflow has occurred and halts compilation. We
|
||||||
obligation: &PredicateObligation<'tcx>,
|
/// halt compilation unconditionally because it is important that
|
||||||
error: &SelectionError<'tcx>)
|
/// overflows never be masked -- they basically represent computations
|
||||||
|
/// whose result could not be truly determined and thus we can't say
|
||||||
|
/// if the program type checks or not -- and they are unusual
|
||||||
|
/// occurrences in any case.
|
||||||
|
pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
|
obligation: &Obligation<'tcx, T>)
|
||||||
|
-> !
|
||||||
|
where T: UserString<'tcx> + TypeFoldable<'tcx>
|
||||||
{
|
{
|
||||||
match *error {
|
|
||||||
SelectionError::Overflow => {
|
|
||||||
// We could track the stack here more precisely if we wanted, I imagine.
|
|
||||||
let predicate =
|
let predicate =
|
||||||
infcx.resolve_type_vars_if_possible(&obligation.predicate);
|
infcx.resolve_type_vars_if_possible(&obligation.predicate);
|
||||||
span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
|
span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
|
||||||
|
@ -153,8 +159,16 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
suggest_new_overflow_limit(infcx.tcx, obligation.cause.span);
|
suggest_new_overflow_limit(infcx.tcx, obligation.cause.span);
|
||||||
|
|
||||||
note_obligation_cause(infcx, obligation);
|
note_obligation_cause(infcx, obligation);
|
||||||
|
|
||||||
|
infcx.tcx.sess.abort_if_errors();
|
||||||
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
|
obligation: &PredicateObligation<'tcx>,
|
||||||
|
error: &SelectionError<'tcx>)
|
||||||
|
{
|
||||||
|
match *error {
|
||||||
SelectionError::Unimplemented => {
|
SelectionError::Unimplemented => {
|
||||||
match &obligation.cause.code {
|
match &obligation.cause.code {
|
||||||
&ObligationCauseCode::CompareImplMethodObligation => {
|
&ObligationCauseCode::CompareImplMethodObligation => {
|
||||||
|
@ -309,8 +323,9 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_obligation_cause<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
fn note_obligation_cause<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
obligation: &PredicateObligation<'tcx>)
|
obligation: &Obligation<'tcx, T>)
|
||||||
|
where T: UserString<'tcx>
|
||||||
{
|
{
|
||||||
note_obligation_cause_code(infcx,
|
note_obligation_cause_code(infcx,
|
||||||
&obligation.predicate,
|
&obligation.predicate,
|
||||||
|
@ -318,10 +333,11 @@ fn note_obligation_cause<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
&obligation.cause.code);
|
&obligation.cause.code);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_obligation_cause_code<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
|
||||||
predicate: &ty::Predicate<'tcx>,
|
predicate: &T,
|
||||||
cause_span: Span,
|
cause_span: Span,
|
||||||
cause_code: &ObligationCauseCode<'tcx>)
|
cause_code: &ObligationCauseCode<'tcx>)
|
||||||
|
where T: UserString<'tcx>
|
||||||
{
|
{
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
match *cause_code {
|
match *cause_code {
|
||||||
|
|
|
@ -23,9 +23,10 @@ use std::slice::Iter;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::{Span, DUMMY_SP};
|
use syntax::codemap::{Span, DUMMY_SP};
|
||||||
use util::ppaux::{Repr, UserString};
|
use util::ppaux::Repr;
|
||||||
|
|
||||||
pub use self::error_reporting::report_fulfillment_errors;
|
pub use self::error_reporting::report_fulfillment_errors;
|
||||||
|
pub use self::error_reporting::report_overflow_error;
|
||||||
pub use self::error_reporting::suggest_new_overflow_limit;
|
pub use self::error_reporting::suggest_new_overflow_limit;
|
||||||
pub use self::coherence::orphan_check;
|
pub use self::coherence::orphan_check;
|
||||||
pub use self::coherence::overlapping_impls;
|
pub use self::coherence::overlapping_impls;
|
||||||
|
@ -151,7 +152,6 @@ pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
pub enum SelectionError<'tcx> {
|
pub enum SelectionError<'tcx> {
|
||||||
Unimplemented,
|
Unimplemented,
|
||||||
Overflow,
|
|
||||||
OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
|
OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
|
||||||
ty::PolyTraitRef<'tcx>,
|
ty::PolyTraitRef<'tcx>,
|
||||||
ty::type_err<'tcx>),
|
ty::type_err<'tcx>),
|
||||||
|
@ -327,16 +327,9 @@ pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||||
let result = match fulfill_cx.select_all_or_error(infcx, typer) {
|
let result = match fulfill_cx.select_all_or_error(infcx, typer) {
|
||||||
Ok(()) => Ok(Some(())), // Success, we know it implements Copy.
|
Ok(()) => Ok(Some(())), // Success, we know it implements Copy.
|
||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
// Check if overflow occurred anywhere and propagate that.
|
// If there were any hard errors, propagate an arbitrary
|
||||||
if errors.iter().any(
|
// one of those. If no hard errors at all, report
|
||||||
|err| match err.code { CodeSelectionError(Overflow) => true, _ => false })
|
// ambiguity.
|
||||||
{
|
|
||||||
return Err(Overflow);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if there were any hard errors, propagate an
|
|
||||||
// arbitrary one of those. If no hard errors at all,
|
|
||||||
// report ambiguity.
|
|
||||||
let sel_error =
|
let sel_error =
|
||||||
errors.iter()
|
errors.iter()
|
||||||
.filter_map(|err| {
|
.filter_map(|err| {
|
||||||
|
@ -384,16 +377,8 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||||
// soldering on, so just treat this like not implemented
|
// soldering on, so just treat this like not implemented
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Err(Overflow) => {
|
|
||||||
span_err!(infcx.tcx.sess, span, E0285,
|
|
||||||
"overflow evaluating whether `{}` is `{}`",
|
|
||||||
ty.user_string(infcx.tcx),
|
|
||||||
bound.user_string(infcx.tcx));
|
|
||||||
suggest_new_overflow_limit(infcx.tcx, span);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// other errors: not implemented.
|
// errors: not implemented.
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -652,15 +637,6 @@ impl<'tcx> FulfillmentError<'tcx> {
|
||||||
{
|
{
|
||||||
FulfillmentError { obligation: obligation, code: code }
|
FulfillmentError { obligation: obligation, code: code }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_overflow(&self) -> bool {
|
|
||||||
match self.code {
|
|
||||||
CodeAmbiguity => false,
|
|
||||||
CodeSelectionError(Overflow) => true,
|
|
||||||
CodeSelectionError(_) => false,
|
|
||||||
CodeProjectionError(_) => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TraitObligation<'tcx> {
|
impl<'tcx> TraitObligation<'tcx> {
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
//! Code for projecting associated types out of trait references.
|
//! Code for projecting associated types out of trait references.
|
||||||
|
|
||||||
use super::elaborate_predicates;
|
use super::elaborate_predicates;
|
||||||
|
use super::report_overflow_error;
|
||||||
use super::Obligation;
|
use super::Obligation;
|
||||||
use super::ObligationCause;
|
use super::ObligationCause;
|
||||||
use super::Overflow;
|
|
||||||
use super::PredicateObligation;
|
use super::PredicateObligation;
|
||||||
use super::SelectionContext;
|
use super::SelectionContext;
|
||||||
use super::SelectionError;
|
use super::SelectionError;
|
||||||
|
@ -442,7 +442,7 @@ fn project_type<'cx,'tcx>(
|
||||||
let recursion_limit = selcx.tcx().sess.recursion_limit.get();
|
let recursion_limit = selcx.tcx().sess.recursion_limit.get();
|
||||||
if obligation.recursion_depth >= recursion_limit {
|
if obligation.recursion_depth >= recursion_limit {
|
||||||
debug!("project: overflow!");
|
debug!("project: overflow!");
|
||||||
return Err(ProjectionTyError::TraitSelectionError(Overflow));
|
report_overflow_error(selcx.infcx(), &obligation);
|
||||||
}
|
}
|
||||||
|
|
||||||
let obligation_trait_ref =
|
let obligation_trait_ref =
|
||||||
|
|
|
@ -21,8 +21,9 @@ use super::DerivedObligationCause;
|
||||||
use super::project;
|
use super::project;
|
||||||
use super::project::{normalize_with_depth, Normalized};
|
use super::project::{normalize_with_depth, Normalized};
|
||||||
use super::{PredicateObligation, TraitObligation, ObligationCause};
|
use super::{PredicateObligation, TraitObligation, ObligationCause};
|
||||||
|
use super::{report_overflow_error};
|
||||||
use super::{ObligationCauseCode, BuiltinDerivedObligation, ImplDerivedObligation};
|
use super::{ObligationCauseCode, BuiltinDerivedObligation, ImplDerivedObligation};
|
||||||
use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
|
use super::{SelectionError, Unimplemented, OutputTypeParameterMismatch};
|
||||||
use super::{Selection};
|
use super::{Selection};
|
||||||
use super::{SelectionResult};
|
use super::{SelectionResult};
|
||||||
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
|
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
|
||||||
|
@ -561,10 +562,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// not update) the cache.
|
// not update) the cache.
|
||||||
let recursion_limit = self.infcx.tcx.sess.recursion_limit.get();
|
let recursion_limit = self.infcx.tcx.sess.recursion_limit.get();
|
||||||
if stack.obligation.recursion_depth >= recursion_limit {
|
if stack.obligation.recursion_depth >= recursion_limit {
|
||||||
debug!("{} --> overflow (limit={})",
|
report_overflow_error(self.infcx(), &stack.obligation);
|
||||||
stack.obligation.repr(self.tcx()),
|
|
||||||
recursion_limit);
|
|
||||||
return Err(Overflow)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the cache. Note that we skolemize the trait-ref
|
// Check the cache. Note that we skolemize the trait-ref
|
||||||
|
@ -2582,11 +2580,13 @@ impl<'o, 'tcx> Repr<'tcx> for TraitObligationStack<'o, 'tcx> {
|
||||||
impl<'tcx> EvaluationResult<'tcx> {
|
impl<'tcx> EvaluationResult<'tcx> {
|
||||||
fn may_apply(&self) -> bool {
|
fn may_apply(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
EvaluatedToOk
|
EvaluatedToOk |
|
||||||
| EvaluatedToAmbig
|
EvaluatedToAmbig |
|
||||||
| EvaluatedToErr(Overflow)
|
EvaluatedToErr(OutputTypeParameterMismatch(..)) =>
|
||||||
| EvaluatedToErr(OutputTypeParameterMismatch(..)) => true,
|
true,
|
||||||
EvaluatedToErr(Unimplemented) => false,
|
|
||||||
|
EvaluatedToErr(Unimplemented) =>
|
||||||
|
false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -514,9 +514,6 @@ impl<'tcx> Repr<'tcx> for super::VtableObjectData<'tcx> {
|
||||||
impl<'tcx> Repr<'tcx> for super::SelectionError<'tcx> {
|
impl<'tcx> Repr<'tcx> for super::SelectionError<'tcx> {
|
||||||
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
|
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
super::Overflow =>
|
|
||||||
format!("Overflow"),
|
|
||||||
|
|
||||||
super::Unimplemented =>
|
super::Unimplemented =>
|
||||||
format!("Unimplemented"),
|
format!("Unimplemented"),
|
||||||
|
|
||||||
|
|
|
@ -1025,7 +1025,8 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
// shallow result we are looking for -- that is, what specific impl.
|
// shallow result we are looking for -- that is, what specific impl.
|
||||||
let typer = NormalizingClosureTyper::new(tcx);
|
let typer = NormalizingClosureTyper::new(tcx);
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
||||||
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
|
let obligation =
|
||||||
|
traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
|
||||||
trait_ref.to_poly_trait_predicate());
|
trait_ref.to_poly_trait_predicate());
|
||||||
let selection = match selcx.select(&obligation) {
|
let selection = match selcx.select(&obligation) {
|
||||||
Ok(Some(selection)) => selection,
|
Ok(Some(selection)) => selection,
|
||||||
|
@ -1081,7 +1082,7 @@ pub fn predicates_hold<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), predicate);
|
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), predicate);
|
||||||
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
||||||
}
|
}
|
||||||
drain_fulfillment_cx(DUMMY_SP, &infcx, &mut fulfill_cx, &()).is_ok()
|
drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NormalizingClosureTyper<'a,'tcx:'a> {
|
pub struct NormalizingClosureTyper<'a,'tcx:'a> {
|
||||||
|
@ -1138,7 +1139,7 @@ pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
|
||||||
-> T
|
-> T
|
||||||
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||||
{
|
{
|
||||||
match drain_fulfillment_cx(span, infcx, fulfill_cx, result) {
|
match drain_fulfillment_cx(infcx, fulfill_cx, result) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
infcx.tcx.sess.span_bug(
|
infcx.tcx.sess.span_bug(
|
||||||
|
@ -1156,8 +1157,7 @@ pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
|
||||||
/// inference variables that appear in `result` to be unified, and
|
/// inference variables that appear in `result` to be unified, and
|
||||||
/// hence we need to process those obligations to get the complete
|
/// hence we need to process those obligations to get the complete
|
||||||
/// picture of the type.
|
/// picture of the type.
|
||||||
pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
|
pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>,
|
||||||
infcx: &infer::InferCtxt<'a,'tcx>,
|
|
||||||
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
||||||
result: &T)
|
result: &T)
|
||||||
-> StdResult<T,Vec<traits::FulfillmentError<'tcx>>>
|
-> StdResult<T,Vec<traits::FulfillmentError<'tcx>>>
|
||||||
|
@ -1173,16 +1173,9 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
|
||||||
match fulfill_cx.select_all_or_error(infcx, &typer) {
|
match fulfill_cx.select_all_or_error(infcx, &typer) {
|
||||||
Ok(()) => { }
|
Ok(()) => { }
|
||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
// We always want to surface any overflow errors, no matter what.
|
|
||||||
if errors.iter().all(|e| e.is_overflow()) {
|
|
||||||
infcx.tcx.sess.span_fatal(
|
|
||||||
span,
|
|
||||||
"reached the recursion limit during monomorphization");
|
|
||||||
} else {
|
|
||||||
return Err(errors);
|
return Err(errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Use freshen to simultaneously replace all type variables with
|
// Use freshen to simultaneously replace all type variables with
|
||||||
// their bindings and replace all regions with 'static. This is
|
// their bindings and replace all regions with 'static. This is
|
||||||
|
|
|
@ -33,7 +33,4 @@ fn main() {
|
||||||
|
|
||||||
0.contains(bits);
|
0.contains(bits);
|
||||||
//~^ ERROR overflow
|
//~^ ERROR overflow
|
||||||
//~| ERROR overflow
|
|
||||||
//~| ERROR overflow
|
|
||||||
//~| ERROR mismatched types
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,12 +42,5 @@ fn is_send<T:Send>() { }
|
||||||
fn main() {
|
fn main() {
|
||||||
is_send::<A>();
|
is_send::<A>();
|
||||||
//~^ ERROR overflow evaluating
|
//~^ ERROR overflow evaluating
|
||||||
//~^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
|
//~| NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
|
||||||
//~^^^ NOTE required by `is_send`
|
|
||||||
//~^^^^ ERROR overflow evaluating
|
|
||||||
//~^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
|
|
||||||
//~^^^^^^ NOTE required by `is_send`
|
|
||||||
//~^^^^^^^ ERROR overflow evaluating
|
|
||||||
//~^^^^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
|
|
||||||
//~^^^^^^^^^ NOTE required by `is_send`
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue