Changes in / [07ac6d0:de23648]
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/prelude/prelude-gen.cc
r07ac6d0 rde23648 10 10 // Created On : Sat Feb 16 08:44:58 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 19 08:19:35201913 // Update Count : 2812 // Last Modified On : Tue Apr 2 17:18:24 2019 13 // Update Count : 37 14 14 // 15 15 … … 118 118 { "?!=?", false, "signed int", Normal, "" }, 119 119 { "?=?", true, "", Normal, "" }, // void * LHS, zero_t RHS ??? 120 { "*?", false, "&", Normal, " | sized(DT)" }, // & ??? 120 // { "*?", false, "&", Normal, " | sized(DT)" }, // & ??? 121 { "*?", false, "&", Normal, "" }, // & ??? 121 122 122 123 { "?-?", false, "ptrdiff_t", Normal, " | sized(DT)" }, -
src/ResolvExpr/AlternativeFinder.cc
r07ac6d0 rde23648 258 258 // - necessary pre-requisite to pruning 259 259 AltList candidates; 260 std::list<std::string> errors; 260 261 for ( unsigned i = 0; i < alternatives.size(); ++i ) { 261 resolveAssertions( alternatives[i], indexer, candidates );262 resolveAssertions( alternatives[i], indexer, candidates, errors ); 262 263 } 263 264 // fail early if none such 264 265 if ( mode.failFast && candidates.empty() ) { 265 266 std::ostringstream stream; 266 stream << "No resolvable alternatives for expression " << expr << "\n" 267 << "Alternatives with failing assertions are:\n"; 268 printAlts( alternatives, stream, 1 ); 267 stream << "No alternatives with satisfiable assertions for " << expr << "\n"; 268 // << "Alternatives with failing assertions are:\n"; 269 // printAlts( alternatives, stream, 1 ); 270 for ( const auto& err : errors ) { 271 stream << err; 272 } 269 273 SemanticError( expr->location, stream.str() ); 270 274 } -
src/ResolvExpr/ResolveAssertions.cc
r07ac6d0 rde23648 20 20 #include <list> // for list 21 21 #include <memory> // for unique_ptr 22 #include <string> 22 #include <sstream> // for ostringstream 23 #include <string> // for string 23 24 #include <unordered_map> // for unordered_map, unordered_multimap 24 25 #include <utility> // for move … … 27 28 #include "Alternative.h" // for Alternative, AssertionItem, AssertionList 28 29 #include "Common/FilterCombos.h" // for filterCombos 30 #include "Common/Indenter.h" // for Indenter 29 31 #include "Common/utility.h" // for sort_mins 30 32 #include "ResolvExpr/RenameVars.h" // for renameTyVars … … 97 99 return { item, item.matches[i] }; 98 100 } 101 102 const DeclarationWithType* get_decl() const { return cache->at(key).deferIds[0].decl; } 99 103 100 104 // sortable by key … … 364 368 static const int recursionLimit = /* 10 */ 4; 365 369 366 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out ) {370 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ) { 367 371 // finish early if no assertions to resolve 368 372 if ( alt.need.empty() ) { … … 385 389 for ( auto& assn : resn.need ) { 386 390 // fail early if any assertion is not resolvable 387 if ( ! resolveAssertion( assn, resn, assnCache ) ) goto nextResn; 391 if ( ! resolveAssertion( assn, resn, assnCache ) ) { 392 Indenter tabs{ Indenter::tabsize, 3 }; 393 std::ostringstream ss; 394 ss << tabs << "Unsatisfiable alternative:\n"; 395 resn.alt.print( ss, ++tabs ); 396 ss << --tabs << "Could not satisfy assertion:\n"; 397 assn.decl->print( ss, ++tabs ); 398 399 errors.emplace_back( ss.str() ); 400 goto nextResn; 401 } 388 402 } 389 403 … … 404 418 resn.deferred, 405 419 CandidateEnvMerger{ resn.alt.env, resn.alt.openVars, resn.indexer } ); 420 // fail early if no mutually-compatible assertion satisfaction 421 if ( compatible.empty() ) { 422 Indenter tabs{ Indenter::tabsize, 3 }; 423 std::ostringstream ss; 424 ss << tabs << "Unsatisfiable alternative:\n"; 425 resn.alt.print( ss, ++tabs ); 426 ss << --tabs << "No mutually-compatible satisfaction for assertions:\n"; 427 ++tabs; 428 for ( const auto& d : resn.deferred ) { 429 d.get_decl()->print( ss, tabs ); 430 } 431 432 errors.emplace_back( ss.str() ); 433 goto nextResn; 434 } 406 435 // sort by cost 407 436 CandidateCost coster{ resn.indexer }; -
src/ResolvExpr/ResolveAssertions.h
r07ac6d0 rde23648 24 24 namespace ResolvExpr { 25 25 /// Recursively resolves all assertions provided in an alternative; returns true iff succeeds 26 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out );26 void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ); 27 27 } // namespace ResolvExpr 28 28 -
src/ResolvExpr/TypeEnvironment.cc
r07ac6d0 rde23648 386 386 } 387 387 388 bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 388 bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, 389 TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, 390 const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) { 389 391 390 392 auto class1 = internal_lookup( var1->get_name() ); … … 428 430 class1->set_type( common ); 429 431 } 432 class1->data.isComplete |= data.isComplete; 430 433 env.erase( class2 ); 431 434 } else return false; … … 435 438 class1->vars.insert( class2->vars.begin(), class2->vars.end() ); 436 439 class1->allowWidening = widen1; 440 class1->data.isComplete |= data.isComplete; 437 441 env.erase( class2 ); 438 442 } else { 439 443 class2->vars.insert( class1->vars.begin(), class1->vars.end() ); 440 444 class2->allowWidening = widen2; 445 class2->data.isComplete |= data.isComplete; 441 446 env.erase( class1 ); 442 447 } // if … … 445 450 class1->vars.insert( var2->get_name() ); 446 451 class1->allowWidening = widen1; 452 class1->data.isComplete |= data.isComplete; 447 453 } else if ( class2 != env.end() ) { 448 454 // var1 unbound, add to class2 449 455 class2->vars.insert( var1->get_name() ); 450 456 class2->allowWidening = widen2; 457 class2->data.isComplete |= data.isComplete; 451 458 } else { 452 459 // neither var bound, create new class -
src/ResolvExpr/TypeEnvironment.h
r07ac6d0 rde23648 139 139 /// Binds the type classes represented by `var1` and `var2` together; will add 140 140 /// one or both classes if needed. Returns false on failure. 141 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data& data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );141 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 142 142 143 143 /// Disallows widening for all bindings in the environment -
src/ResolvExpr/Unify.cc
r07ac6d0 rde23648 172 172 bool isopen2 = var2 && ( entry2 != openVars.end() ); 173 173 174 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 175 result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 174 if ( isopen1 && isopen2 ) { 175 if ( entry1->second.kind != entry2->second.kind ) { 176 result = false; 177 } else { 178 result = env.bindVarToVar( 179 var1, var2, TypeDecl::Data{ entry1->second, entry2->second }, needAssertions, 180 haveAssertions, openVars, widenMode, indexer ); 181 } 176 182 } else if ( isopen1 ) { 177 183 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); -
src/SynTree/Declaration.h
r07ac6d0 rde23648 211 211 TypeDecl::Kind kind; 212 212 bool isComplete; 213 213 214 Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {} 214 215 Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {} 215 216 Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {} 217 Data( const Data& d1, const Data& d2 ) 218 : kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {} 219 216 220 bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; } 217 221 bool operator!=(const Data & other) const { return !(*this == other);} -
tests/.expect/completeTypeError.txt
r07ac6d0 rde23648 1 completeTypeError.cfa:33:1 error: No reasonable alternatives for expression Applying untyped: 2 Name: *? 3 ...to: 4 Name: v 1 completeTypeError.cfa:34:1 error: Cannot choose between 2 alternatives for expression 2 Generated Cast of: 3 Applying untyped: 4 Name: *? 5 ...to: 6 Name: x 5 7 6 completeTypeError.cfa:34:1 error: No reasonable alternatives for expression Applying untyped: 7 Name: *? 8 ...to: 9 Name: y 8 ... to: nothing Alternatives are: 9 Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of: 10 Application of 11 Variable Expression: *?: forall 12 DT: object type 13 function 14 ... with parameters 15 intrinsic pointer to instance of type DT (not function type) 16 ... returning 17 _retval__operator_deref: reference to instance of type DT (not function type) 18 ... with attributes: 19 Attribute with name: unused 20 21 22 ... to arguments 23 Variable Expression: x: pointer to instance of struct A with body 0 24 25 ... to: nothing 26 (types: 27 void 28 ) 29 Environment:( _80_4_DT ) -> instance of struct A with body 0 (no widening) 30 31 32 Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of: 33 Application of 34 Variable Expression: *?: forall 35 DT: object type 36 function 37 ... with parameters 38 intrinsic pointer to instance of type DT (not function type) 39 ... returning 40 _retval__operator_deref: reference to instance of type DT (not function type) 41 ... with attributes: 42 Attribute with name: unused 43 44 45 ... to arguments 46 Variable Expression: x: pointer to instance of struct B with body 1 47 48 ... to: nothing 49 (types: 50 void 51 ) 52 Environment:( _80_4_DT ) -> instance of struct B with body 1 (no widening) 53 54 10 55 11 56 completeTypeError.cfa:35:1 error: No reasonable alternatives for expression Applying untyped: … … 24 69 Name: v 25 70 26 completeTypeError.cfa:5 8:1 error: No reasonable alternatives for expression Applying untyped:71 completeTypeError.cfa:59:1 error: No reasonable alternatives for expression Applying untyped: 27 72 Name: baz 28 73 ...to: 29 74 Name: y 30 75 31 completeTypeError.cfa: 59:1 error: No reasonable alternatives for expression Applying untyped:76 completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped: 32 77 Name: quux 33 78 ...to: 34 79 Name: y 35 80 36 completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped: 37 Name: *? 38 ...to: 39 Name: y 40 41 completeTypeError.cfa:72:1 error: No resolvable alternatives for expression Applying untyped: 81 completeTypeError.cfa:72:1 error: No alternatives with satisfiable assertions for Applying untyped: 42 82 Name: baz 43 83 ...to: 44 84 Name: z 45 85 46 Alternatives with failing assertions are:86 Unsatisfiable alternative: 47 87 Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of 48 Variable Expression: baz: forall49 T: sized object type50 ... with assertions51 ?=?: pointer to function52 ... with parameters53 reference to instance of type T (not function type)54 instance of type T (not function type)55 ... returning56 _retval__operator_assign: instance of type T (not function type)57 ... with attributes:58 Attribute with name: unused88 Variable Expression: baz: forall 89 T: sized object type 90 ... with assertions 91 ?=?: pointer to function 92 ... with parameters 93 reference to instance of type T (not function type) 94 instance of type T (not function type) 95 ... returning 96 _retval__operator_assign: instance of type T (not function type) 97 ... with attributes: 98 Attribute with name: unused 59 99 60 100 61 ?{}: pointer to function 101 ?{}: pointer to function 102 ... with parameters 103 reference to instance of type T (not function type) 104 ... returning nothing 105 106 ?{}: pointer to function 107 ... with parameters 108 reference to instance of type T (not function type) 109 instance of type T (not function type) 110 ... returning nothing 111 112 ^?{}: pointer to function 113 ... with parameters 114 reference to instance of type T (not function type) 115 ... returning nothing 116 117 118 function 62 119 ... with parameters 63 referenceto instance of type T (not function type)120 pointer to instance of type T (not function type) 64 121 ... returning nothing 65 122 66 ?{}: pointer to function 67 ... with parameters 68 reference to instance of type T (not function type) 69 instance of type T (not function type) 70 ... returning nothing 123 ... to arguments 124 Variable Expression: z: pointer to instance of type T (not function type) 71 125 72 ^?{}: pointer to function 73 ... with parameters 74 reference to instance of type T (not function type) 75 ... returning nothing 126 (types: 127 void 128 ) 129 Environment:( _99_0_T ) -> instance of type T (not function type) (no widening) 130 131 Could not satisfy assertion: 132 ?=?: pointer to function 133 ... with parameters 134 reference to instance of type _99_0_T (not function type) 135 instance of type _99_0_T (not function type) 136 ... returning 137 _retval__operator_assign: instance of type _99_0_T (not function type) 138 ... with attributes: 139 Attribute with name: unused 76 140 77 141 78 function79 ... with parameters80 pointer to instance of type T (not function type)81 ... returning nothing82 83 ... to arguments84 Variable Expression: z: pointer to instance of type T (not function type)85 86 (types:87 void88 )89 Environment:( _99_0_T ) -> instance of type T (not function type) (no widening)90 91 92 -
tests/completeTypeError.cfa
r07ac6d0 rde23648 19 19 // okay 20 20 *i; 21 * x; // picks B21 *y; 22 22 *z; 23 23 foo(i); … … 32 32 // bad 33 33 *v; 34 * y;34 *x; // ambiguous 35 35 foo(v); 36 36 baz(v); … … 54 54 bar(y); 55 55 qux(y); 56 *y; 56 57 57 58 // bad 58 59 baz(y); 59 60 quux(y); 60 *y;61 61 } 62 62
Note: See TracChangeset
for help on using the changeset viewer.