Skip to content

Commit dbf994b

Browse files
committed
Make RFC 1214 warnings into errors, and rip out the "warn or err"
associated machinery. Future such attempts should go through lints anyhow. There is a fair amount of fallout in the compile-fail tests, as WF checking now occurs earlier in the process.
1 parent de62f9d commit dbf994b

File tree

88 files changed

+291
-1187
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+291
-1187
lines changed

src/librustc/middle/infer/error_reporting.rs

+6-25
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
578578
// where the error was detected. But that span is not readily
579579
// accessible.
580580

581-
let is_warning = match origin {
582-
infer::RFC1214Subregion(_) => true,
583-
_ => false,
584-
};
585-
586581
let labeled_user_string = match bound_kind {
587582
GenericKind::Param(ref p) =>
588583
format!("the parameter type `{}`", p),
@@ -593,8 +588,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
593588
match sub {
594589
ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
595590
// Does the required lifetime have a nice name we can print?
596-
span_err_or_warn!(
597-
is_warning, self.tcx.sess, origin.span(), E0309,
591+
span_err!(
592+
self.tcx.sess, origin.span(), E0309,
598593
"{} may not live long enough", labeled_user_string);
599594
self.tcx.sess.fileline_help(
600595
origin.span(),
@@ -606,8 +601,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
606601

607602
ty::ReStatic => {
608603
// Does the required lifetime have a nice name we can print?
609-
span_err_or_warn!(
610-
is_warning, self.tcx.sess, origin.span(), E0310,
604+
span_err!(
605+
self.tcx.sess, origin.span(), E0310,
611606
"{} may not live long enough", labeled_user_string);
612607
self.tcx.sess.fileline_help(
613608
origin.span(),
@@ -618,8 +613,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
618613

619614
_ => {
620615
// If not, be less specific.
621-
span_err_or_warn!(
622-
is_warning, self.tcx.sess, origin.span(), E0311,
616+
span_err!(
617+
self.tcx.sess, origin.span(), E0311,
623618
"{} may not live long enough",
624619
labeled_user_string);
625620
self.tcx.sess.fileline_help(
@@ -634,10 +629,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
634629
}
635630
}
636631

637-
if is_warning {
638-
self.tcx.sess.note_rfc_1214(origin.span());
639-
}
640-
641632
self.note_region_origin(&origin);
642633
}
643634

@@ -646,13 +637,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
646637
sub: Region,
647638
sup: Region) {
648639
match origin {
649-
infer::RFC1214Subregion(ref suborigin) => {
650-
// Ideally, this would be a warning, but it doesn't
651-
// seem to come up in practice, since the changes from
652-
// RFC1214 mostly trigger errors in type definitions
653-
// that don't wind up coming down this path.
654-
self.report_concrete_failure((**suborigin).clone(), sub, sup);
655-
}
656640
infer::Subtype(trace) => {
657641
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
658642
self.report_and_explain_type_error(trace, &terr);
@@ -1599,9 +1583,6 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
15991583

16001584
fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
16011585
match *origin {
1602-
infer::RFC1214Subregion(ref suborigin) => {
1603-
self.note_region_origin(suborigin);
1604-
}
16051586
infer::Subtype(ref trace) => {
16061587
let desc = match trace.origin {
16071588
TypeOrigin::Misc(_) => {

src/librustc/middle/infer/mod.rs

-7
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ use middle::ty::relate::{Relate, RelateResult, TypeRelation};
3737
use rustc_data_structures::unify::{self, UnificationTable};
3838
use std::cell::{RefCell, Ref};
3939
use std::fmt;
40-
use std::rc::Rc;
4140
use syntax::ast;
4241
use syntax::codemap;
4342
use syntax::codemap::{Span, DUMMY_SP};
@@ -198,11 +197,6 @@ pub struct TypeTrace<'tcx> {
198197
/// See `error_reporting.rs` for more details
199198
#[derive(Clone, Debug)]
200199
pub enum SubregionOrigin<'tcx> {
201-
// Marker to indicate a constraint that only arises due to new
202-
// provisions from RFC 1214. This will result in a warning, not an
203-
// error.
204-
RFC1214Subregion(Rc<SubregionOrigin<'tcx>>),
205-
206200
// Arose from a subtyping relation
207201
Subtype(TypeTrace<'tcx>),
208202

@@ -1568,7 +1562,6 @@ impl TypeOrigin {
15681562
impl<'tcx> SubregionOrigin<'tcx> {
15691563
pub fn span(&self) -> Span {
15701564
match *self {
1571-
RFC1214Subregion(ref a) => a.span(),
15721565
Subtype(ref a) => a.span(),
15731566
InfStackClosure(a) => a,
15741567
InvokeClosure(a) => a,

src/librustc/middle/traits/error_reporting.rs

+30-44
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ use syntax::attr::{AttributeMethods, AttrMetaMethods};
3636

3737
#[derive(Debug, PartialEq, Eq, Hash)]
3838
pub struct TraitErrorKey<'tcx> {
39-
is_warning: bool,
4039
span: Span,
4140
predicate: ty::Predicate<'tcx>
4241
}
@@ -47,7 +46,6 @@ impl<'tcx> TraitErrorKey<'tcx> {
4746
let predicate =
4847
infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
4948
TraitErrorKey {
50-
is_warning: is_warning(&e.obligation),
5149
span: e.obligation.cause.span,
5250
predicate: infcx.tcx.erase_regions(&predicate)
5351
}
@@ -83,10 +81,6 @@ fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
8381
}
8482
}
8583

86-
fn is_warning<T>(obligation: &Obligation<T>) -> bool {
87-
obligation.cause.code.is_rfc1214()
88-
}
89-
9084
pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
9185
obligation: &PredicateObligation<'tcx>,
9286
error: &MismatchedProjectionTypes<'tcx>)
@@ -100,8 +94,8 @@ pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
10094
// then $X will be unified with TyError, but the error still needs to be
10195
// reported.
10296
if !infcx.tcx.sess.has_errors() || !predicate.references_error() {
103-
span_err_or_warn!(
104-
is_warning(obligation), infcx.tcx.sess, obligation.cause.span, E0271,
97+
span_err!(
98+
infcx.tcx.sess, obligation.cause.span, E0271,
10599
"type mismatch resolving `{}`: {}",
106100
predicate,
107101
error.err);
@@ -208,12 +202,11 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
208202
obligation: &PredicateObligation<'tcx>,
209203
error: &SelectionError<'tcx>)
210204
{
211-
let is_warning = is_warning(obligation);
212205
match *error {
213206
SelectionError::Unimplemented => {
214207
if let ObligationCauseCode::CompareImplMethodObligation = obligation.cause.code {
215-
span_err_or_warn!(
216-
is_warning, infcx.tcx.sess, obligation.cause.span, E0276,
208+
span_err!(
209+
infcx.tcx.sess, obligation.cause.span, E0276,
217210
"the requirement `{}` appears on the impl \
218211
method but not on the corresponding trait method",
219212
obligation.predicate);
@@ -225,8 +218,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
225218

226219
if !infcx.tcx.sess.has_errors() || !trait_predicate.references_error() {
227220
let trait_ref = trait_predicate.to_poly_trait_ref();
228-
span_err_or_warn!(
229-
is_warning, infcx.tcx.sess, obligation.cause.span, E0277,
221+
span_err!(
222+
infcx.tcx.sess, obligation.cause.span, E0277,
230223
"the trait `{}` is not implemented for the type `{}`",
231224
trait_ref, trait_ref.self_ty());
232225

@@ -245,8 +238,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
245238
let predicate = infcx.resolve_type_vars_if_possible(predicate);
246239
let err = infcx.equality_predicate(obligation.cause.span,
247240
&predicate).err().unwrap();
248-
span_err_or_warn!(
249-
is_warning, infcx.tcx.sess, obligation.cause.span, E0278,
241+
span_err!(
242+
infcx.tcx.sess, obligation.cause.span, E0278,
250243
"the requirement `{}` is not satisfied (`{}`)",
251244
predicate,
252245
err);
@@ -257,8 +250,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
257250
let predicate = infcx.resolve_type_vars_if_possible(predicate);
258251
let err = infcx.region_outlives_predicate(obligation.cause.span,
259252
&predicate).err().unwrap();
260-
span_err_or_warn!(
261-
is_warning, infcx.tcx.sess, obligation.cause.span, E0279,
253+
span_err!(
254+
infcx.tcx.sess, obligation.cause.span, E0279,
262255
"the requirement `{}` is not satisfied (`{}`)",
263256
predicate,
264257
err);
@@ -268,8 +261,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
268261
ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
269262
let predicate =
270263
infcx.resolve_type_vars_if_possible(&obligation.predicate);
271-
span_err_or_warn!(
272-
is_warning, infcx.tcx.sess, obligation.cause.span, E0280,
264+
span_err!(
265+
infcx.tcx.sess, obligation.cause.span, E0280,
273266
"the requirement `{}` is not satisfied",
274267
predicate);
275268
note_obligation_cause(infcx, obligation);
@@ -281,8 +274,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
281274
report_object_safety_error(infcx.tcx,
282275
obligation.cause.span,
283276
trait_def_id,
284-
violations,
285-
is_warning);
277+
violations);
286278
note_obligation_cause(infcx, obligation);
287279
}
288280

@@ -304,8 +296,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
304296
let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref);
305297
let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref);
306298
if !actual_trait_ref.self_ty().references_error() {
307-
span_err_or_warn!(
308-
is_warning, infcx.tcx.sess, obligation.cause.span, E0281,
299+
span_err!(
300+
infcx.tcx.sess, obligation.cause.span, E0281,
309301
"type mismatch: the type `{}` implements the trait `{}`, \
310302
but the trait `{}` is required ({})",
311303
expected_trait_ref.self_ty(),
@@ -318,8 +310,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
318310

319311
TraitNotObjectSafe(did) => {
320312
let violations = object_safety_violations(infcx.tcx, did);
321-
report_object_safety_error(infcx.tcx, obligation.cause.span, did,
322-
violations, is_warning);
313+
report_object_safety_error(infcx.tcx, obligation.cause.span, did, violations);
323314
note_obligation_cause(infcx, obligation);
324315
}
325316
}
@@ -328,11 +319,10 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
328319
pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
329320
span: Span,
330321
trait_def_id: DefId,
331-
violations: Vec<ObjectSafetyViolation>,
332-
is_warning: bool)
322+
violations: Vec<ObjectSafetyViolation>)
333323
{
334-
span_err_or_warn!(
335-
is_warning, tcx.sess, span, E0038,
324+
span_err!(
325+
tcx.sess, span, E0038,
336326
"the trait `{}` cannot be made into an object",
337327
tcx.item_path_str(trait_def_id));
338328

@@ -402,7 +392,17 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
402392
let self_ty = trait_ref.self_ty();
403393
let all_types = &trait_ref.substs().types;
404394
if all_types.references_error() {
405-
} else if all_types.needs_infer() {
395+
} else {
396+
// Typically, this ambiguity should only happen if
397+
// there are unresolved type inference variables
398+
// (otherwise it would suggest a coherence
399+
// failure). But given #21974 that is not necessarily
400+
// the case -- we can have multiple where clauses that
401+
// are only distinguished by a region, which results
402+
// in an ambiguity even when all types are fully
403+
// known, since we don't dispatch based on region
404+
// relationships.
405+
406406
// This is kind of a hack: it frequently happens that some earlier
407407
// error prevents types from being fully inferred, and then we get
408408
// a bunch of uninteresting errors saying something like "<generic
@@ -430,16 +430,6 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
430430
note_obligation_cause(infcx, obligation);
431431
}
432432
}
433-
} else if !infcx.tcx.sess.has_errors() {
434-
// Ambiguity. Coherence should have reported an error.
435-
infcx.tcx.sess.span_bug(
436-
obligation.cause.span,
437-
&format!(
438-
"coherence failed to report ambiguity: \
439-
cannot locate the impl of the trait `{}` for \
440-
the type `{}`",
441-
trait_ref,
442-
self_ty));
443433
}
444434
}
445435

@@ -491,10 +481,6 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
491481
let tcx = infcx.tcx;
492482
match *cause_code {
493483
ObligationCauseCode::MiscObligation => { }
494-
ObligationCauseCode::RFC1214(ref subcode) => {
495-
tcx.sess.note_rfc_1214(cause_span);
496-
note_obligation_cause_code(infcx, predicate, cause_span, subcode);
497-
}
498484
ObligationCauseCode::SliceOrArrayElem => {
499485
tcx.sess.fileline_note(
500486
cause_span,

src/librustc/middle/traits/fulfill.rs

+10-23
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,14 @@ use super::CodeSelectionError;
2121
use super::is_object_safe;
2222
use super::FulfillmentError;
2323
use super::ObligationCause;
24-
use super::ObligationCauseCode;
2524
use super::PredicateObligation;
2625
use super::project;
27-
use super::RFC1214Warning;
2826
use super::select::SelectionContext;
2927
use super::Unimplemented;
3028
use super::util::predicate_for_builtin_bound;
3129

3230
pub struct FulfilledPredicates<'tcx> {
33-
set: FnvHashSet<(RFC1214Warning, ty::Predicate<'tcx>)>
31+
set: FnvHashSet<ty::Predicate<'tcx>>
3432
}
3533

3634
/// The fulfillment context is used to drive trait resolution. It
@@ -194,9 +192,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
194192

195193
assert!(!obligation.has_escaping_regions());
196194

197-
let w = RFC1214Warning(obligation.cause.code.is_rfc1214());
198-
199-
if self.is_duplicate_or_add(infcx.tcx, w, &obligation.predicate) {
195+
if self.is_duplicate_or_add(infcx.tcx, &obligation.predicate) {
200196
debug!("register_predicate({:?}) -- already seen, skip", obligation);
201197
return;
202198
}
@@ -261,7 +257,6 @@ impl<'tcx> FulfillmentContext<'tcx> {
261257

262258
fn is_duplicate_or_add(&mut self,
263259
tcx: &ty::ctxt<'tcx>,
264-
w: RFC1214Warning,
265260
predicate: &ty::Predicate<'tcx>)
266261
-> bool {
267262
// This is a kind of dirty hack to allow us to avoid "rederiving"
@@ -276,12 +271,10 @@ impl<'tcx> FulfillmentContext<'tcx> {
276271
// evaluating the 'nested obligations'. This cache lets us
277272
// skip those.
278273

279-
let will_warn_due_to_rfc1214 = w.0;
280-
let errors_will_be_reported = self.errors_will_be_reported && !will_warn_due_to_rfc1214;
281-
if errors_will_be_reported && predicate.is_global() {
282-
tcx.fulfilled_predicates.borrow_mut().is_duplicate_or_add(w, predicate)
274+
if self.errors_will_be_reported && predicate.is_global() {
275+
tcx.fulfilled_predicates.borrow_mut().is_duplicate_or_add(predicate)
283276
} else {
284-
self.duplicate_set.is_duplicate_or_add(w, predicate)
277+
self.duplicate_set.is_duplicate_or_add(predicate)
285278
}
286279
}
287280

@@ -496,12 +489,8 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
496489
}
497490

498491
ty::Predicate::WellFormed(ty) => {
499-
let rfc1214 = match obligation.cause.code {
500-
ObligationCauseCode::RFC1214(_) => true,
501-
_ => false,
502-
};
503492
match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id,
504-
ty, obligation.cause.span, rfc1214) {
493+
ty, obligation.cause.span) {
505494
Some(obligations) => {
506495
new_obligations.extend(obligations);
507496
true
@@ -539,13 +528,11 @@ impl<'tcx> FulfilledPredicates<'tcx> {
539528
}
540529
}
541530

542-
pub fn is_duplicate(&self, w: RFC1214Warning, p: &ty::Predicate<'tcx>) -> bool {
543-
let key = (w, p.clone());
544-
self.set.contains(&key)
531+
pub fn is_duplicate(&self, key: &ty::Predicate<'tcx>) -> bool {
532+
self.set.contains(key)
545533
}
546534

547-
fn is_duplicate_or_add(&mut self, w: RFC1214Warning, p: &ty::Predicate<'tcx>) -> bool {
548-
let key = (w, p.clone());
549-
!self.set.insert(key)
535+
fn is_duplicate_or_add(&mut self, key: &ty::Predicate<'tcx>) -> bool {
536+
!self.set.insert(key.clone())
550537
}
551538
}

0 commit comments

Comments
 (0)