mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
parent
ad8a3eb039
commit
d7bb98f7a1
@ -164,6 +164,9 @@ pub struct Session {
|
||||
|
||||
/// Cap lint level specified by a driver specifically.
|
||||
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
|
||||
|
||||
/// `Span`s of trait methods that weren't found to avoid emitting object safety errors
|
||||
pub trait_methods_not_found: OneThread<RefCell<FxHashSet<Span>>>,
|
||||
}
|
||||
|
||||
pub struct PerfStats {
|
||||
@ -1230,6 +1233,7 @@ fn build_session_(
|
||||
has_global_allocator: Once::new(),
|
||||
has_panic_handler: Once::new(),
|
||||
driver_lint_caps,
|
||||
trait_methods_not_found: OneThread::new(RefCell::new(Default::default())),
|
||||
};
|
||||
|
||||
validate_commandline_args_with_session_available(&sess);
|
||||
|
@ -754,9 +754,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||
let violations = self.tcx.global_tcx()
|
||||
.object_safety_violations(trait_def_id);
|
||||
self.tcx.report_object_safety_error(span,
|
||||
trait_def_id,
|
||||
violations)
|
||||
if let Some(err) = self.tcx.report_object_safety_error(
|
||||
span,
|
||||
trait_def_id,
|
||||
violations,
|
||||
) {
|
||||
err
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
|
||||
@ -884,7 +890,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
TraitNotObjectSafe(did) => {
|
||||
let violations = self.tcx.global_tcx().object_safety_violations(did);
|
||||
self.tcx.report_object_safety_error(span, did, violations)
|
||||
if let Some(err) = self.tcx.report_object_safety_error(span, did, violations) {
|
||||
err
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// already reported in the query
|
||||
@ -1293,12 +1303,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
err
|
||||
}
|
||||
|
||||
pub fn report_object_safety_error(self,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
violations: Vec<ObjectSafetyViolation>)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
pub fn report_object_safety_error(
|
||||
self,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
violations: Vec<ObjectSafetyViolation>,
|
||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
if self.sess.trait_methods_not_found.borrow().contains(&span) {
|
||||
// Avoid emitting error caused by non-existing method (#58734)
|
||||
return None;
|
||||
}
|
||||
let trait_str = self.def_path_str(trait_def_id);
|
||||
let span = self.sess.source_map().def_span(span);
|
||||
let mut err = struct_span_err!(
|
||||
@ -1313,7 +1327,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
err.note(&violation.error_msg());
|
||||
}
|
||||
}
|
||||
err
|
||||
Some(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,9 +1012,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
let object_safety_violations =
|
||||
tcx.global_tcx().astconv_object_safety_violations(principal.def_id());
|
||||
if !object_safety_violations.is_empty() {
|
||||
tcx.report_object_safety_error(
|
||||
span, principal.def_id(), object_safety_violations)
|
||||
.emit();
|
||||
tcx.report_object_safety_error(span, principal.def_id(), object_safety_violations)
|
||||
.map(|mut err| err.emit());
|
||||
return tcx.types.err;
|
||||
}
|
||||
|
||||
|
@ -60,13 +60,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_method_error<'b>(&self,
|
||||
span: Span,
|
||||
rcvr_ty: Ty<'tcx>,
|
||||
item_name: ast::Ident,
|
||||
source: SelfSource<'b>,
|
||||
error: MethodError<'tcx>,
|
||||
args: Option<&'gcx [hir::Expr]>) {
|
||||
pub fn report_method_error<'b>(
|
||||
&self,
|
||||
span: Span,
|
||||
rcvr_ty: Ty<'tcx>,
|
||||
item_name: ast::Ident,
|
||||
source: SelfSource<'b>,
|
||||
error: MethodError<'tcx>,
|
||||
args: Option<&'gcx [hir::Expr]>,
|
||||
) {
|
||||
// Avoid suggestions when we don't know what's going on.
|
||||
if rcvr_ty.references_error() {
|
||||
return;
|
||||
@ -373,6 +375,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
err.span_label(span, format!("{} not found in `{}`", item_kind, ty_str));
|
||||
self.tcx.sess.trait_methods_not_found.borrow_mut().insert(span);
|
||||
}
|
||||
|
||||
if self.is_fn_ty(&rcvr_ty, span) {
|
||||
|
22
src/test/ui/issues/issue-58734.rs
Normal file
22
src/test/ui/issues/issue-58734.rs
Normal file
@ -0,0 +1,22 @@
|
||||
trait Trait {
|
||||
fn exists(self) -> ();
|
||||
|
||||
fn not_object_safe() -> Self;
|
||||
}
|
||||
|
||||
impl Trait for () {
|
||||
fn exists(self) -> () {
|
||||
}
|
||||
|
||||
fn not_object_safe() -> Self {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// object-safe or not, this call is OK
|
||||
Trait::exists(());
|
||||
// no object safety error
|
||||
Trait::nonexistent(());
|
||||
//~^ ERROR no function or associated item named `nonexistent` found for type `dyn Trait`
|
||||
}
|
11
src/test/ui/issues/issue-58734.stderr
Normal file
11
src/test/ui/issues/issue-58734.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0599]: no function or associated item named `nonexistent` found for type `dyn Trait` in the current scope
|
||||
--> $DIR/issue-58734.rs:20:12
|
||||
|
|
||||
LL | Trait::nonexistent(());
|
||||
| -------^^^^^^^^^^^
|
||||
| |
|
||||
| function or associated item not found in `dyn Trait`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user