compare-method lint
This commit is contained in:
parent
f652651275
commit
ddabd509a8
24 changed files with 152 additions and 67 deletions
|
@ -646,13 +646,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let SubregionOrigin::CompareImplMethodObligation {
|
if let SubregionOrigin::CompareImplMethodObligation {
|
||||||
span, item_name, impl_item_def_id, trait_item_def_id
|
span, item_name, impl_item_def_id, trait_item_def_id, lint_id
|
||||||
} = origin {
|
} = origin {
|
||||||
self.report_extra_impl_obligation(span,
|
self.report_extra_impl_obligation(span,
|
||||||
item_name,
|
item_name,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id,
|
trait_item_def_id,
|
||||||
&format!("`{}: {}`", bound_kind, sub))
|
&format!("`{}: {}`", bound_kind, sub),
|
||||||
|
lint_id)
|
||||||
.emit();
|
.emit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -977,12 +978,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
infer::CompareImplMethodObligation { span,
|
infer::CompareImplMethodObligation { span,
|
||||||
item_name,
|
item_name,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id } => {
|
trait_item_def_id,
|
||||||
|
lint_id } => {
|
||||||
self.report_extra_impl_obligation(span,
|
self.report_extra_impl_obligation(span,
|
||||||
item_name,
|
item_name,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id,
|
trait_item_def_id,
|
||||||
&format!("`{}: {}`", sup, sub))
|
&format!("`{}: {}`", sup, sub),
|
||||||
|
lint_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,6 +368,10 @@ pub enum SubregionOrigin<'tcx> {
|
||||||
item_name: ast::Name,
|
item_name: ast::Name,
|
||||||
impl_item_def_id: DefId,
|
impl_item_def_id: DefId,
|
||||||
trait_item_def_id: DefId,
|
trait_item_def_id: DefId,
|
||||||
|
|
||||||
|
// this is `Some(_)` if this error arises from the bug fix for
|
||||||
|
// #18937. This is a temporary measure.
|
||||||
|
lint_id: Option<ast::NodeId>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1816,12 +1820,14 @@ impl<'tcx> SubregionOrigin<'tcx> {
|
||||||
|
|
||||||
traits::ObligationCauseCode::CompareImplMethodObligation { item_name,
|
traits::ObligationCauseCode::CompareImplMethodObligation { item_name,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id } =>
|
trait_item_def_id,
|
||||||
|
lint_id } =>
|
||||||
SubregionOrigin::CompareImplMethodObligation {
|
SubregionOrigin::CompareImplMethodObligation {
|
||||||
span: cause.span,
|
span: cause.span,
|
||||||
item_name: item_name,
|
item_name: item_name,
|
||||||
impl_item_def_id: impl_item_def_id,
|
impl_item_def_id: impl_item_def_id,
|
||||||
trait_item_def_id: trait_item_def_id,
|
trait_item_def_id: trait_item_def_id,
|
||||||
|
lint_id: lint_id,
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => default(),
|
_ => default(),
|
||||||
|
|
|
@ -198,6 +198,12 @@ declare_lint! {
|
||||||
"patterns in functions without body were erroneously allowed"
|
"patterns in functions without body were erroneously allowed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
pub EXTRA_REQUIREMENT_IN_IMPL,
|
||||||
|
Warn,
|
||||||
|
"detects extra requirements in impls that were erroneously allowed"
|
||||||
|
}
|
||||||
|
|
||||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||||
/// which are used by other parts of the compiler.
|
/// which are used by other parts of the compiler.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -235,7 +241,8 @@ impl LintPass for HardwiredLints {
|
||||||
HR_LIFETIME_IN_ASSOC_TYPE,
|
HR_LIFETIME_IN_ASSOC_TYPE,
|
||||||
LIFETIME_UNDERSCORE,
|
LIFETIME_UNDERSCORE,
|
||||||
SAFE_EXTERN_STATICS,
|
SAFE_EXTERN_STATICS,
|
||||||
PATTERNS_IN_FNS_WITHOUT_BODY
|
PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||||
|
EXTRA_REQUIREMENT_IN_IMPL
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ use std::fmt;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::parse::token::InternedString;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::{MultiSpan, Span};
|
||||||
use errors::{self, Diagnostic, DiagnosticBuilder};
|
use errors::{self, Diagnostic, DiagnosticBuilder};
|
||||||
use hir;
|
use hir;
|
||||||
use hir::intravisit as hir_visit;
|
use hir::intravisit as hir_visit;
|
||||||
|
@ -107,9 +107,12 @@ impl fmt::Debug for EarlyLint {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EarlyLint {
|
impl EarlyLint {
|
||||||
pub fn new(id: LintId, span: Span, msg: String) -> Self {
|
pub fn new<M: EarlyLintMessage>(id: LintId, span: Span, msg: M) -> Self {
|
||||||
let mut diagnostic = Diagnostic::new(errors::Level::Warning, &msg);
|
let diagnostic = msg.into_diagnostic(span);
|
||||||
diagnostic.set_span(span);
|
EarlyLint { id: id, span: span, diagnostic: diagnostic }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_diagnostic(id: LintId, span: Span, diagnostic: Diagnostic) -> Self {
|
||||||
EarlyLint { id: id, span: span, diagnostic: diagnostic }
|
EarlyLint { id: id, span: span, diagnostic: diagnostic }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +123,23 @@ impl EarlyLint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait EarlyLintMessage {
|
||||||
|
fn into_diagnostic(self, span: Span) -> Diagnostic;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EarlyLintMessage for String {
|
||||||
|
fn into_diagnostic(self, span: Span) -> Diagnostic {
|
||||||
|
let mut diagnostic = Diagnostic::new(errors::Level::Warning, &self);
|
||||||
|
diagnostic.set_span(span);
|
||||||
|
diagnostic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EarlyLintMessage for Diagnostic {
|
||||||
|
fn into_diagnostic(self, _span: Span) -> Diagnostic {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Extra information for a future incompatibility lint. See the call
|
/// Extra information for a future incompatibility lint. See the call
|
||||||
/// to `register_future_incompatible` in `librustc_lint/lib.rs` for
|
/// to `register_future_incompatible` in `librustc_lint/lib.rs` for
|
||||||
|
@ -439,13 +458,15 @@ pub fn raw_emit_lint(sess: &Session,
|
||||||
raw_struct_lint(sess, lints, lint, lvlsrc, span, msg).emit();
|
raw_struct_lint(sess, lints, lint, lvlsrc, span, msg).emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw_struct_lint<'a>(sess: &'a Session,
|
pub fn raw_struct_lint<'a, S>(sess: &'a Session,
|
||||||
lints: &LintStore,
|
lints: &LintStore,
|
||||||
lint: &'static Lint,
|
lint: &'static Lint,
|
||||||
lvlsrc: LevelSource,
|
lvlsrc: LevelSource,
|
||||||
span: Option<Span>,
|
span: Option<S>,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a>
|
||||||
|
where S: Into<MultiSpan>
|
||||||
|
{
|
||||||
let (mut level, source) = lvlsrc;
|
let (mut level, source) = lvlsrc;
|
||||||
if level == Allow {
|
if level == Allow {
|
||||||
return sess.diagnostic().struct_dummy();
|
return sess.diagnostic().struct_dummy();
|
||||||
|
|
|
@ -41,7 +41,7 @@ use hir;
|
||||||
|
|
||||||
pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
||||||
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
|
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
|
||||||
raw_struct_lint, FutureIncompatibleInfo, EarlyLint};
|
raw_struct_lint, FutureIncompatibleInfo, EarlyLint, EarlyLintMessage};
|
||||||
|
|
||||||
/// Specification of a single lint.
|
/// Specification of a single lint.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
|
@ -258,11 +258,11 @@ impl Session {
|
||||||
pub fn unimpl(&self, msg: &str) -> ! {
|
pub fn unimpl(&self, msg: &str) -> ! {
|
||||||
self.diagnostic().unimpl(msg)
|
self.diagnostic().unimpl(msg)
|
||||||
}
|
}
|
||||||
pub fn add_lint(&self,
|
pub fn add_lint<M: lint::EarlyLintMessage>(&self,
|
||||||
lint: &'static lint::Lint,
|
lint: &'static lint::Lint,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
msg: String) {
|
msg: M) {
|
||||||
let lint_id = lint::LintId::of(lint);
|
let lint_id = lint::LintId::of(lint);
|
||||||
let mut lints = self.lints.borrow_mut();
|
let mut lints = self.lints.borrow_mut();
|
||||||
let early_lint = lint::EarlyLint::new(lint_id, sp, msg);
|
let early_lint = lint::EarlyLint::new(lint_id, sp, msg);
|
||||||
|
|
|
@ -27,6 +27,7 @@ use super::{
|
||||||
use fmt_macros::{Parser, Piece, Position};
|
use fmt_macros::{Parser, Piece, Position};
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use infer::{self, InferCtxt, TypeOrigin};
|
use infer::{self, InferCtxt, TypeOrigin};
|
||||||
|
use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
|
||||||
use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
||||||
use ty::error::ExpectedFound;
|
use ty::error::ExpectedFound;
|
||||||
use ty::fast_reject;
|
use ty::fast_reject;
|
||||||
|
@ -423,9 +424,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
item_name: ast::Name,
|
item_name: ast::Name,
|
||||||
_impl_item_def_id: DefId,
|
_impl_item_def_id: DefId,
|
||||||
trait_item_def_id: DefId,
|
trait_item_def_id: DefId,
|
||||||
requirement: &fmt::Display)
|
requirement: &fmt::Display,
|
||||||
|
lint_id: Option<ast::NodeId>) // (*)
|
||||||
-> DiagnosticBuilder<'tcx>
|
-> DiagnosticBuilder<'tcx>
|
||||||
{
|
{
|
||||||
|
// (*) This parameter is temporary and used only for phasing
|
||||||
|
// in the bug fix to #18937. If it is `Some`, it has a kind of
|
||||||
|
// weird effect -- the diagnostic is reported as a lint, and
|
||||||
|
// the builder which is returned is marked as canceled.
|
||||||
|
|
||||||
let mut err =
|
let mut err =
|
||||||
struct_span_err!(self.tcx.sess,
|
struct_span_err!(self.tcx.sess,
|
||||||
error_span,
|
error_span,
|
||||||
|
@ -441,6 +448,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
error_span,
|
error_span,
|
||||||
&format!("impl has extra requirement {}", requirement));
|
&format!("impl has extra requirement {}", requirement));
|
||||||
|
|
||||||
|
if let Some(node_id) = lint_id {
|
||||||
|
let diagnostic = (*err).clone();
|
||||||
|
self.tcx.sess.add_lint(EXTRA_REQUIREMENT_IN_IMPL, node_id, error_span, diagnostic);
|
||||||
|
err.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,14 +465,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
let mut err = match *error {
|
let mut err = match *error {
|
||||||
SelectionError::Unimplemented => {
|
SelectionError::Unimplemented => {
|
||||||
if let ObligationCauseCode::CompareImplMethodObligation {
|
if let ObligationCauseCode::CompareImplMethodObligation {
|
||||||
item_name, impl_item_def_id, trait_item_def_id
|
item_name, impl_item_def_id, trait_item_def_id, lint_id
|
||||||
} = obligation.cause.code {
|
} = obligation.cause.code {
|
||||||
self.report_extra_impl_obligation(
|
self.report_extra_impl_obligation(
|
||||||
span,
|
span,
|
||||||
item_name,
|
item_name,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id,
|
trait_item_def_id,
|
||||||
&format!("`{}`", obligation.predicate))
|
&format!("`{}`", obligation.predicate),
|
||||||
|
lint_id)
|
||||||
.emit();
|
.emit();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -138,10 +138,12 @@ pub enum ObligationCauseCode<'tcx> {
|
||||||
|
|
||||||
ImplDerivedObligation(DerivedObligationCause<'tcx>),
|
ImplDerivedObligation(DerivedObligationCause<'tcx>),
|
||||||
|
|
||||||
|
// error derived when matching traits/impls; see ObligationCause for more details
|
||||||
CompareImplMethodObligation {
|
CompareImplMethodObligation {
|
||||||
item_name: ast::Name,
|
item_name: ast::Name,
|
||||||
impl_item_def_id: DefId,
|
impl_item_def_id: DefId,
|
||||||
trait_item_def_id: DefId
|
trait_item_def_id: DefId,
|
||||||
|
lint_id: Option<ast::NodeId>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,11 +197,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
|
||||||
}
|
}
|
||||||
super::CompareImplMethodObligation { item_name,
|
super::CompareImplMethodObligation { item_name,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id } => {
|
trait_item_def_id,
|
||||||
|
lint_id } => {
|
||||||
Some(super::CompareImplMethodObligation {
|
Some(super::CompareImplMethodObligation {
|
||||||
item_name: item_name,
|
item_name: item_name,
|
||||||
impl_item_def_id: impl_item_def_id,
|
impl_item_def_id: impl_item_def_id,
|
||||||
trait_item_def_id: trait_item_def_id,
|
trait_item_def_id: trait_item_def_id,
|
||||||
|
lint_id: lint_id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::fmt;
|
||||||
use syntax_pos::{MultiSpan, Span};
|
use syntax_pos::{MultiSpan, Span};
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Diagnostic {
|
pub struct Diagnostic {
|
||||||
pub level: Level,
|
pub level: Level,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
@ -16,7 +16,7 @@ pub struct Diagnostic {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For example a note attached to an error.
|
/// For example a note attached to an error.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SubDiagnostic {
|
pub struct SubDiagnostic {
|
||||||
pub level: Level,
|
pub level: Level,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
@ -190,9 +190,3 @@ impl Diagnostic {
|
||||||
self.children.push(sub);
|
self.children.push(sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Diagnostic {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
self.message.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -70,6 +70,21 @@ impl<'a> DiagnosticBuilder<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match self.level {
|
||||||
|
Level::Bug |
|
||||||
|
Level::Fatal |
|
||||||
|
Level::PhaseFatal |
|
||||||
|
Level::Error => {
|
||||||
|
self.handler.bump_err_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
Level::Warning |
|
||||||
|
Level::Note |
|
||||||
|
Level::Help |
|
||||||
|
Level::Cancelled => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.handler.emitter.borrow_mut().emit(&self);
|
self.handler.emitter.borrow_mut().emit(&self);
|
||||||
self.cancel();
|
self.cancel();
|
||||||
self.handler.panic_if_treat_err_as_bug();
|
self.handler.panic_if_treat_err_as_bug();
|
||||||
|
@ -140,6 +155,13 @@ impl<'a> DiagnosticBuilder<'a> {
|
||||||
diagnostic: Diagnostic::new_with_code(level, code, message)
|
diagnostic: Diagnostic::new_with_code(level, code, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_diagnostic(mut self) -> Diagnostic {
|
||||||
|
// annoyingly, the Drop impl means we can't actually move
|
||||||
|
let result = self.diagnostic.clone();
|
||||||
|
self.cancel();
|
||||||
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Debug for DiagnosticBuilder<'a> {
|
impl<'a> Debug for DiagnosticBuilder<'a> {
|
||||||
|
|
|
@ -57,7 +57,7 @@ mod lock;
|
||||||
use syntax_pos::{BytePos, Loc, FileLinesResult, FileName, MultiSpan, Span, NO_EXPANSION};
|
use syntax_pos::{BytePos, Loc, FileLinesResult, FileName, MultiSpan, Span, NO_EXPANSION};
|
||||||
use syntax_pos::MacroBacktrace;
|
use syntax_pos::MacroBacktrace;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum RenderSpan {
|
pub enum RenderSpan {
|
||||||
/// A FullSpan renders with both with an initial line for the
|
/// A FullSpan renders with both with an initial line for the
|
||||||
/// message, prefixed by file:linenum, followed by a summary of
|
/// message, prefixed by file:linenum, followed by a summary of
|
||||||
|
@ -71,7 +71,7 @@ pub enum RenderSpan {
|
||||||
Suggestion(CodeSuggestion),
|
Suggestion(CodeSuggestion),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct CodeSuggestion {
|
pub struct CodeSuggestion {
|
||||||
pub msp: MultiSpan,
|
pub msp: MultiSpan,
|
||||||
pub substitutes: Vec<String>,
|
pub substitutes: Vec<String>,
|
||||||
|
@ -293,7 +293,6 @@ impl Handler {
|
||||||
sp: S,
|
sp: S,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
|
||||||
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
|
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
|
||||||
result.set_span(sp);
|
result.set_span(sp);
|
||||||
result
|
result
|
||||||
|
@ -303,21 +302,18 @@ impl Handler {
|
||||||
msg: &str,
|
msg: &str,
|
||||||
code: &str)
|
code: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
|
||||||
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
|
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
|
||||||
result.set_span(sp);
|
result.set_span(sp);
|
||||||
result.code(code.to_owned());
|
result.code(code.to_owned());
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
|
||||||
DiagnosticBuilder::new(self, Level::Error, msg)
|
DiagnosticBuilder::new(self, Level::Error, msg)
|
||||||
}
|
}
|
||||||
pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
|
pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
|
||||||
sp: S,
|
sp: S,
|
||||||
msg: &str)
|
msg: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
|
||||||
let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
|
let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
|
||||||
result.set_span(sp);
|
result.set_span(sp);
|
||||||
result
|
result
|
||||||
|
@ -327,24 +323,16 @@ impl Handler {
|
||||||
msg: &str,
|
msg: &str,
|
||||||
code: &str)
|
code: &str)
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
|
||||||
let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
|
let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
|
||||||
result.set_span(sp);
|
result.set_span(sp);
|
||||||
result.code(code.to_owned());
|
result.code(code.to_owned());
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
|
||||||
self.bump_err_count();
|
|
||||||
DiagnosticBuilder::new(self, Level::Fatal, msg)
|
DiagnosticBuilder::new(self, Level::Fatal, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel(&self, err: &mut DiagnosticBuilder) {
|
pub fn cancel(&self, err: &mut DiagnosticBuilder) {
|
||||||
if err.level == Level::Error || err.level == Level::Fatal {
|
|
||||||
self.err_count.set(self.err_count
|
|
||||||
.get()
|
|
||||||
.checked_sub(1)
|
|
||||||
.expect("cancelled an error but err_count is 0"));
|
|
||||||
}
|
|
||||||
err.cancel();
|
err.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +344,6 @@ impl Handler {
|
||||||
|
|
||||||
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> FatalError {
|
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> FatalError {
|
||||||
self.emit(&sp.into(), msg, Fatal);
|
self.emit(&sp.into(), msg, Fatal);
|
||||||
self.bump_err_count();
|
|
||||||
self.panic_if_treat_err_as_bug();
|
self.panic_if_treat_err_as_bug();
|
||||||
return FatalError;
|
return FatalError;
|
||||||
}
|
}
|
||||||
|
@ -366,13 +353,11 @@ impl Handler {
|
||||||
code: &str)
|
code: &str)
|
||||||
-> FatalError {
|
-> FatalError {
|
||||||
self.emit_with_code(&sp.into(), msg, code, Fatal);
|
self.emit_with_code(&sp.into(), msg, code, Fatal);
|
||||||
self.bump_err_count();
|
|
||||||
self.panic_if_treat_err_as_bug();
|
self.panic_if_treat_err_as_bug();
|
||||||
return FatalError;
|
return FatalError;
|
||||||
}
|
}
|
||||||
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||||
self.emit(&sp.into(), msg, Error);
|
self.emit(&sp.into(), msg, Error);
|
||||||
self.bump_err_count();
|
|
||||||
self.panic_if_treat_err_as_bug();
|
self.panic_if_treat_err_as_bug();
|
||||||
}
|
}
|
||||||
pub fn mut_span_err<'a, S: Into<MultiSpan>>(&'a self,
|
pub fn mut_span_err<'a, S: Into<MultiSpan>>(&'a self,
|
||||||
|
@ -381,12 +366,10 @@ impl Handler {
|
||||||
-> DiagnosticBuilder<'a> {
|
-> DiagnosticBuilder<'a> {
|
||||||
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
|
let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
|
||||||
result.set_span(sp);
|
result.set_span(sp);
|
||||||
self.bump_err_count();
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
|
pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
|
||||||
self.emit_with_code(&sp.into(), msg, code, Error);
|
self.emit_with_code(&sp.into(), msg, code, Error);
|
||||||
self.bump_err_count();
|
|
||||||
self.panic_if_treat_err_as_bug();
|
self.panic_if_treat_err_as_bug();
|
||||||
}
|
}
|
||||||
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||||
|
@ -405,7 +388,6 @@ impl Handler {
|
||||||
}
|
}
|
||||||
pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||||
self.emit(&sp.into(), msg, Bug);
|
self.emit(&sp.into(), msg, Bug);
|
||||||
self.bump_err_count();
|
|
||||||
}
|
}
|
||||||
pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||||
self.emit(&sp.into(), msg, Note);
|
self.emit(&sp.into(), msg, Note);
|
||||||
|
@ -419,7 +401,6 @@ impl Handler {
|
||||||
}
|
}
|
||||||
let mut db = DiagnosticBuilder::new(self, Fatal, msg);
|
let mut db = DiagnosticBuilder::new(self, Fatal, msg);
|
||||||
db.emit();
|
db.emit();
|
||||||
self.bump_err_count();
|
|
||||||
FatalError
|
FatalError
|
||||||
}
|
}
|
||||||
pub fn err(&self, msg: &str) {
|
pub fn err(&self, msg: &str) {
|
||||||
|
@ -428,7 +409,6 @@ impl Handler {
|
||||||
}
|
}
|
||||||
let mut db = DiagnosticBuilder::new(self, Error, msg);
|
let mut db = DiagnosticBuilder::new(self, Error, msg);
|
||||||
db.emit();
|
db.emit();
|
||||||
self.bump_err_count();
|
|
||||||
}
|
}
|
||||||
pub fn warn(&self, msg: &str) {
|
pub fn warn(&self, msg: &str) {
|
||||||
let mut db = DiagnosticBuilder::new(self, Warning, msg);
|
let mut db = DiagnosticBuilder::new(self, Warning, msg);
|
||||||
|
|
|
@ -229,6 +229,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||||
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
|
id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
|
||||||
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
|
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
|
||||||
},
|
},
|
||||||
|
FutureIncompatibleInfo {
|
||||||
|
id: LintId::of(EXTRA_REQUIREMENT_IN_IMPL),
|
||||||
|
reference: "issue #18937 <https://github.com/rust-lang/rust/issues/18937>",
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Register renamed and removed lints
|
// Register renamed and removed lints
|
||||||
|
|
|
@ -367,6 +367,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
item_name: impl_m.name,
|
item_name: impl_m.name,
|
||||||
impl_item_def_id: impl_m.def_id,
|
impl_item_def_id: impl_m.def_id,
|
||||||
trait_item_def_id: trait_m.def_id,
|
trait_item_def_id: trait_m.def_id,
|
||||||
|
lint_id: Some(impl_m_body_id),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
// Regression test for #18937.
|
// Regression test for #18937.
|
||||||
|
|
||||||
|
#![deny(extra_requirement_in_impl)]
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
#![deny(extra_requirement_in_impl)]
|
||||||
|
|
||||||
// Test that we elaborate `Type: 'region` constraints and infer various important things.
|
// Test that we elaborate `Type: 'region` constraints and infer various important things.
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
error[E0276]: impl has stricter requirements than trait
|
error[E0276]: impl has stricter requirements than trait
|
||||||
--> $DIR/proj-outlives-region.rs:21:5
|
--> $DIR/proj-outlives-region.rs:22:5
|
||||||
|
|
|
|
||||||
16 | fn foo() where T: 'a;
|
17 | fn foo() where T: 'a;
|
||||||
| --------------------- definition of `foo` from trait
|
| --------------------- definition of `foo` from trait
|
||||||
...
|
...
|
||||||
21 | fn foo() where U: 'a { } //~ ERROR E0276
|
22 | fn foo() where U: 'a { } //~ ERROR E0276
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: 'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: 'a`
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #18937 <https://github.com/rust-lang/rust/issues/18937>
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/proj-outlives-region.rs:12:9
|
||||||
|
|
|
||||||
|
12 | #![deny(extra_requirement_in_impl)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
0
src/test/ui/compare-method/proj-outlives-region.stdout
Normal file
0
src/test/ui/compare-method/proj-outlives-region.stdout
Normal file
|
@ -9,6 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
#![deny(extra_requirement_in_impl)]
|
||||||
|
|
||||||
// Test that we elaborate `Type: 'region` constraints and infer various important things.
|
// Test that we elaborate `Type: 'region` constraints and infer various important things.
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
error[E0276]: impl has stricter requirements than trait
|
error[E0276]: impl has stricter requirements than trait
|
||||||
--> $DIR/region-unrelated.rs:21:5
|
--> $DIR/region-unrelated.rs:22:5
|
||||||
|
|
|
|
||||||
16 | fn foo() where T: 'a;
|
17 | fn foo() where T: 'a;
|
||||||
| --------------------- definition of `foo` from trait
|
| --------------------- definition of `foo` from trait
|
||||||
...
|
...
|
||||||
21 | fn foo() where V: 'a { }
|
22 | fn foo() where V: 'a { }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `V: 'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `V: 'a`
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #18937 <https://github.com/rust-lang/rust/issues/18937>
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/region-unrelated.rs:12:9
|
||||||
|
|
|
||||||
|
12 | #![deny(extra_requirement_in_impl)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
0
src/test/ui/compare-method/region-unrelated.stdout
Normal file
0
src/test/ui/compare-method/region-unrelated.stdout
Normal file
|
@ -9,6 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
#![deny(extra_requirement_in_impl)]
|
||||||
|
|
||||||
// Test that we elaborate `Type: 'region` constraints and infer various important things.
|
// Test that we elaborate `Type: 'region` constraints and infer various important things.
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
error[E0276]: impl has stricter requirements than trait
|
error[E0276]: impl has stricter requirements than trait
|
||||||
--> $DIR/region.rs:21:5
|
--> $DIR/region.rs:22:5
|
||||||
|
|
|
|
||||||
16 | fn foo();
|
17 | fn foo();
|
||||||
| --------- definition of `foo` from trait
|
| --------- definition of `foo` from trait
|
||||||
...
|
...
|
||||||
21 | fn foo() where 'a: 'b { }
|
22 | fn foo() where 'a: 'b { }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #18937 <https://github.com/rust-lang/rust/issues/18937>
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/region.rs:12:9
|
||||||
|
|
|
||||||
|
12 | #![deny(extra_requirement_in_impl)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
0
src/test/ui/compare-method/region.stdout
Normal file
0
src/test/ui/compare-method/region.stdout
Normal file
Loading…
Add table
Add a link
Reference in a new issue